From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 1C0A21382C5 for ; Fri, 16 Apr 2021 11:15:55 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 63C20E081A; Fri, 16 Apr 2021 11:15:54 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 397B4E081A for ; Fri, 16 Apr 2021 11:15:54 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 293AF335C2A for ; Fri, 16 Apr 2021 11:15:53 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id DE3C9643 for ; Fri, 16 Apr 2021 11:15:51 +0000 (UTC) From: "Alice Ferrazzi" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Alice Ferrazzi" Message-ID: <1618571733.c9b7de80c8386cbd1e7033401062a566d8bf90b1.alicef@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.19 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1187_linux-4.19.188.patch X-VCS-Directories: / X-VCS-Committer: alicef X-VCS-Committer-Name: Alice Ferrazzi X-VCS-Revision: c9b7de80c8386cbd1e7033401062a566d8bf90b1 X-VCS-Branch: 4.19 Date: Fri, 16 Apr 2021 11:15:51 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 9f2c073b-cafc-44d6-8b86-84dc5abafd06 X-Archives-Hash: 88ce5f723dbfabc7ea8c67c7774a5bf5 commit: c9b7de80c8386cbd1e7033401062a566d8bf90b1 Author: Alice Ferrazzi gentoo org> AuthorDate: Fri Apr 16 11:15:24 2021 +0000 Commit: Alice Ferrazzi gentoo org> CommitDate: Fri Apr 16 11:15:33 2021 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c9b7de80 linux patch 4.19.188 Signed-off-by: Alice Ferrazzi gentoo.org> 0000_README | 4 + 1187_linux-4.19.188.patch | 3892 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3896 insertions(+) diff --git a/0000_README b/0000_README index 0fdb045..32b1ad4 100644 --- a/0000_README +++ b/0000_README @@ -787,6 +787,10 @@ Patch: 1186_linux-4.19.187.patch From: https://www.kernel.org Desc: Linux 4.19.187 +Patch: 1187_linux-4.19.188.patch +From: https://www.kernel.org +Desc: Linux 4.19.188 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1187_linux-4.19.188.patch b/1187_linux-4.19.188.patch new file mode 100644 index 0000000..aa0f999 --- /dev/null +++ b/1187_linux-4.19.188.patch @@ -0,0 +1,3892 @@ +diff --git a/Makefile b/Makefile +index ceec39b530bbe..85f071709a619 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 187 ++SUBLEVEL = 188 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h +index a3b6f58d188c9..6d43f7901da23 100644 +--- a/arch/arm64/include/asm/kvm_arm.h ++++ b/arch/arm64/include/asm/kvm_arm.h +@@ -198,6 +198,7 @@ + #define CPTR_EL2_DEFAULT CPTR_EL2_RES1 + + /* Hyp Debug Configuration Register bits */ ++#define MDCR_EL2_TTRF (1 << 19) + #define MDCR_EL2_TPMS (1 << 14) + #define MDCR_EL2_E2PB_MASK (UL(0x3)) + #define MDCR_EL2_E2PB_SHIFT (UL(12)) +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index 1719d21a171a9..122d5e843ab6d 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -258,7 +258,6 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { + * of support. + */ + S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0), +- ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6), + ARM64_FTR_END, + }; +diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c +index 4e722d73a3c34..3606f6b890942 100644 +--- a/arch/arm64/kvm/debug.c ++++ b/arch/arm64/kvm/debug.c +@@ -100,6 +100,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) + * - Debug ROM Address (MDCR_EL2_TDRA) + * - OS related registers (MDCR_EL2_TDOSA) + * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) ++ * - Self-hosted Trace Filter controls (MDCR_EL2_TTRF) + * + * Additionally, KVM only traps guest accesses to the debug registers if + * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY +@@ -123,6 +124,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) + vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; + vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | + MDCR_EL2_TPMS | ++ MDCR_EL2_TTRF | + MDCR_EL2_TPMCR | + MDCR_EL2_TDRA | + MDCR_EL2_TDOSA); +diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S +index a03821b2656aa..d9de22686e27d 100644 +--- a/arch/riscv/kernel/entry.S ++++ b/arch/riscv/kernel/entry.S +@@ -449,6 +449,7 @@ ENDPROC(__fstate_restore) + + + .section ".rodata" ++ .align LGREG + /* Exception vector table */ + ENTRY(excp_vect_table) + RISCV_PTR do_trap_insn_misaligned +diff --git a/block/bio.c b/block/bio.c +index 3d757055305f9..fe749404ef93b 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -314,7 +314,7 @@ static struct bio *__bio_chain_endio(struct bio *bio) + { + struct bio *parent = bio->bi_private; + +- if (!parent->bi_status) ++ if (bio->bi_status && !parent->bi_status) + parent->bi_status = bio->bi_status; + bio_put(bio); + return parent; +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index 4ba9231a6be80..26ba7a99b7d5b 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -254,14 +254,16 @@ int driver_deferred_probe_check_state(struct device *dev) + + static void deferred_probe_timeout_work_func(struct work_struct *work) + { +- struct device_private *private, *p; ++ struct device_private *p; + + deferred_probe_timeout = 0; + driver_deferred_probe_trigger(); + flush_work(&deferred_probe_work); + +- list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe) +- dev_info(private->device, "deferred probe pending"); ++ mutex_lock(&deferred_probe_mutex); ++ list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe) ++ dev_info(p->device, "deferred probe pending\n"); ++ mutex_unlock(&deferred_probe_mutex); + } + static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); + +diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c +index 221a8cbc57f90..a4dba034dca48 100644 +--- a/drivers/gpu/drm/imx/imx-ldb.c ++++ b/drivers/gpu/drm/imx/imx-ldb.c +@@ -206,6 +206,11 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder) + int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; + int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); + ++ if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { ++ dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); ++ return; ++ } ++ + drm_panel_prepare(imx_ldb_ch->panel); + + if (dual) { +@@ -264,6 +269,11 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder, + int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); + u32 bus_format = imx_ldb_ch->bus_format; + ++ if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { ++ dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); ++ return; ++ } ++ + if (mode->clock > 170000) { + dev_warn(ldb->dev, + "%s: mode exceeds 170 MHz pixel clock\n", __func__); +diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c +index 965088afcfade..03adb4cf325b9 100644 +--- a/drivers/gpu/drm/tegra/dc.c ++++ b/drivers/gpu/drm/tegra/dc.c +@@ -1670,6 +1670,11 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, + dev_err(dc->dev, + "failed to set clock rate to %lu Hz\n", + state->pclk); ++ ++ err = clk_set_rate(dc->clk, state->pclk); ++ if (err < 0) ++ dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", ++ dc->clk, state->pclk, err); + } + + DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), +@@ -1680,11 +1685,6 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, + value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1; + tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); + } +- +- err = clk_set_rate(dc->clk, state->pclk); +- if (err < 0) +- dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", +- dc->clk, state->pclk, err); + } + + static void tegra_dc_stop(struct tegra_dc *dc) +diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c +index e10e7b54ec4b6..7e5892597533e 100644 +--- a/drivers/net/phy/bcm-phy-lib.c ++++ b/drivers/net/phy/bcm-phy-lib.c +@@ -198,7 +198,7 @@ EXPORT_SYMBOL_GPL(bcm_phy_enable_apd); + + int bcm_phy_set_eee(struct phy_device *phydev, bool enable) + { +- int val; ++ int val, mask = 0; + + /* Enable EEE at PHY level */ + val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL); +@@ -217,10 +217,15 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) + if (val < 0) + return val; + ++ if (phydev->supported & SUPPORTED_1000baseT_Full) ++ mask |= MDIO_EEE_1000T; ++ if (phydev->supported & SUPPORTED_100baseT_Full) ++ mask |= MDIO_EEE_100TX; ++ + if (enable) +- val |= (MDIO_EEE_100TX | MDIO_EEE_1000T); ++ val |= mask; + else +- val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T); ++ val &= ~mask; + + phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val); + +diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig +index 1abf76be2aa8c..58e8140c1f57a 100644 +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -114,8 +114,6 @@ source "drivers/staging/mt7621-spi/Kconfig" + + source "drivers/staging/mt7621-dma/Kconfig" + +-source "drivers/staging/mt7621-mmc/Kconfig" +- + source "drivers/staging/mt7621-eth/Kconfig" + + source "drivers/staging/mt7621-dts/Kconfig" +diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile +index ab0cbe8815b1c..6f3065569fa00 100644 +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -47,7 +47,6 @@ obj-$(CONFIG_SOC_MT7621) += mt7621-pci/ + obj-$(CONFIG_SOC_MT7621) += mt7621-pinctrl/ + obj-$(CONFIG_SOC_MT7621) += mt7621-spi/ + obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ +-obj-$(CONFIG_SOC_MT7621) += mt7621-mmc/ + obj-$(CONFIG_SOC_MT7621) += mt7621-eth/ + obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ + obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ +diff --git a/drivers/staging/mt7621-mmc/Kconfig b/drivers/staging/mt7621-mmc/Kconfig +deleted file mode 100644 +index c6dfe8c637dc3..0000000000000 +--- a/drivers/staging/mt7621-mmc/Kconfig ++++ /dev/null +@@ -1,16 +0,0 @@ +-config MTK_MMC +- tristate "MTK SD/MMC" +- depends on !MTD_NAND_RALINK && MMC +- +-config MTK_AEE_KDUMP +- bool "MTK AEE KDUMP" +- depends on MTK_MMC +- +-config MTK_MMC_CD_POLL +- bool "Card Detect with Polling" +- depends on MTK_MMC +- +-config MTK_MMC_EMMC_8BIT +- bool "eMMC 8-bit support" +- depends on MTK_MMC && RALINK_MT7628 +- +diff --git a/drivers/staging/mt7621-mmc/Makefile b/drivers/staging/mt7621-mmc/Makefile +deleted file mode 100644 +index caead0b547035..0000000000000 +--- a/drivers/staging/mt7621-mmc/Makefile ++++ /dev/null +@@ -1,42 +0,0 @@ +-# Copyright Statement: +-# +-# This software/firmware and related documentation ("MediaTek Software") are +-# protected under relevant copyright laws. The information contained herein +-# is confidential and proprietary to MediaTek Inc. and/or its licensors. +-# Without the prior written permission of MediaTek inc. and/or its licensors, +-# any reproduction, modification, use or disclosure of MediaTek Software, +-# and information contained herein, in whole or in part, shall be strictly prohibited. +-# +-# MediaTek Inc. (C) 2010. All rights reserved. +-# +-# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +-# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +-# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +-# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +-# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +-# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +-# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +-# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +-# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +-# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +-# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +-# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +-# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +-# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +-# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +-# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +-# +-# The following software/firmware and/or related documentation ("MediaTek Software") +-# have been modified by MediaTek Inc. All revisions are subject to any receiver's +-# applicable license agreements with MediaTek Inc. +- +-obj-$(CONFIG_MTK_MMC) += mtk_sd.o +-mtk_sd-objs := sd.o dbg.o +-ifeq ($(CONFIG_MTK_AEE_KDUMP),y) +-EXTRA_CFLAGS += -DMT6575_SD_DEBUG +-endif +- +-clean: +- @rm -f *.o modules.order .*.cmd +diff --git a/drivers/staging/mt7621-mmc/TODO b/drivers/staging/mt7621-mmc/TODO +deleted file mode 100644 +index febb32d37e07b..0000000000000 +--- a/drivers/staging/mt7621-mmc/TODO ++++ /dev/null +@@ -1,8 +0,0 @@ +- +-- general code review and clean up +-- ensure device-tree requirements are documented +-- should probably be merged with drivers/mmc/host/mtk-sd.c +-- possibly fix to work with highmem pages so a bounce buffer isn't +- needed. +- +-Cc: NeilBrown +diff --git a/drivers/staging/mt7621-mmc/board.h b/drivers/staging/mt7621-mmc/board.h +deleted file mode 100644 +index 983791ee308dd..0000000000000 +--- a/drivers/staging/mt7621-mmc/board.h ++++ /dev/null +@@ -1,63 +0,0 @@ +-/* Copyright Statement: +- * +- * This software/firmware and related documentation ("MediaTek Software") are +- * protected under relevant copyright laws. The information contained herein +- * is confidential and proprietary to MediaTek Inc. and/or its licensors. +- * Without the prior written permission of MediaTek inc. and/or its licensors, +- * any reproduction, modification, use or disclosure of MediaTek Software, +- * and information contained herein, in whole or in part, shall be strictly prohibited. +- */ +-/* MediaTek Inc. (C) 2010. All rights reserved. +- * +- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +- * +- * The following software/firmware and/or related documentation ("MediaTek Software") +- * have been modified by MediaTek Inc. All revisions are subject to any receiver's +- * applicable license agreements with MediaTek Inc. +- */ +- +-#ifndef __ARCH_ARM_MACH_BOARD_H +-#define __ARCH_ARM_MACH_BOARD_H +- +-#define MSDC_CD_PIN_EN BIT(0) /* card detection pin is wired */ +-#define MSDC_WP_PIN_EN BIT(1) /* write protection pin is wired */ +-#define MSDC_RST_PIN_EN BIT(2) /* emmc reset pin is wired */ +-#define MSDC_REMOVABLE BIT(5) /* removable slot */ +- +-#define MSDC_SMPL_RISING (0) +-#define MSDC_SMPL_FALLING (1) +- +-#define MSDC_CMD_PIN (0) +-#define MSDC_DAT_PIN (1) +-#define MSDC_CD_PIN (2) +-#define MSDC_WP_PIN (3) +-#define MSDC_RST_PIN (4) +- +-struct msdc_hw { +- unsigned char clk_src; /* host clock source */ +- unsigned long flags; /* hardware capability flags */ +- +- /* config gpio pull mode */ +- void (*config_gpio_pin)(int type, int pull); +-}; +- +-extern struct msdc_hw msdc0_hw; +- +-#endif /* __ARCH_ARM_MACH_BOARD_H */ +diff --git a/drivers/staging/mt7621-mmc/dbg.c b/drivers/staging/mt7621-mmc/dbg.c +deleted file mode 100644 +index 6e518dce9029a..0000000000000 +--- a/drivers/staging/mt7621-mmc/dbg.c ++++ /dev/null +@@ -1,307 +0,0 @@ +-/* Copyright Statement: +- * +- * This software/firmware and related documentation ("MediaTek Software") are +- * protected under relevant copyright laws. The information contained herein +- * is confidential and proprietary to MediaTek Inc. and/or its licensors. +- * Without the prior written permission of MediaTek inc. and/or its licensors, +- * any reproduction, modification, use or disclosure of MediaTek Software, +- * and information contained herein, in whole or in part, shall be strictly prohibited. +- * +- * MediaTek Inc. (C) 2010. All rights reserved. +- * +- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +- * +- * The following software/firmware and/or related documentation ("MediaTek Software") +- * have been modified by MediaTek Inc. All revisions are subject to any receiver's +- * applicable license agreements with MediaTek Inc. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-// #include /* --- by chhung */ +-#include "dbg.h" +-#include "mt6575_sd.h" +-#include +- +-static char cmd_buf[256]; +- +-/* for debug zone */ +-unsigned int sd_debug_zone[4] = { +- 0, +- 0, +- 0, +- 0 +-}; +- +-#if defined(MT6575_SD_DEBUG) +-/* for driver profile */ +-#define TICKS_ONE_MS (13000) +-u32 gpt_enable; +-u32 sdio_pro_enable; /* make sure gpt is enabled */ +-u32 sdio_pro_time; /* no more than 30s */ +-struct sdio_profile sdio_perfomance = {0}; +- +-#if 0 /* --- chhung */ +-void msdc_init_gpt(void) +-{ +- GPT_CONFIG config; +- +- config.num = GPT6; +- config.mode = GPT_FREE_RUN; +- config.clkSrc = GPT_CLK_SRC_SYS; +- config.clkDiv = GPT_CLK_DIV_1; /* 13MHz GPT6 */ +- +- if (GPT_Config(config) == FALSE) +- return; +- +- GPT_Start(GPT6); +-} +-#endif /* end of --- */ +- +-u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32) +-{ +- u32 ret = 0; +- +- if (new_H32 == old_H32) { +- ret = new_L32 - old_L32; +- } else if (new_H32 == (old_H32 + 1)) { +- if (new_L32 > old_L32) +- pr_debug("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32); +- ret = (0xffffffff - old_L32); +- ret += new_L32; +- } else { +- pr_debug("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32); +- } +- +- return ret; +-} +- +-void msdc_sdio_profile(struct sdio_profile *result) +-{ +- struct cmd_profile *cmd; +- u32 i; +- +- pr_debug("sdio === performance dump ===\n"); +- pr_debug("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n", +- result->total_tc, result->total_tc / TICKS_ONE_MS, +- result->total_tx_bytes, result->total_rx_bytes); +- +- /* CMD52 Dump */ +- cmd = &result->cmd52_rx; +- pr_debug("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, +- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count); +- cmd = &result->cmd52_tx; +- pr_debug("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, +- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count); +- +- /* CMD53 Rx bytes + block mode */ +- for (i = 0; i < 512; i++) { +- cmd = &result->cmd53_rx_byte[i]; +- if (cmd->count) { +- pr_debug("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, +- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, +- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); +- } +- } +- for (i = 0; i < 100; i++) { +- cmd = &result->cmd53_rx_blk[i]; +- if (cmd->count) { +- pr_debug("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, +- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, +- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); +- } +- } +- +- /* CMD53 Tx bytes + block mode */ +- for (i = 0; i < 512; i++) { +- cmd = &result->cmd53_tx_byte[i]; +- if (cmd->count) { +- pr_debug("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, +- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, +- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); +- } +- } +- for (i = 0; i < 100; i++) { +- cmd = &result->cmd53_tx_blk[i]; +- if (cmd->count) { +- pr_debug("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, +- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, +- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); +- } +- } +- +- pr_debug("sdio === performance dump done ===\n"); +-} +- +-//========= sdio command table =========== +-void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks) +-{ +- struct sdio_profile *result = &sdio_perfomance; +- struct cmd_profile *cmd; +- u32 block; +- +- if (sdio_pro_enable == 0) +- return; +- +- if (opcode == 52) { +- cmd = bRx ? &result->cmd52_rx : &result->cmd52_tx; +- } else if (opcode == 53) { +- if (sizes < 512) { +- cmd = bRx ? &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes]; +- } else { +- block = sizes / 512; +- if (block >= 99) { +- pr_err("cmd53 error blocks\n"); +- while (1) +- ; +- } +- cmd = bRx ? &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block]; +- } +- } else { +- return; +- } +- +- /* update the members */ +- if (ticks > cmd->max_tc) +- cmd->max_tc = ticks; +- if (cmd->min_tc == 0 || ticks < cmd->min_tc) +- cmd->min_tc = ticks; +- cmd->tot_tc += ticks; +- cmd->tot_bytes += sizes; +- cmd->count++; +- +- if (bRx) +- result->total_rx_bytes += sizes; +- else +- result->total_tx_bytes += sizes; +- result->total_tc += ticks; +- +- /* dump when total_tc > 30s */ +- if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) { +- msdc_sdio_profile(result); +- memset(result, 0, sizeof(struct sdio_profile)); +- } +-} +- +-//========== driver proc interface =========== +-static int msdc_debug_proc_read(struct seq_file *s, void *p) +-{ +- seq_puts(s, "\n=========================================\n"); +- seq_puts(s, "Index<0> + Id + Zone\n"); +- seq_puts(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n"); +- seq_puts(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n"); +- seq_printf(s, "-> MSDC[0] Zone: 0x%.8x\n", sd_debug_zone[0]); +- seq_printf(s, "-> MSDC[1] Zone: 0x%.8x\n", sd_debug_zone[1]); +- seq_printf(s, "-> MSDC[2] Zone: 0x%.8x\n", sd_debug_zone[2]); +- seq_printf(s, "-> MSDC[3] Zone: 0x%.8x\n", sd_debug_zone[3]); +- +- seq_puts(s, "Index<3> + SDIO_PROFILE + TIME\n"); +- seq_puts(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n"); +- seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time); +- seq_puts(s, "=========================================\n\n"); +- +- return 0; +-} +- +-static ssize_t msdc_debug_proc_write(struct file *file, +- const char __user *buf, +- size_t count, loff_t *data) +-{ +- int ret; +- +- int cmd, p1, p2; +- int id, zone; +- int mode, size; +- +- if (count == 0) +- return -1; +- if (count > 255) +- count = 255; +- +- if (copy_from_user(cmd_buf, buf, count)) +- return -EFAULT; +- +- cmd_buf[count] = '\0'; +- pr_debug("msdc Write %s\n", cmd_buf); +- +- sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2); +- +- if (cmd == SD_TOOL_ZONE) { +- id = p1; +- zone = p2; +- zone &= 0x3ff; +- pr_debug("msdc host_id<%d> zone<0x%.8x>\n", id, zone); +- if (id >= 0 && id <= 3) { +- sd_debug_zone[id] = zone; +- } else if (id == 4) { +- sd_debug_zone[0] = sd_debug_zone[1] = zone; +- sd_debug_zone[2] = sd_debug_zone[3] = zone; +- } else { +- pr_err("msdc host_id error when set debug zone\n"); +- } +- } else if (cmd == SD_TOOL_SDIO_PROFILE) { +- if (p1 == 1) { /* enable profile */ +- if (gpt_enable == 0) { +- // msdc_init_gpt(); /* --- by chhung */ +- gpt_enable = 1; +- } +- sdio_pro_enable = 1; +- if (p2 == 0) +- p2 = 1; +- if (p2 >= 30) +- p2 = 30; +- sdio_pro_time = p2; +- } else if (p1 == 0) { +- /* todo */ +- sdio_pro_enable = 0; +- } +- } +- +- return count; +-} +- +-static int msdc_debug_show(struct inode *inode, struct file *file) +-{ +- return single_open(file, msdc_debug_proc_read, NULL); +-} +- +-static const struct file_operations msdc_debug_fops = { +- .owner = THIS_MODULE, +- .open = msdc_debug_show, +- .read = seq_read, +- .write = msdc_debug_proc_write, +- .llseek = seq_lseek, +- .release = single_release, +-}; +- +-void msdc_debug_proc_init(void) +-{ +- proc_create("msdc_debug", 0660, NULL, &msdc_debug_fops); +-} +-EXPORT_SYMBOL_GPL(msdc_debug_proc_init); +-#endif +diff --git a/drivers/staging/mt7621-mmc/dbg.h b/drivers/staging/mt7621-mmc/dbg.h +deleted file mode 100644 +index 2f2c56b739874..0000000000000 +--- a/drivers/staging/mt7621-mmc/dbg.h ++++ /dev/null +@@ -1,149 +0,0 @@ +-/* Copyright Statement: +- * +- * This software/firmware and related documentation ("MediaTek Software") are +- * protected under relevant copyright laws. The information contained herein +- * is confidential and proprietary to MediaTek Inc. and/or its licensors. +- * Without the prior written permission of MediaTek inc. and/or its licensors, +- * any reproduction, modification, use or disclosure of MediaTek Software, +- * and information contained herein, in whole or in part, shall be strictly prohibited. +- * +- * MediaTek Inc. (C) 2010. All rights reserved. +- * +- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +- * +- * The following software/firmware and/or related documentation ("MediaTek Software") +- * have been modified by MediaTek Inc. All revisions are subject to any receiver's +- * applicable license agreements with MediaTek Inc. +- */ +-#ifndef __MT_MSDC_DEUBG__ +-#define __MT_MSDC_DEUBG__ +- +-//========================== +-extern u32 sdio_pro_enable; +-/* for a type command, e.g. CMD53, 2 blocks */ +-struct cmd_profile { +- u32 max_tc; /* Max tick count */ +- u32 min_tc; +- u32 tot_tc; /* total tick count */ +- u32 tot_bytes; +- u32 count; /* the counts of the command */ +-}; +- +-/* dump when total_tc and total_bytes */ +-struct sdio_profile { +- u32 total_tc; /* total tick count of CMD52 and CMD53 */ +- u32 total_tx_bytes; /* total bytes of CMD53 Tx */ +- u32 total_rx_bytes; /* total bytes of CMD53 Rx */ +- +- /*CMD52*/ +- struct cmd_profile cmd52_tx; +- struct cmd_profile cmd52_rx; +- +- /*CMD53 in byte unit */ +- struct cmd_profile cmd53_tx_byte[512]; +- struct cmd_profile cmd53_rx_byte[512]; +- +- /*CMD53 in block unit */ +- struct cmd_profile cmd53_tx_blk[100]; +- struct cmd_profile cmd53_rx_blk[100]; +-}; +- +-//========================== +-enum msdc_dbg { +- SD_TOOL_ZONE = 0, +- SD_TOOL_DMA_SIZE = 1, +- SD_TOOL_PM_ENABLE = 2, +- SD_TOOL_SDIO_PROFILE = 3, +-}; +- +-/* Debug message event */ +-#define DBG_EVT_NONE (0) /* No event */ +-#define DBG_EVT_DMA (1 << 0) /* DMA related event */ +-#define DBG_EVT_CMD (1 << 1) /* MSDC CMD related event */ +-#define DBG_EVT_RSP (1 << 2) /* MSDC CMD RSP related event */ +-#define DBG_EVT_INT (1 << 3) /* MSDC INT event */ +-#define DBG_EVT_CFG (1 << 4) /* MSDC CFG event */ +-#define DBG_EVT_FUC (1 << 5) /* Function event */ +-#define DBG_EVT_OPS (1 << 6) /* Read/Write operation event */ +-#define DBG_EVT_FIO (1 << 7) /* FIFO operation event */ +-#define DBG_EVT_WRN (1 << 8) /* Warning event */ +-#define DBG_EVT_PWR (1 << 9) /* Power event */ +-#define DBG_EVT_ALL (0xffffffff) +- +-#define DBG_EVT_MASK (DBG_EVT_ALL) +- +-extern unsigned int sd_debug_zone[4]; +-#define TAG "msdc" +-#if 0 /* +++ chhung */ +-#define BUG_ON(x) \ +-do { \ +- if (x) { \ +- printk("[BUG] %s LINE:%d FILE:%s\n", #x, __LINE__, __FILE__); \ +- while (1) \ +- ; \ +- } \ +-} while (0) +-#endif /* end of +++ */ +- +-#define N_MSG(evt, fmt, args...) +-/* +-do { \ +- if ((DBG_EVT_##evt) & sd_debug_zone[host->id]) { \ +- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ +- host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \ +- } \ +-} while(0) +-*/ +- +-#define ERR_MSG(fmt, args...) \ +-do { \ +- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ +- host->id, ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \ +-} while (0); +- +-#if 1 +-//defined CONFIG_MTK_MMC_CD_POLL +-#define INIT_MSG(fmt, args...) +-#define IRQ_MSG(fmt, args...) +-#else +-#define INIT_MSG(fmt, args...) \ +-do { \ +- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ +- host->id, ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \ +-} while (0); +- +-/* PID in ISR in not corrent */ +-#define IRQ_MSG(fmt, args...) \ +-do { \ +- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \ +- host->id, ##args, __FUNCTION__, __LINE__); \ +-} while (0); +-#endif +- +-void msdc_debug_proc_init(void); +- +-#if 0 /* --- chhung */ +-void msdc_init_gpt(void); +-extern void GPT_GetCounter64(UINT32 *cntL32, UINT32 *cntH32); +-#endif /* end of --- */ +-u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32); +-void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks); +- +-#endif +diff --git a/drivers/staging/mt7621-mmc/mt6575_sd.h b/drivers/staging/mt7621-mmc/mt6575_sd.h +deleted file mode 100644 +index 4e287c140acb4..0000000000000 +--- a/drivers/staging/mt7621-mmc/mt6575_sd.h ++++ /dev/null +@@ -1,488 +0,0 @@ +-/* Copyright Statement: +- * +- * This software/firmware and related documentation ("MediaTek Software") are +- * protected under relevant copyright laws. The information contained herein +- * is confidential and proprietary to MediaTek Inc. and/or its licensors. +- * Without the prior written permission of MediaTek inc. and/or its licensors, +- * any reproduction, modification, use or disclosure of MediaTek Software, +- * and information contained herein, in whole or in part, shall be strictly prohibited. +- */ +-/* MediaTek Inc. (C) 2010. All rights reserved. +- * +- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +- * +- * The following software/firmware and/or related documentation ("MediaTek Software") +- * have been modified by MediaTek Inc. All revisions are subject to any receiver's +- * applicable license agreements with MediaTek Inc. +- */ +- +-#ifndef MT6575_SD_H +-#define MT6575_SD_H +- +-#include +-#include +- +-// #include /* --- by chhung */ +- +-/*--------------------------------------------------------------------------*/ +-/* Common Definition */ +-/*--------------------------------------------------------------------------*/ +-#define MSDC_FIFO_SZ (128) +-#define MSDC_FIFO_THD (64) // (128) +-#define MSDC_NUM (4) +- +-#define MSDC_MS (0) +-#define MSDC_SDMMC (1) +- +-#define MSDC_BUS_1BITS (0) +-#define MSDC_BUS_4BITS (1) +-#define MSDC_BUS_8BITS (2) +- +-#define MSDC_BRUST_8B (3) +-#define MSDC_BRUST_16B (4) +-#define MSDC_BRUST_32B (5) +-#define MSDC_BRUST_64B (6) +- +-#define MSDC_PIN_PULL_NONE (0) +-#define MSDC_PIN_PULL_DOWN (1) +-#define MSDC_PIN_PULL_UP (2) +-#define MSDC_PIN_KEEP (3) +- +-#define MSDC_MAX_SCLK (48000000) /* +/- by chhung */ +-#define MSDC_MIN_SCLK (260000) +- +-#define MSDC_AUTOCMD12 (0x0001) +-#define MSDC_AUTOCMD23 (0x0002) +-#define MSDC_AUTOCMD19 (0x0003) +- +-#define MSDC_EMMC_BOOTMODE0 (0) /* Pull low CMD mode */ +-#define MSDC_EMMC_BOOTMODE1 (1) /* Reset CMD mode */ +- +-enum { +- RESP_NONE = 0, +- RESP_R1, +- RESP_R2, +- RESP_R3, +- RESP_R4, +- RESP_R5, +- RESP_R6, +- RESP_R7, +- RESP_R1B +-}; +- +-/*--------------------------------------------------------------------------*/ +-/* Register Offset */ +-/*--------------------------------------------------------------------------*/ +-#define MSDC_CFG (0x0) +-#define MSDC_IOCON (0x04) +-#define MSDC_PS (0x08) +-#define MSDC_INT (0x0c) +-#define MSDC_INTEN (0x10) +-#define MSDC_FIFOCS (0x14) +-#define MSDC_TXDATA (0x18) +-#define MSDC_RXDATA (0x1c) +-#define SDC_CFG (0x30) +-#define SDC_CMD (0x34) +-#define SDC_ARG (0x38) +-#define SDC_STS (0x3c) +-#define SDC_RESP0 (0x40) +-#define SDC_RESP1 (0x44) +-#define SDC_RESP2 (0x48) +-#define SDC_RESP3 (0x4c) +-#define SDC_BLK_NUM (0x50) +-#define SDC_CSTS (0x58) +-#define SDC_CSTS_EN (0x5c) +-#define SDC_DCRC_STS (0x60) +-#define EMMC_CFG0 (0x70) +-#define EMMC_CFG1 (0x74) +-#define EMMC_STS (0x78) +-#define EMMC_IOCON (0x7c) +-#define SDC_ACMD_RESP (0x80) +-#define SDC_ACMD19_TRG (0x84) +-#define SDC_ACMD19_STS (0x88) +-#define MSDC_DMA_SA (0x90) +-#define MSDC_DMA_CA (0x94) +-#define MSDC_DMA_CTRL (0x98) +-#define MSDC_DMA_CFG (0x9c) +-#define MSDC_DBG_SEL (0xa0) +-#define MSDC_DBG_OUT (0xa4) +-#define MSDC_PATCH_BIT (0xb0) +-#define MSDC_PATCH_BIT0 MSDC_PATCH_BIT +-#define MSDC_PATCH_BIT1 (0xb4) +-#define MSDC_PAD_CTL0 (0xe0) +-#define MSDC_PAD_CTL1 (0xe4) +-#define MSDC_PAD_CTL2 (0xe8) +-#define MSDC_PAD_TUNE (0xec) +-#define MSDC_DAT_RDDLY0 (0xf0) +-#define MSDC_DAT_RDDLY1 (0xf4) +-#define MSDC_HW_DBG (0xf8) +-#define MSDC_VERSION (0x100) +-#define MSDC_ECO_VER (0x104) +- +-/*--------------------------------------------------------------------------*/ +-/* Register Mask */ +-/*--------------------------------------------------------------------------*/ +- +-/* MSDC_CFG mask */ +-#define MSDC_CFG_MODE (0x1 << 0) /* RW */ +-#define MSDC_CFG_CKPDN (0x1 << 1) /* RW */ +-#define MSDC_CFG_RST (0x1 << 2) /* RW */ +-#define MSDC_CFG_PIO (0x1 << 3) /* RW */ +-#define MSDC_CFG_CKDRVEN (0x1 << 4) /* RW */ +-#define MSDC_CFG_BV18SDT (0x1 << 5) /* RW */ +-#define MSDC_CFG_BV18PSS (0x1 << 6) /* R */ +-#define MSDC_CFG_CKSTB (0x1 << 7) /* R */ +-#define MSDC_CFG_CKDIV (0xff << 8) /* RW */ +-#define MSDC_CFG_CKMOD (0x3 << 16) /* RW */ +- +-/* MSDC_IOCON mask */ +-#define MSDC_IOCON_SDR104CKS (0x1 << 0) /* RW */ +-#define MSDC_IOCON_RSPL (0x1 << 1) /* RW */ +-#define MSDC_IOCON_DSPL (0x1 << 2) /* RW */ +-#define MSDC_IOCON_DDLSEL (0x1 << 3) /* RW */ +-#define MSDC_IOCON_DDR50CKD (0x1 << 4) /* RW */ +-#define MSDC_IOCON_DSPLSEL (0x1 << 5) /* RW */ +-#define MSDC_IOCON_D0SPL (0x1 << 16) /* RW */ +-#define MSDC_IOCON_D1SPL (0x1 << 17) /* RW */ +-#define MSDC_IOCON_D2SPL (0x1 << 18) /* RW */ +-#define MSDC_IOCON_D3SPL (0x1 << 19) /* RW */ +-#define MSDC_IOCON_D4SPL (0x1 << 20) /* RW */ +-#define MSDC_IOCON_D5SPL (0x1 << 21) /* RW */ +-#define MSDC_IOCON_D6SPL (0x1 << 22) /* RW */ +-#define MSDC_IOCON_D7SPL (0x1 << 23) /* RW */ +-#define MSDC_IOCON_RISCSZ (0x3 << 24) /* RW */ +- +-/* MSDC_PS mask */ +-#define MSDC_PS_CDEN (0x1 << 0) /* RW */ +-#define MSDC_PS_CDSTS (0x1 << 1) /* R */ +-#define MSDC_PS_CDDEBOUNCE (0xf << 12) /* RW */ +-#define MSDC_PS_DAT (0xff << 16) /* R */ +-#define MSDC_PS_CMD (0x1 << 24) /* R */ +-#define MSDC_PS_WP (0x1UL << 31) /* R */ +- +-/* MSDC_INT mask */ +-#define MSDC_INT_MMCIRQ (0x1 << 0) /* W1C */ +-#define MSDC_INT_CDSC (0x1 << 1) /* W1C */ +-#define MSDC_INT_ACMDRDY (0x1 << 3) /* W1C */ +-#define MSDC_INT_ACMDTMO (0x1 << 4) /* W1C */ +-#define MSDC_INT_ACMDCRCERR (0x1 << 5) /* W1C */ +-#define MSDC_INT_DMAQ_EMPTY (0x1 << 6) /* W1C */ +-#define MSDC_INT_SDIOIRQ (0x1 << 7) /* W1C */ +-#define MSDC_INT_CMDRDY (0x1 << 8) /* W1C */ +-#define MSDC_INT_CMDTMO (0x1 << 9) /* W1C */ +-#define MSDC_INT_RSPCRCERR (0x1 << 10) /* W1C */ +-#define MSDC_INT_CSTA (0x1 << 11) /* R */ +-#define MSDC_INT_XFER_COMPL (0x1 << 12) /* W1C */ +-#define MSDC_INT_DXFER_DONE (0x1 << 13) /* W1C */ +-#define MSDC_INT_DATTMO (0x1 << 14) /* W1C */ +-#define MSDC_INT_DATCRCERR (0x1 << 15) /* W1C */ +-#define MSDC_INT_ACMD19_DONE (0x1 << 16) /* W1C */ +- +-/* MSDC_INTEN mask */ +-#define MSDC_INTEN_MMCIRQ (0x1 << 0) /* RW */ +-#define MSDC_INTEN_CDSC (0x1 << 1) /* RW */ +-#define MSDC_INTEN_ACMDRDY (0x1 << 3) /* RW */ +-#define MSDC_INTEN_ACMDTMO (0x1 << 4) /* RW */ +-#define MSDC_INTEN_ACMDCRCERR (0x1 << 5) /* RW */ +-#define MSDC_INTEN_DMAQ_EMPTY (0x1 << 6) /* RW */ +-#define MSDC_INTEN_SDIOIRQ (0x1 << 7) /* RW */ +-#define MSDC_INTEN_CMDRDY (0x1 << 8) /* RW */ +-#define MSDC_INTEN_CMDTMO (0x1 << 9) /* RW */ +-#define MSDC_INTEN_RSPCRCERR (0x1 << 10) /* RW */ +-#define MSDC_INTEN_CSTA (0x1 << 11) /* RW */ +-#define MSDC_INTEN_XFER_COMPL (0x1 << 12) /* RW */ +-#define MSDC_INTEN_DXFER_DONE (0x1 << 13) /* RW */ +-#define MSDC_INTEN_DATTMO (0x1 << 14) /* RW */ +-#define MSDC_INTEN_DATCRCERR (0x1 << 15) /* RW */ +-#define MSDC_INTEN_ACMD19_DONE (0x1 << 16) /* RW */ +- +-/* MSDC_FIFOCS mask */ +-#define MSDC_FIFOCS_RXCNT (0xff << 0) /* R */ +-#define MSDC_FIFOCS_TXCNT (0xff << 16) /* R */ +-#define MSDC_FIFOCS_CLR (0x1UL << 31) /* RW */ +- +-/* SDC_CFG mask */ +-#define SDC_CFG_SDIOINTWKUP (0x1 << 0) /* RW */ +-#define SDC_CFG_INSWKUP (0x1 << 1) /* RW */ +-#define SDC_CFG_BUSWIDTH (0x3 << 16) /* RW */ +-#define SDC_CFG_SDIO (0x1 << 19) /* RW */ +-#define SDC_CFG_SDIOIDE (0x1 << 20) /* RW */ +-#define SDC_CFG_INTATGAP (0x1 << 21) /* RW */ +-#define SDC_CFG_DTOC (0xffUL << 24) /* RW */ +- +-/* SDC_CMD mask */ +-#define SDC_CMD_OPC (0x3f << 0) /* RW */ +-#define SDC_CMD_BRK (0x1 << 6) /* RW */ +-#define SDC_CMD_RSPTYP (0x7 << 7) /* RW */ +-#define SDC_CMD_DTYP (0x3 << 11) /* RW */ +-#define SDC_CMD_DTYP (0x3 << 11) /* RW */ +-#define SDC_CMD_RW (0x1 << 13) /* RW */ +-#define SDC_CMD_STOP (0x1 << 14) /* RW */ +-#define SDC_CMD_GOIRQ (0x1 << 15) /* RW */ +-#define SDC_CMD_BLKLEN (0xfff << 16) /* RW */ +-#define SDC_CMD_AUTOCMD (0x3 << 28) /* RW */ +-#define SDC_CMD_VOLSWTH (0x1 << 30) /* RW */ +- +-/* SDC_STS mask */ +-#define SDC_STS_SDCBUSY (0x1 << 0) /* RW */ +-#define SDC_STS_CMDBUSY (0x1 << 1) /* RW */ +-#define SDC_STS_SWR_COMPL (0x1 << 31) /* RW */ +- +-/* SDC_DCRC_STS mask */ +-#define SDC_DCRC_STS_NEG (0xf << 8) /* RO */ +-#define SDC_DCRC_STS_POS (0xff << 0) /* RO */ +- +-/* EMMC_CFG0 mask */ +-#define EMMC_CFG0_BOOTSTART (0x1 << 0) /* W */ +-#define EMMC_CFG0_BOOTSTOP (0x1 << 1) /* W */ +-#define EMMC_CFG0_BOOTMODE (0x1 << 2) /* RW */ +-#define EMMC_CFG0_BOOTACKDIS (0x1 << 3) /* RW */ +-#define EMMC_CFG0_BOOTWDLY (0x7 << 12) /* RW */ +-#define EMMC_CFG0_BOOTSUPP (0x1 << 15) /* RW */ +- +-/* EMMC_CFG1 mask */ +-#define EMMC_CFG1_BOOTDATTMC (0xfffff << 0) /* RW */ +-#define EMMC_CFG1_BOOTACKTMC (0xfffUL << 20) /* RW */ +- +-/* EMMC_STS mask */ +-#define EMMC_STS_BOOTCRCERR (0x1 << 0) /* W1C */ +-#define EMMC_STS_BOOTACKERR (0x1 << 1) /* W1C */ +-#define EMMC_STS_BOOTDATTMO (0x1 << 2) /* W1C */ +-#define EMMC_STS_BOOTACKTMO (0x1 << 3) /* W1C */ +-#define EMMC_STS_BOOTUPSTATE (0x1 << 4) /* R */ +-#define EMMC_STS_BOOTACKRCV (0x1 << 5) /* W1C */ +-#define EMMC_STS_BOOTDATRCV (0x1 << 6) /* R */ +- +-/* EMMC_IOCON mask */ +-#define EMMC_IOCON_BOOTRST (0x1 << 0) /* RW */ +- +-/* SDC_ACMD19_TRG mask */ +-#define SDC_ACMD19_TRG_TUNESEL (0xf << 0) /* RW */ +- +-/* MSDC_DMA_CTRL mask */ +-#define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ +-#define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ +-#define MSDC_DMA_CTRL_RESUME (0x1 << 2) /* W */ +-#define MSDC_DMA_CTRL_MODE (0x1 << 8) /* RW */ +-#define MSDC_DMA_CTRL_LASTBUF (0x1 << 10) /* RW */ +-#define MSDC_DMA_CTRL_BRUSTSZ (0x7 << 12) /* RW */ +-#define MSDC_DMA_CTRL_XFERSZ (0xffffUL << 16)/* RW */ +- +-/* MSDC_DMA_CFG mask */ +-#define MSDC_DMA_CFG_STS (0x1 << 0) /* R */ +-#define MSDC_DMA_CFG_DECSEN (0x1 << 1) /* RW */ +-#define MSDC_DMA_CFG_BDCSERR (0x1 << 4) /* R */ +-#define MSDC_DMA_CFG_GPDCSERR (0x1 << 5) /* R */ +- +-/* MSDC_PATCH_BIT mask */ +-#define MSDC_PATCH_BIT_WFLSMODE (0x1 << 0) /* RW */ +-#define MSDC_PATCH_BIT_ODDSUPP (0x1 << 1) /* RW */ +-#define MSDC_PATCH_BIT_CKGEN_CK (0x1 << 6) /* E2: Fixed to 1 */ +-#define MSDC_PATCH_BIT_IODSSEL (0x1 << 16) /* RW */ +-#define MSDC_PATCH_BIT_IOINTSEL (0x1 << 17) /* RW */ +-#define MSDC_PATCH_BIT_BUSYDLY (0xf << 18) /* RW */ +-#define MSDC_PATCH_BIT_WDOD (0xf << 22) /* RW */ +-#define MSDC_PATCH_BIT_IDRTSEL (0x1 << 26) /* RW */ +-#define MSDC_PATCH_BIT_CMDFSEL (0x1 << 27) /* RW */ +-#define MSDC_PATCH_BIT_INTDLSEL (0x1 << 28) /* RW */ +-#define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */ +-#define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */ +- +-/* MSDC_PATCH_BIT1 mask */ +-#define MSDC_PATCH_BIT1_WRDAT_CRCS (0x7 << 3) +-#define MSDC_PATCH_BIT1_CMD_RSP (0x7 << 0) +- +-/* MSDC_PAD_CTL0 mask */ +-#define MSDC_PAD_CTL0_CLKDRVN (0x7 << 0) /* RW */ +-#define MSDC_PAD_CTL0_CLKDRVP (0x7 << 4) /* RW */ +-#define MSDC_PAD_CTL0_CLKSR (0x1 << 8) /* RW */ +-#define MSDC_PAD_CTL0_CLKPD (0x1 << 16) /* RW */ +-#define MSDC_PAD_CTL0_CLKPU (0x1 << 17) /* RW */ +-#define MSDC_PAD_CTL0_CLKSMT (0x1 << 18) /* RW */ +-#define MSDC_PAD_CTL0_CLKIES (0x1 << 19) /* RW */ +-#define MSDC_PAD_CTL0_CLKTDSEL (0xf << 20) /* RW */ +-#define MSDC_PAD_CTL0_CLKRDSEL (0xffUL << 24) /* RW */ +- +-/* MSDC_PAD_CTL1 mask */ +-#define MSDC_PAD_CTL1_CMDDRVN (0x7 << 0) /* RW */ +-#define MSDC_PAD_CTL1_CMDDRVP (0x7 << 4) /* RW */ +-#define MSDC_PAD_CTL1_CMDSR (0x1 << 8) /* RW */ +-#define MSDC_PAD_CTL1_CMDPD (0x1 << 16) /* RW */ +-#define MSDC_PAD_CTL1_CMDPU (0x1 << 17) /* RW */ +-#define MSDC_PAD_CTL1_CMDSMT (0x1 << 18) /* RW */ +-#define MSDC_PAD_CTL1_CMDIES (0x1 << 19) /* RW */ +-#define MSDC_PAD_CTL1_CMDTDSEL (0xf << 20) /* RW */ +-#define MSDC_PAD_CTL1_CMDRDSEL (0xffUL << 24) /* RW */ +- +-/* MSDC_PAD_CTL2 mask */ +-#define MSDC_PAD_CTL2_DATDRVN (0x7 << 0) /* RW */ +-#define MSDC_PAD_CTL2_DATDRVP (0x7 << 4) /* RW */ +-#define MSDC_PAD_CTL2_DATSR (0x1 << 8) /* RW */ +-#define MSDC_PAD_CTL2_DATPD (0x1 << 16) /* RW */ +-#define MSDC_PAD_CTL2_DATPU (0x1 << 17) /* RW */ +-#define MSDC_PAD_CTL2_DATIES (0x1 << 19) /* RW */ +-#define MSDC_PAD_CTL2_DATSMT (0x1 << 18) /* RW */ +-#define MSDC_PAD_CTL2_DATTDSEL (0xf << 20) /* RW */ +-#define MSDC_PAD_CTL2_DATRDSEL (0xffUL << 24) /* RW */ +- +-/* MSDC_PAD_TUNE mask */ +-#define MSDC_PAD_TUNE_DATWRDLY (0x1F << 0) /* RW */ +-#define MSDC_PAD_TUNE_DATRRDLY (0x1F << 8) /* RW */ +-#define MSDC_PAD_TUNE_CMDRDLY (0x1F << 16) /* RW */ +-#define MSDC_PAD_TUNE_CMDRRDLY (0x1FUL << 22) /* RW */ +-#define MSDC_PAD_TUNE_CLKTXDLY (0x1FUL << 27) /* RW */ +- +-/* MSDC_DAT_RDDLY0/1 mask */ +-#define MSDC_DAT_RDDLY0_D0 (0x1F << 0) /* RW */ +-#define MSDC_DAT_RDDLY0_D1 (0x1F << 8) /* RW */ +-#define MSDC_DAT_RDDLY0_D2 (0x1F << 16) /* RW */ +-#define MSDC_DAT_RDDLY0_D3 (0x1F << 24) /* RW */ +- +-#define MSDC_DAT_RDDLY1_D4 (0x1F << 0) /* RW */ +-#define MSDC_DAT_RDDLY1_D5 (0x1F << 8) /* RW */ +-#define MSDC_DAT_RDDLY1_D6 (0x1F << 16) /* RW */ +-#define MSDC_DAT_RDDLY1_D7 (0x1F << 24) /* RW */ +- +-#define MSDC_CKGEN_MSDC_DLY_SEL (0x1F << 10) +-#define MSDC_INT_DAT_LATCH_CK_SEL (0x7 << 7) +-#define MSDC_CKGEN_MSDC_CK_SEL (0x1 << 6) +-#define CARD_READY_FOR_DATA (1 << 8) +-#define CARD_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) +- +-/*--------------------------------------------------------------------------*/ +-/* Descriptor Structure */ +-/*--------------------------------------------------------------------------*/ +-struct gpd { +- u32 hwo:1; /* could be changed by hw */ +- u32 bdp:1; +- u32 rsv0:6; +- u32 chksum:8; +- u32 intr:1; +- u32 rsv1:15; +- void *next; +- void *ptr; +- u32 buflen:16; +- u32 extlen:8; +- u32 rsv2:8; +- u32 arg; +- u32 blknum; +- u32 cmd; +-}; +- +-struct bd { +- u32 eol:1; +- u32 rsv0:7; +- u32 chksum:8; +- u32 rsv1:1; +- u32 blkpad:1; +- u32 dwpad:1; +- u32 rsv2:13; +- void *next; +- void *ptr; +- u32 buflen:16; +- u32 rsv3:16; +-}; +- +-struct msdc_dma { +- struct gpd *gpd; /* pointer to gpd array */ +- struct bd *bd; /* pointer to bd array */ +- dma_addr_t gpd_addr; /* the physical address of gpd array */ +- dma_addr_t bd_addr; /* the physical address of bd array */ +-}; +- +-struct msdc_host { +- struct msdc_hw *hw; +- +- struct mmc_host *mmc; /* mmc structure */ +- struct mmc_command *cmd; +- struct mmc_data *data; +- struct mmc_request *mrq; +- int cmd_rsp; +- +- int error; +- spinlock_t lock; /* mutex */ +- struct semaphore sem; +- +- u32 blksz; /* host block size */ +- void __iomem *base; /* host base address */ +- int id; /* host id */ +- int pwr_ref; /* core power reference count */ +- +- u32 xfer_size; /* total transferred size */ +- +- struct msdc_dma dma; /* dma channel */ +- u32 dma_xfer_size; /* dma transfer size in bytes */ +- +- u32 timeout_ns; /* data timeout ns */ +- u32 timeout_clks; /* data timeout clks */ +- +- int irq; /* host interrupt */ +- +- struct delayed_work card_delaywork; +- +- struct completion cmd_done; +- struct completion xfer_done; +- struct pm_message pm_state; +- +- u32 mclk; /* mmc subsystem clock */ +- u32 hclk; /* host clock speed */ +- u32 sclk; /* SD/MS clock speed */ +- u8 core_clkon; /* Host core clock on ? */ +- u8 card_clkon; /* Card clock on ? */ +- u8 core_power; /* core power */ +- u8 power_mode; /* host power mode */ +- u8 card_inserted; /* card inserted ? */ +- u8 suspend; /* host suspended ? */ +- u8 app_cmd; /* for app command */ +- u32 app_cmd_arg; +-}; +- +-static inline void sdr_set_bits(void __iomem *reg, u32 bs) +-{ +- u32 val = readl(reg); +- +- val |= bs; +- writel(val, reg); +-} +- +-static inline void sdr_clr_bits(void __iomem *reg, u32 bs) +-{ +- u32 val = readl(reg); +- +- val &= ~bs; +- writel(val, reg); +-} +- +-static inline void sdr_set_field(void __iomem *reg, u32 field, u32 val) +-{ +- unsigned int tv = readl(reg); +- +- tv &= ~field; +- tv |= ((val) << (ffs((unsigned int)field) - 1)); +- writel(tv, reg); +-} +- +-static inline void sdr_get_field(void __iomem *reg, u32 field, u32 *val) +-{ +- unsigned int tv = readl(reg); +- *val = ((tv & field) >> (ffs((unsigned int)field) - 1)); +-} +- +-#endif +diff --git a/drivers/staging/mt7621-mmc/sd.c b/drivers/staging/mt7621-mmc/sd.c +deleted file mode 100644 +index 04d23cc7cd4a6..0000000000000 +--- a/drivers/staging/mt7621-mmc/sd.c ++++ /dev/null +@@ -1,2392 +0,0 @@ +-/* Copyright Statement: +- * +- * This software/firmware and related documentation ("MediaTek Software") are +- * protected under relevant copyright laws. The information contained herein +- * is confidential and proprietary to MediaTek Inc. and/or its licensors. +- * Without the prior written permission of MediaTek inc. and/or its licensors, +- * any reproduction, modification, use or disclosure of MediaTek Software, +- * and information contained herein, in whole or in part, shall be strictly prohibited. +- * +- * MediaTek Inc. (C) 2010. All rights reserved. +- * +- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +- * +- * The following software/firmware and/or related documentation ("MediaTek Software") +- * have been modified by MediaTek Inc. All revisions are subject to any receiver's +- * applicable license agreements with MediaTek Inc. +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-#include +- +-#include "board.h" +-#include "dbg.h" +-#include "mt6575_sd.h" +- +-#ifdef CONFIG_SOC_MT7621 +-#define RALINK_SYSCTL_BASE 0xbe000000 +-#else +-#define RALINK_SYSCTL_BASE 0xb0000000 +-#endif +- +-#define DRV_NAME "mtk-sd" +- +-#if defined(CONFIG_SOC_MT7620) +-#define HOST_MAX_MCLK (48000000) /* +/- by chhung */ +-#elif defined(CONFIG_SOC_MT7621) +-#define HOST_MAX_MCLK (50000000) /* +/- by chhung */ +-#endif +-#define HOST_MIN_MCLK (260000) +- +-#define HOST_MAX_BLKSZ (2048) +- +-#define MSDC_OCR_AVAIL (MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33) +- +-#define GPIO_PULL_DOWN (0) +-#define GPIO_PULL_UP (1) +- +-#if 0 /* --- by chhung */ +-#define MSDC_CLKSRC_REG (0xf100000C) +-#define PDN_REG (0xF1000010) +-#endif /* end of --- */ +- +-#define DEFAULT_DEBOUNCE (8) /* 8 cycles */ +-#define DEFAULT_DTOC (40) /* data timeout counter. 65536x40 sclk. */ +- +-#define CMD_TIMEOUT (HZ / 10) /* 100ms */ +-#define DAT_TIMEOUT (HZ / 2 * 5) /* 500ms x5 */ +- +-#define MAX_DMA_CNT (64 * 1024 - 512) /* a single transaction for WIFI may be 50K*/ +- +-#define MAX_GPD_NUM (1 + 1) /* one null gpd */ +-#define MAX_BD_NUM (1024) +- +-#define MAX_HW_SGMTS (MAX_BD_NUM) +-#define MAX_SGMT_SZ (MAX_DMA_CNT) +-#define MAX_REQ_SZ (MAX_SGMT_SZ * 8) +- +-static int cd_active_low = 1; +- +-//================================= +-#define PERI_MSDC0_PDN (15) +-//#define PERI_MSDC1_PDN (16) +-//#define PERI_MSDC2_PDN (17) +-//#define PERI_MSDC3_PDN (18) +- +-#if 0 /* --- by chhung */ +-/* gate means clock power down */ +-static int g_clk_gate = 0; +-#define msdc_gate_clock(id) \ +- do { \ +- g_clk_gate &= ~(1 << ((id) + PERI_MSDC0_PDN)); \ +- } while (0) +-/* not like power down register. 1 means clock on. */ +-#define msdc_ungate_clock(id) \ +- do { \ +- g_clk_gate |= 1 << ((id) + PERI_MSDC0_PDN); \ +- } while (0) +- +-// do we need sync object or not +-void msdc_clk_status(int *status) +-{ +- *status = g_clk_gate; +-} +-#endif /* end of --- */ +- +-/* +++ by chhung */ +-struct msdc_hw msdc0_hw = { +- .clk_src = 0, +- .flags = MSDC_CD_PIN_EN | MSDC_REMOVABLE, +-// .flags = MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE, +-}; +- +-/* end of +++ */ +- +-static int msdc_rsp[] = { +- 0, /* RESP_NONE */ +- 1, /* RESP_R1 */ +- 2, /* RESP_R2 */ +- 3, /* RESP_R3 */ +- 4, /* RESP_R4 */ +- 1, /* RESP_R5 */ +- 1, /* RESP_R6 */ +- 1, /* RESP_R7 */ +- 7, /* RESP_R1b */ +-}; +- +-#define msdc_dma_on() sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_PIO) +- +-static void msdc_reset_hw(struct msdc_host *host) +-{ +- sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); +- while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST) +- cpu_relax(); +-} +- +-#define msdc_clr_int() \ +- do { \ +- volatile u32 val = readl(host->base + MSDC_INT); \ +- writel(val, host->base + MSDC_INT); \ +- } while (0) +- +-static void msdc_clr_fifo(struct msdc_host *host) +-{ +- sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); +- while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR) +- cpu_relax(); +-} +- +-#define msdc_irq_save(val) \ +- do { \ +- val = readl(host->base + MSDC_INTEN); \ +- sdr_clr_bits(host->base + MSDC_INTEN, val); \ +- } while (0) +- +-#define msdc_irq_restore(val) \ +- do { \ +- sdr_set_bits(host->base + MSDC_INTEN, val); \ +- } while (0) +- +-/* clock source for host: global */ +-#if defined(CONFIG_SOC_MT7620) +-static u32 hclks[] = {48000000}; /* +/- by chhung */ +-#elif defined(CONFIG_SOC_MT7621) +-static u32 hclks[] = {50000000}; /* +/- by chhung */ +-#endif +- +-//============================================ +-// the power for msdc host controller: global +-// always keep the VMC on. +-//============================================ +-#define msdc_vcore_on(host) \ +- do { \ +- INIT_MSG("[+]VMC ref. count<%d>", ++host->pwr_ref); \ +- (void)hwPowerOn(MT65XX_POWER_LDO_VMC, VOL_3300, "SD"); \ +- } while (0) +-#define msdc_vcore_off(host) \ +- do { \ +- INIT_MSG("[-]VMC ref. count<%d>", --host->pwr_ref); \ +- (void)hwPowerDown(MT65XX_POWER_LDO_VMC, "SD"); \ +- } while (0) +- +-//==================================== +-// the vdd output for card: global +-// always keep the VMCH on. +-//==================================== +-#define msdc_vdd_on(host) \ +- do { \ +- (void)hwPowerOn(MT65XX_POWER_LDO_VMCH, VOL_3300, "SD"); \ +- } while (0) +-#define msdc_vdd_off(host) \ +- do { \ +- (void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \ +- } while (0) +- +-#define sdc_is_busy() (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) +-#define sdc_is_cmd_busy() (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) +- +-#define sdc_send_cmd(cmd, arg) \ +- do { \ +- writel((arg), host->base + SDC_ARG); \ +- writel((cmd), host->base + SDC_CMD); \ +- } while (0) +- +-/* +++ by chhung */ +-#ifndef __ASSEMBLY__ +-#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) +-#else +-#define PHYSADDR(a) ((a) & 0x1fffffff) +-#endif +-/* end of +++ */ +-static unsigned int msdc_do_command(struct msdc_host *host, +- struct mmc_command *cmd, +- int tune, +- unsigned long timeout); +- +-static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd); +- +-#ifdef MT6575_SD_DEBUG +-static void msdc_dump_card_status(struct msdc_host *host, u32 status) +-{ +-/* N_MSG is currently a no-op */ +-#if 0 +- static char *state[] = { +- "Idle", /* 0 */ +- "Ready", /* 1 */ +- "Ident", /* 2 */ +- "Stby", /* 3 */ +- "Tran", /* 4 */ +- "Data", /* 5 */ +- "Rcv", /* 6 */ +- "Prg", /* 7 */ +- "Dis", /* 8 */ +- "Reserved", /* 9 */ +- "Reserved", /* 10 */ +- "Reserved", /* 11 */ +- "Reserved", /* 12 */ +- "Reserved", /* 13 */ +- "Reserved", /* 14 */ +- "I/O mode", /* 15 */ +- }; +-#endif +- if (status & R1_OUT_OF_RANGE) +- N_MSG(RSP, "[CARD_STATUS] Out of Range"); +- if (status & R1_ADDRESS_ERROR) +- N_MSG(RSP, "[CARD_STATUS] Address Error"); +- if (status & R1_BLOCK_LEN_ERROR) +- N_MSG(RSP, "[CARD_STATUS] Block Len Error"); +- if (status & R1_ERASE_SEQ_ERROR) +- N_MSG(RSP, "[CARD_STATUS] Erase Seq Error"); +- if (status & R1_ERASE_PARAM) +- N_MSG(RSP, "[CARD_STATUS] Erase Param"); +- if (status & R1_WP_VIOLATION) +- N_MSG(RSP, "[CARD_STATUS] WP Violation"); +- if (status & R1_CARD_IS_LOCKED) +- N_MSG(RSP, "[CARD_STATUS] Card is Locked"); +- if (status & R1_LOCK_UNLOCK_FAILED) +- N_MSG(RSP, "[CARD_STATUS] Lock/Unlock Failed"); +- if (status & R1_COM_CRC_ERROR) +- N_MSG(RSP, "[CARD_STATUS] Command CRC Error"); +- if (status & R1_ILLEGAL_COMMAND) +- N_MSG(RSP, "[CARD_STATUS] Illegal Command"); +- if (status & R1_CARD_ECC_FAILED) +- N_MSG(RSP, "[CARD_STATUS] Card ECC Failed"); +- if (status & R1_CC_ERROR) +- N_MSG(RSP, "[CARD_STATUS] CC Error"); +- if (status & R1_ERROR) +- N_MSG(RSP, "[CARD_STATUS] Error"); +- if (status & R1_UNDERRUN) +- N_MSG(RSP, "[CARD_STATUS] Underrun"); +- if (status & R1_OVERRUN) +- N_MSG(RSP, "[CARD_STATUS] Overrun"); +- if (status & R1_CID_CSD_OVERWRITE) +- N_MSG(RSP, "[CARD_STATUS] CID/CSD Overwrite"); +- if (status & R1_WP_ERASE_SKIP) +- N_MSG(RSP, "[CARD_STATUS] WP Eraser Skip"); +- if (status & R1_CARD_ECC_DISABLED) +- N_MSG(RSP, "[CARD_STATUS] Card ECC Disabled"); +- if (status & R1_ERASE_RESET) +- N_MSG(RSP, "[CARD_STATUS] Erase Reset"); +- if (status & R1_READY_FOR_DATA) +- N_MSG(RSP, "[CARD_STATUS] Ready for Data"); +- if (status & R1_SWITCH_ERROR) +- N_MSG(RSP, "[CARD_STATUS] Switch error"); +- if (status & R1_APP_CMD) +- N_MSG(RSP, "[CARD_STATUS] App Command"); +- +- N_MSG(RSP, "[CARD_STATUS] '%s' State", state[R1_CURRENT_STATE(status)]); +-} +- +-static void msdc_dump_ocr_reg(struct msdc_host *host, u32 resp) +-{ +- if (resp & (1 << 7)) +- N_MSG(RSP, "[OCR] Low Voltage Range"); +- if (resp & (1 << 15)) +- N_MSG(RSP, "[OCR] 2.7-2.8 volt"); +- if (resp & (1 << 16)) +- N_MSG(RSP, "[OCR] 2.8-2.9 volt"); +- if (resp & (1 << 17)) +- N_MSG(RSP, "[OCR] 2.9-3.0 volt"); +- if (resp & (1 << 18)) +- N_MSG(RSP, "[OCR] 3.0-3.1 volt"); +- if (resp & (1 << 19)) +- N_MSG(RSP, "[OCR] 3.1-3.2 volt"); +- if (resp & (1 << 20)) +- N_MSG(RSP, "[OCR] 3.2-3.3 volt"); +- if (resp & (1 << 21)) +- N_MSG(RSP, "[OCR] 3.3-3.4 volt"); +- if (resp & (1 << 22)) +- N_MSG(RSP, "[OCR] 3.4-3.5 volt"); +- if (resp & (1 << 23)) +- N_MSG(RSP, "[OCR] 3.5-3.6 volt"); +- if (resp & (1 << 24)) +- N_MSG(RSP, "[OCR] Switching to 1.8V Accepted (S18A)"); +- if (resp & (1 << 30)) +- N_MSG(RSP, "[OCR] Card Capacity Status (CCS)"); +- if (resp & (1 << 31)) +- N_MSG(RSP, "[OCR] Card Power Up Status (Idle)"); +- else +- N_MSG(RSP, "[OCR] Card Power Up Status (Busy)"); +-} +- +-static void msdc_dump_rca_resp(struct msdc_host *host, u32 resp) +-{ +- u32 status = (((resp >> 15) & 0x1) << 23) | +- (((resp >> 14) & 0x1) << 22) | +- (((resp >> 13) & 0x1) << 19) | +- (resp & 0x1fff); +- +- N_MSG(RSP, "[RCA] 0x%.4x", resp >> 16); +- msdc_dump_card_status(host, status); +-} +- +-static void msdc_dump_io_resp(struct msdc_host *host, u32 resp) +-{ +- u32 flags = (resp >> 8) & 0xFF; +-#if 0 +- char *state[] = {"DIS", "CMD", "TRN", "RFU"}; +-#endif +- if (flags & (1 << 7)) +- N_MSG(RSP, "[IO] COM_CRC_ERR"); +- if (flags & (1 << 6)) +- N_MSG(RSP, "[IO] Illegal command"); +- if (flags & (1 << 3)) +- N_MSG(RSP, "[IO] Error"); +- if (flags & (1 << 2)) +- N_MSG(RSP, "[IO] RFU"); +- if (flags & (1 << 1)) +- N_MSG(RSP, "[IO] Function number error"); +- if (flags & (1 << 0)) +- N_MSG(RSP, "[IO] Out of range"); +- +- N_MSG(RSP, "[IO] State: %s, Data:0x%x", state[(resp >> 12) & 0x3], resp & 0xFF); +-} +-#endif +- +-static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) +-{ +- u32 timeout, clk_ns; +- +- host->timeout_ns = ns; +- host->timeout_clks = clks; +- +- clk_ns = 1000000000UL / host->sclk; +- timeout = ns / clk_ns + clks; +- timeout = timeout >> 16; /* in 65536 sclk cycle unit */ +- timeout = timeout > 1 ? timeout - 1 : 0; +- timeout = timeout > 255 ? 255 : timeout; +- +- sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, timeout); +- +- N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles", +- ns, clks, timeout + 1); +-} +- +-static void msdc_tasklet_card(struct work_struct *work) +-{ +- struct msdc_host *host = (struct msdc_host *)container_of(work, +- struct msdc_host, card_delaywork.work); +- u32 inserted; +- u32 status = 0; +- //u32 change = 0; +- +- spin_lock(&host->lock); +- +- status = readl(host->base + MSDC_PS); +- if (cd_active_low) +- inserted = (status & MSDC_PS_CDSTS) ? 0 : 1; +- else +- inserted = (status & MSDC_PS_CDSTS) ? 1 : 0; +- +-#if 0 +- change = host->card_inserted ^ inserted; +- host->card_inserted = inserted; +- +- if (change && !host->suspend) { +- if (inserted) +- host->mmc->f_max = HOST_MAX_MCLK; // work around +- mmc_detect_change(host->mmc, msecs_to_jiffies(20)); +- } +-#else /* Make sure: handle the last interrupt */ +- host->card_inserted = inserted; +- +- if (!host->suspend) { +- host->mmc->f_max = HOST_MAX_MCLK; +- mmc_detect_change(host->mmc, msecs_to_jiffies(20)); +- } +- +- IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed"); +-#endif +- +- spin_unlock(&host->lock); +-} +- +-#if 0 /* --- by chhung */ +-/* For E2 only */ +-static u8 clk_src_bit[4] = { +- 0, 3, 5, 7 +-}; +- +-static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc) +-{ +- u32 val; +- +- BUG_ON(clksrc > 3); +- INIT_MSG("set clock source to <%d>", clksrc); +- +- val = readl(host->base + MSDC_CLKSRC_REG); +- if (readl(host->base + MSDC_ECO_VER) >= 4) { +- val &= ~(0x3 << clk_src_bit[host->id]); +- val |= clksrc << clk_src_bit[host->id]; +- } else { +- val &= ~0x3; val |= clksrc; +- } +- writel(val, host->base + MSDC_CLKSRC_REG); +- +- host->hclk = hclks[clksrc]; +- host->hw->clk_src = clksrc; +-} +-#endif /* end of --- */ +- +-static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz) +-{ +- //struct msdc_hw *hw = host->hw; +- u32 mode; +- u32 flags; +- u32 div; +- u32 sclk; +- u32 hclk = host->hclk; +- //u8 clksrc = hw->clk_src; +- +- if (!hz) { // set mmc system clock to 0 ? +- //ERR_MSG("set mclk to 0!!!"); +- msdc_reset_hw(host); +- return; +- } +- +- msdc_irq_save(flags); +- +- if (ddr) { +- mode = 0x2; /* ddr mode and use divisor */ +- if (hz >= (hclk >> 2)) { +- div = 1; /* mean div = 1/4 */ +- sclk = hclk >> 2; /* sclk = clk / 4 */ +- } else { +- div = (hclk + ((hz << 2) - 1)) / (hz << 2); +- sclk = (hclk >> 2) / div; +- } +- } else if (hz >= hclk) { /* bug fix */ +- mode = 0x1; /* no divisor and divisor is ignored */ +- div = 0; +- sclk = hclk; +- } else { +- mode = 0x0; /* use divisor */ +- if (hz >= (hclk >> 1)) { +- div = 0; /* mean div = 1/2 */ +- sclk = hclk >> 1; /* sclk = clk / 2 */ +- } else { +- div = (hclk + ((hz << 2) - 1)) / (hz << 2); +- sclk = (hclk >> 2) / div; +- } +- } +- +- /* set clock mode and divisor */ +- sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, mode); +- sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKDIV, div); +- +- /* wait clock stable */ +- while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) +- cpu_relax(); +- +- host->sclk = sclk; +- host->mclk = hz; +- msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); // need? +- +- INIT_MSG("================"); +- INIT_MSG("!!! Set<%dKHz> Source<%dKHz> -> sclk<%dKHz>", hz / 1000, hclk / 1000, sclk / 1000); +- INIT_MSG("================"); +- +- msdc_irq_restore(flags); +-} +- +-/* Fix me. when need to abort */ +-static void msdc_abort_data(struct msdc_host *host) +-{ +- struct mmc_command *stop = host->mrq->stop; +- +- ERR_MSG("Need to Abort."); +- +- msdc_reset_hw(host); +- msdc_clr_fifo(host); +- msdc_clr_int(); +- +- // need to check FIFO count 0 ? +- +- if (stop) { /* try to stop, but may not success */ +- ERR_MSG("stop when abort CMD<%d>", stop->opcode); +- (void)msdc_do_command(host, stop, 0, CMD_TIMEOUT); +- } +- +- //if (host->mclk >= 25000000) { +- // msdc_set_mclk(host, 0, host->mclk >> 1); +- //} +-} +- +-#if 0 /* --- by chhung */ +-static void msdc_pin_config(struct msdc_host *host, int mode) +-{ +- struct msdc_hw *hw = host->hw; +- int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; +- +- /* Config WP pin */ +- if (hw->flags & MSDC_WP_PIN_EN) { +- if (hw->config_gpio_pin) /* NULL */ +- hw->config_gpio_pin(MSDC_WP_PIN, pull); +- } +- +- switch (mode) { +- case MSDC_PIN_PULL_UP: +- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */ +- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); +- break; +- case MSDC_PIN_PULL_DOWN: +- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ +- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */ +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1); +- break; +- case MSDC_PIN_PULL_NONE: +- default: +- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ +- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); +- break; +- } +- +- N_MSG(CFG, "Pins mode(%d), down(%d), up(%d)", +- mode, MSDC_PIN_PULL_DOWN, MSDC_PIN_PULL_UP); +-} +- +-void msdc_pin_reset(struct msdc_host *host, int mode) +-{ +- struct msdc_hw *hw = (struct msdc_hw *)host->hw; +- int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; +- +- /* Config reset pin */ +- if (hw->flags & MSDC_RST_PIN_EN) { +- if (hw->config_gpio_pin) /* NULL */ +- hw->config_gpio_pin(MSDC_RST_PIN, pull); +- +- if (mode == MSDC_PIN_PULL_UP) +- sdr_clr_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST); +- else +- sdr_set_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST); +- } +-} +- +-static void msdc_core_power(struct msdc_host *host, int on) +-{ +- N_MSG(CFG, "Turn %s %s power (copower: %d -> %d)", +- on ? "on" : "off", "core", host->core_power, on); +- +- if (on && host->core_power == 0) { +- msdc_vcore_on(host); +- host->core_power = 1; +- msleep(1); +- } else if (!on && host->core_power == 1) { +- msdc_vcore_off(host); +- host->core_power = 0; +- msleep(1); +- } +-} +- +-static void msdc_host_power(struct msdc_host *host, int on) +-{ +- N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "host"); +- +- if (on) { +- //msdc_core_power(host, 1); // need do card detection. +- msdc_pin_reset(host, MSDC_PIN_PULL_UP); +- } else { +- msdc_pin_reset(host, MSDC_PIN_PULL_DOWN); +- //msdc_core_power(host, 0); +- } +-} +- +-static void msdc_card_power(struct msdc_host *host, int on) +-{ +- N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "card"); +- +- if (on) { +- msdc_pin_config(host, MSDC_PIN_PULL_UP); +- //msdc_vdd_on(host); // need todo card detection. +- msleep(1); +- } else { +- //msdc_vdd_off(host); +- msdc_pin_config(host, MSDC_PIN_PULL_DOWN); +- msleep(1); +- } +-} +- +-static void msdc_set_power_mode(struct msdc_host *host, u8 mode) +-{ +- N_MSG(CFG, "Set power mode(%d)", mode); +- +- if (host->power_mode == MMC_POWER_OFF && mode != MMC_POWER_OFF) { +- msdc_host_power(host, 1); +- msdc_card_power(host, 1); +- } else if (host->power_mode != MMC_POWER_OFF && mode == MMC_POWER_OFF) { +- msdc_card_power(host, 0); +- msdc_host_power(host, 0); +- } +- host->power_mode = mode; +-} +-#endif /* end of --- */ +- +-#ifdef CONFIG_PM +-/* +- register as callback function of WIFI(combo_sdio_register_pm) . +- can called by msdc_drv_suspend/resume too. +-*/ +-static void msdc_pm(pm_message_t state, void *data) +-{ +- struct msdc_host *host = (struct msdc_host *)data; +- int evt = state.event; +- +- if (evt == PM_EVENT_USER_RESUME || evt == PM_EVENT_USER_SUSPEND) { +- INIT_MSG("USR_%s: suspend<%d> power<%d>", +- evt == PM_EVENT_USER_RESUME ? "EVENT_USER_RESUME" : "EVENT_USER_SUSPEND", +- host->suspend, host->power_mode); +- } +- +- if (evt == PM_EVENT_SUSPEND || evt == PM_EVENT_USER_SUSPEND) { +- if (host->suspend) /* already suspend */ /* default 0*/ +- return; +- +- /* for memory card. already power off by mmc */ +- if (evt == PM_EVENT_SUSPEND && host->power_mode == MMC_POWER_OFF) +- return; +- +- host->suspend = 1; +- host->pm_state = state; /* default PMSG_RESUME */ +- +- } else if (evt == PM_EVENT_RESUME || evt == PM_EVENT_USER_RESUME) { +- if (!host->suspend) { +- //ERR_MSG("warning: already resume"); +- return; +- } +- +- /* No PM resume when USR suspend */ +- if (evt == PM_EVENT_RESUME && host->pm_state.event == PM_EVENT_USER_SUSPEND) { +- ERR_MSG("PM Resume when in USR Suspend"); /* won't happen. */ +- return; +- } +- +- host->suspend = 0; +- host->pm_state = state; +- +- } +-} +-#endif +- +-static inline u32 msdc_cmd_find_resp(struct mmc_command *cmd) +-{ +- u32 opcode = cmd->opcode; +- u32 resp; +- +- if (opcode == MMC_SET_RELATIVE_ADDR) { +- resp = (mmc_cmd_type(cmd) == MMC_CMD_BCR) ? RESP_R6 : RESP_R1; +- } else if (opcode == MMC_FAST_IO) { +- resp = RESP_R4; +- } else if (opcode == MMC_GO_IRQ_STATE) { +- resp = RESP_R5; +- } else if (opcode == MMC_SELECT_CARD) { +- resp = (cmd->arg != 0) ? RESP_R1B : RESP_NONE; +- } else if (opcode == SD_IO_RW_DIRECT || opcode == SD_IO_RW_EXTENDED) { +- resp = RESP_R1; /* SDIO workaround. */ +- } else if (opcode == SD_SEND_IF_COND && (mmc_cmd_type(cmd) == MMC_CMD_BCR)) { +- resp = RESP_R1; +- } else { +- switch (mmc_resp_type(cmd)) { +- case MMC_RSP_R1: +- resp = RESP_R1; +- break; +- case MMC_RSP_R1B: +- resp = RESP_R1B; +- break; +- case MMC_RSP_R2: +- resp = RESP_R2; +- break; +- case MMC_RSP_R3: +- resp = RESP_R3; +- break; +- case MMC_RSP_NONE: +- default: +- resp = RESP_NONE; +- break; +- } +- } +- +- return resp; +-} +- +-/*--------------------------------------------------------------------------*/ +-/* mmc_host_ops members */ +-/*--------------------------------------------------------------------------*/ +-static unsigned int msdc_command_start(struct msdc_host *host, +- struct mmc_command *cmd, +- unsigned long timeout) +-{ +- u32 opcode = cmd->opcode; +- u32 rawcmd; +- u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | +- MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | +- MSDC_INT_ACMD19_DONE; +- +- u32 resp; +- unsigned long tmo; +- +- /* Protocol layer does not provide response type, but our hardware needs +- * to know exact type, not just size! +- */ +- resp = msdc_cmd_find_resp(cmd); +- +- cmd->error = 0; +- /* rawcmd : +- * vol_swt << 30 | auto_cmd << 28 | blklen << 16 | go_irq << 15 | +- * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode +- */ +- rawcmd = opcode | msdc_rsp[resp] << 7 | host->blksz << 16; +- +- if (opcode == MMC_READ_MULTIPLE_BLOCK) { +- rawcmd |= (2 << 11); +- } else if (opcode == MMC_READ_SINGLE_BLOCK) { +- rawcmd |= (1 << 11); +- } else if (opcode == MMC_WRITE_MULTIPLE_BLOCK) { +- rawcmd |= ((2 << 11) | (1 << 13)); +- } else if (opcode == MMC_WRITE_BLOCK) { +- rawcmd |= ((1 << 11) | (1 << 13)); +- } else if (opcode == SD_IO_RW_EXTENDED) { +- if (cmd->data->flags & MMC_DATA_WRITE) +- rawcmd |= (1 << 13); +- if (cmd->data->blocks > 1) +- rawcmd |= (2 << 11); +- else +- rawcmd |= (1 << 11); +- } else if (opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int)-1) { +- rawcmd |= (1 << 14); +- } else if ((opcode == SD_APP_SEND_SCR) || +- (opcode == SD_APP_SEND_NUM_WR_BLKS) || +- (opcode == SD_SWITCH && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || +- (opcode == SD_APP_SD_STATUS && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || +- (opcode == MMC_SEND_EXT_CSD && (mmc_cmd_type(cmd) == MMC_CMD_ADTC))) { +- rawcmd |= (1 << 11); +- } else if (opcode == MMC_STOP_TRANSMISSION) { +- rawcmd |= (1 << 14); +- rawcmd &= ~(0x0FFF << 16); +- } +- +- N_MSG(CMD, "CMD<%d><0x%.8x> Arg<0x%.8x>", opcode, rawcmd, cmd->arg); +- +- tmo = jiffies + timeout; +- +- if (opcode == MMC_SEND_STATUS) { +- for (;;) { +- if (!sdc_is_cmd_busy()) +- break; +- +- if (time_after(jiffies, tmo)) { +- ERR_MSG("XXX cmd_busy timeout: before CMD<%d>", opcode); +- cmd->error = -ETIMEDOUT; +- msdc_reset_hw(host); +- goto end; +- } +- } +- } else { +- for (;;) { +- if (!sdc_is_busy()) +- break; +- if (time_after(jiffies, tmo)) { +- ERR_MSG("XXX sdc_busy timeout: before CMD<%d>", opcode); +- cmd->error = -ETIMEDOUT; +- msdc_reset_hw(host); +- goto end; +- } +- } +- } +- +- //BUG_ON(in_interrupt()); +- host->cmd = cmd; +- host->cmd_rsp = resp; +- +- init_completion(&host->cmd_done); +- +- sdr_set_bits(host->base + MSDC_INTEN, wints); +- sdc_send_cmd(rawcmd, cmd->arg); +- +-end: +- return cmd->error; +-} +- +-static unsigned int msdc_command_resp(struct msdc_host *host, +- struct mmc_command *cmd, +- int tune, +- unsigned long timeout) +- __must_hold(&host->lock) +-{ +- u32 opcode = cmd->opcode; +- //u32 rawcmd; +- u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | +- MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | +- MSDC_INT_ACMD19_DONE; +- +- BUG_ON(in_interrupt()); +- //init_completion(&host->cmd_done); +- //sdr_set_bits(host->base + MSDC_INTEN, wints); +- +- spin_unlock(&host->lock); +- if (!wait_for_completion_timeout(&host->cmd_done, 10 * timeout)) { +- ERR_MSG("XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>", opcode, cmd->arg); +- cmd->error = -ETIMEDOUT; +- msdc_reset_hw(host); +- } +- spin_lock(&host->lock); +- +- sdr_clr_bits(host->base + MSDC_INTEN, wints); +- host->cmd = NULL; +- +-//end: +-#ifdef MT6575_SD_DEBUG +- switch (resp) { +- case RESP_NONE: +- N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)", opcode, cmd->error, resp); +- break; +- case RESP_R2: +- N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= %.8x %.8x %.8x %.8x", +- opcode, cmd->error, resp, cmd->resp[0], cmd->resp[1], +- cmd->resp[2], cmd->resp[3]); +- break; +- default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ +- N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= 0x%.8x", +- opcode, cmd->error, resp, cmd->resp[0]); +- if (cmd->error == 0) { +- switch (resp) { +- case RESP_R1: +- case RESP_R1B: +- msdc_dump_card_status(host, cmd->resp[0]); +- break; +- case RESP_R3: +- msdc_dump_ocr_reg(host, cmd->resp[0]); +- break; +- case RESP_R5: +- msdc_dump_io_resp(host, cmd->resp[0]); +- break; +- case RESP_R6: +- msdc_dump_rca_resp(host, cmd->resp[0]); +- break; +- } +- } +- break; +- } +-#endif +- +- /* do we need to save card's RCA when SD_SEND_RELATIVE_ADDR */ +- +- if (!tune) +- return cmd->error; +- +- /* memory card CRC */ +- if (host->hw->flags & MSDC_REMOVABLE && cmd->error == -EIO) { +- /* check if has data phase */ +- if (readl(host->base + SDC_CMD) & 0x1800) { +- msdc_abort_data(host); +- } else { +- /* do basic: reset*/ +- msdc_reset_hw(host); +- msdc_clr_fifo(host); +- msdc_clr_int(); +- } +- cmd->error = msdc_tune_cmdrsp(host, cmd); +- } +- +- // check DAT0 +- /* if (resp == RESP_R1B) { +- while ((readl(host->base + MSDC_PS) & 0x10000) != 0x10000); +- } */ +- /* CMD12 Error Handle */ +- +- return cmd->error; +-} +- +-static unsigned int msdc_do_command(struct msdc_host *host, +- struct mmc_command *cmd, +- int tune, +- unsigned long timeout) +-{ +- if (msdc_command_start(host, cmd, timeout)) +- goto end; +- +- if (msdc_command_resp(host, cmd, tune, timeout)) +- goto end; +- +-end: +- +- N_MSG(CMD, " return<%d> resp<0x%.8x>", cmd->error, cmd->resp[0]); +- return cmd->error; +-} +- +-#if 0 /* --- by chhung */ +-// DMA resume / start / stop +-static void msdc_dma_resume(struct msdc_host *host) +-{ +- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1); +- +- N_MSG(DMA, "DMA resume"); +-} +-#endif /* end of --- */ +- +-static void msdc_dma_start(struct msdc_host *host) +-{ +- u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR; +- +- sdr_set_bits(host->base + MSDC_INTEN, wints); +- //dsb(); /* --- by chhung */ +- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1); +- +- N_MSG(DMA, "DMA start"); +-} +- +-static void msdc_dma_stop(struct msdc_host *host) +-{ +- //u32 retries=500; +- u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR; +- +- N_MSG(DMA, "DMA status: 0x%.8x", readl(host->base + MSDC_DMA_CFG)); +- //while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS); +- +- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1); +- while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS) +- ; +- +- //dsb(); /* --- by chhung */ +- sdr_clr_bits(host->base + MSDC_INTEN, wints); /* Not just xfer_comp */ +- +- N_MSG(DMA, "DMA stop"); +-} +- +-/* calc checksum */ +-static u8 msdc_dma_calcs(u8 *buf, u32 len) +-{ +- u32 i, sum = 0; +- +- for (i = 0; i < len; i++) +- sum += buf[i]; +- return 0xFF - (u8)sum; +-} +- +-static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, +- struct scatterlist *sg_cmd, unsigned int sglen) +-{ +- struct scatterlist *sg; +- struct gpd *gpd; +- struct bd *bd; +- u32 j; +- +- BUG_ON(sglen > MAX_BD_NUM); /* not support currently */ +- +- N_MSG(DMA, "DMA sglen<%d> xfersz<%d>", sglen, host->xfer_size); +- +- gpd = dma->gpd; +- bd = dma->bd; +- +- /* modify gpd*/ +- //gpd->intr = 0; +- gpd->hwo = 1; /* hw will clear it */ +- gpd->bdp = 1; +- gpd->chksum = 0; /* need to clear first. */ +- gpd->chksum = msdc_dma_calcs((u8 *)gpd, 16); +- +- /* modify bd*/ +- for_each_sg(sg_cmd, sg, sglen, j) { +- bd[j].blkpad = 0; +- bd[j].dwpad = 0; +- bd[j].ptr = (void *)sg_dma_address(sg); +- bd[j].buflen = sg_dma_len(sg); +- +- if (j == sglen - 1) +- bd[j].eol = 1; /* the last bd */ +- else +- bd[j].eol = 0; +- +- bd[j].chksum = 0; /* checksume need to clear first */ +- bd[j].chksum = msdc_dma_calcs((u8 *)(&bd[j]), 16); +- } +- +- sdr_set_field(host->base + MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1); +- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ, +- MSDC_BRUST_64B); +- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1); +- +- writel(PHYSADDR((u32)dma->gpd_addr), host->base + MSDC_DMA_SA); +- +- N_MSG(DMA, "DMA_CTRL = 0x%x", readl(host->base + MSDC_DMA_CTRL)); +- N_MSG(DMA, "DMA_CFG = 0x%x", readl(host->base + MSDC_DMA_CFG)); +- N_MSG(DMA, "DMA_SA = 0x%x", readl(host->base + MSDC_DMA_SA)); +-} +- +-static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq) +- __must_hold(&host->lock) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- struct mmc_command *cmd; +- struct mmc_data *data; +- //u32 intsts = 0; +- int read = 1, send_type = 0; +- +-#define SND_DAT 0 +-#define SND_CMD 1 +- +- BUG_ON(mmc == NULL); +- BUG_ON(mrq == NULL); +- +- host->error = 0; +- +- cmd = mrq->cmd; +- data = mrq->cmd->data; +- +-#if 0 /* --- by chhung */ +- //if(host->id ==1){ +- N_MSG(OPS, "enable clock!"); +- msdc_ungate_clock(host->id); +- //} +-#endif /* end of --- */ +- +- if (!data) { +- send_type = SND_CMD; +- if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0) +- goto done; +- } else { +- BUG_ON(data->blksz > HOST_MAX_BLKSZ); +- send_type = SND_DAT; +- +- data->error = 0; +- read = data->flags & MMC_DATA_READ ? 1 : 0; +- host->data = data; +- host->xfer_size = data->blocks * data->blksz; +- host->blksz = data->blksz; +- +- if (read) { +- if ((host->timeout_ns != data->timeout_ns) || +- (host->timeout_clks != data->timeout_clks)) { +- msdc_set_timeout(host, data->timeout_ns, data->timeout_clks); +- } +- } +- +- writel(data->blocks, host->base + SDC_BLK_NUM); +- //msdc_clr_fifo(host); /* no need */ +- +- msdc_dma_on(); /* enable DMA mode first!! */ +- init_completion(&host->xfer_done); +- +- /* start the command first*/ +- if (msdc_command_start(host, cmd, CMD_TIMEOUT) != 0) +- goto done; +- +- data->sg_count = dma_map_sg(mmc_dev(mmc), data->sg, +- data->sg_len, +- mmc_get_dma_dir(data)); +- msdc_dma_setup(host, &host->dma, data->sg, +- data->sg_count); +- +- /* then wait command done */ +- if (msdc_command_resp(host, cmd, 1, CMD_TIMEOUT) != 0) +- goto done; +- +- /* for read, the data coming too fast, then CRC error +- start DMA no business with CRC. */ +- //init_completion(&host->xfer_done); +- msdc_dma_start(host); +- +- spin_unlock(&host->lock); +- if (!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)) { +- ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz); +- ERR_MSG(" DMA_SA = 0x%x", +- readl(host->base + MSDC_DMA_SA)); +- ERR_MSG(" DMA_CA = 0x%x", +- readl(host->base + MSDC_DMA_CA)); +- ERR_MSG(" DMA_CTRL = 0x%x", +- readl(host->base + MSDC_DMA_CTRL)); +- ERR_MSG(" DMA_CFG = 0x%x", +- readl(host->base + MSDC_DMA_CFG)); +- data->error = -ETIMEDOUT; +- +- msdc_reset_hw(host); +- msdc_clr_fifo(host); +- msdc_clr_int(); +- } +- spin_lock(&host->lock); +- msdc_dma_stop(host); +- +- /* Last: stop transfer */ +- if (data->stop) { +- if (msdc_do_command(host, data->stop, 0, CMD_TIMEOUT) != 0) +- goto done; +- } +- } +- +-done: +- if (data != NULL) { +- host->data = NULL; +- dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, +- mmc_get_dma_dir(data)); +- host->blksz = 0; +- +-#if 0 // don't stop twice! +- if (host->hw->flags & MSDC_REMOVABLE && data->error) { +- msdc_abort_data(host); +- /* reset in IRQ, stop command has issued. -> No need */ +- } +-#endif +- +- N_MSG(OPS, "CMD<%d> data<%s %s> blksz<%d> block<%d> error<%d>", cmd->opcode, (dma ? "dma" : "pio"), +- (read ? "read " : "write"), data->blksz, data->blocks, data->error); +- } +- +-#if 0 /* --- by chhung */ +-#if 1 +- //if(host->id==1) { +- if (send_type == SND_CMD) { +- if (cmd->opcode == MMC_SEND_STATUS) { +- if ((cmd->resp[0] & CARD_READY_FOR_DATA) || (CARD_CURRENT_STATE(cmd->resp[0]) != 7)) { +- N_MSG(OPS, "disable clock, CMD13 IDLE"); +- msdc_gate_clock(host->id); +- } +- } else { +- N_MSG(OPS, "disable clock, CMD<%d>", cmd->opcode); +- msdc_gate_clock(host->id); +- } +- } else { +- if (read) { +- N_MSG(OPS, "disable clock!!! Read CMD<%d>", cmd->opcode); +- msdc_gate_clock(host->id); +- } +- } +- //} +-#else +- msdc_gate_clock(host->id); +-#endif +-#endif /* end of --- */ +- +- if (mrq->cmd->error) +- host->error = 0x001; +- if (mrq->data && mrq->data->error) +- host->error |= 0x010; +- if (mrq->stop && mrq->stop->error) +- host->error |= 0x100; +- +- //if (host->error) ERR_MSG("host->error<%d>", host->error); +- +- return host->error; +-} +- +-static int msdc_app_cmd(struct mmc_host *mmc, struct msdc_host *host) +-{ +- struct mmc_command cmd; +- struct mmc_request mrq; +- u32 err; +- +- memset(&cmd, 0, sizeof(struct mmc_command)); +- cmd.opcode = MMC_APP_CMD; +-#if 0 /* bug: we meet mmc->card is null when ACMD6 */ +- cmd.arg = mmc->card->rca << 16; +-#else +- cmd.arg = host->app_cmd_arg; +-#endif +- cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; +- +- memset(&mrq, 0, sizeof(struct mmc_request)); +- mrq.cmd = &cmd; cmd.mrq = &mrq; +- cmd.data = NULL; +- +- err = msdc_do_command(host, &cmd, 0, CMD_TIMEOUT); +- return err; +-} +- +-static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd) +-{ +- int result = -1; +- u32 rsmpl, cur_rsmpl, orig_rsmpl; +- u32 rrdly, cur_rrdly = 0xffffffff, orig_rrdly; +- u32 skip = 1; +- +- /* ==== don't support 3.0 now ==== +- 1: R_SMPL[1] +- 2: PAD_CMD_RESP_RXDLY[26:22] +- ==========================*/ +- +- // save the previous tune result +- sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl); +- sdr_get_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, +- &orig_rrdly); +- +- rrdly = 0; +- do { +- for (rsmpl = 0; rsmpl < 2; rsmpl++) { +- /* Lv1: R_SMPL[1] */ +- cur_rsmpl = (orig_rsmpl + rsmpl) % 2; +- if (skip == 1) { +- skip = 0; +- continue; +- } +- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, +- cur_rsmpl); +- +- if (host->app_cmd) { +- result = msdc_app_cmd(host->mmc, host); +- if (result) { +- ERR_MSG("TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>", +- host->mrq->cmd->opcode, cur_rrdly, cur_rsmpl); +- continue; +- } +- } +- result = msdc_do_command(host, cmd, 0, CMD_TIMEOUT); // not tune. +- ERR_MSG("TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>", cmd->opcode, +- (result == 0) ? "PASS" : "FAIL", cur_rrdly, cur_rsmpl); +- +- if (result == 0) +- return 0; +- if (result != -EIO) { +- ERR_MSG("TUNE_CMD<%d> Error<%d> not -EIO", cmd->opcode, result); +- return result; +- } +- +- /* should be EIO */ +- /* check if has data phase */ +- if (readl(host->base + SDC_CMD) & 0x1800) +- msdc_abort_data(host); +- } +- +- /* Lv2: PAD_CMD_RESP_RXDLY[26:22] */ +- cur_rrdly = (orig_rrdly + rrdly + 1) % 32; +- sdr_set_field(host->base + MSDC_PAD_TUNE, +- MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly); +- } while (++rrdly < 32); +- +- return result; +-} +- +-/* Support SD2.0 Only */ +-static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- u32 ddr = 0; +- u32 dcrc = 0; +- u32 rxdly, cur_rxdly0, cur_rxdly1; +- u32 dsmpl, cur_dsmpl, orig_dsmpl; +- u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; +- u32 cur_dat4, cur_dat5, cur_dat6, cur_dat7; +- u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; +- u32 orig_dat4, orig_dat5, orig_dat6, orig_dat7; +- int result = -1; +- u32 skip = 1; +- +- sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl); +- +- /* Tune Method 2. */ +- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); +- +- rxdly = 0; +- do { +- for (dsmpl = 0; dsmpl < 2; dsmpl++) { +- cur_dsmpl = (orig_dsmpl + dsmpl) % 2; +- if (skip == 1) { +- skip = 0; +- continue; +- } +- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, +- cur_dsmpl); +- +- if (host->app_cmd) { +- result = msdc_app_cmd(host->mmc, host); +- if (result) { +- ERR_MSG("TUNE_BREAD app_cmd<%d> failed", host->mrq->cmd->opcode); +- continue; +- } +- } +- result = msdc_do_request(mmc, mrq); +- +- sdr_get_field(host->base + SDC_DCRC_STS, +- SDC_DCRC_STS_POS | SDC_DCRC_STS_NEG, +- &dcrc); /* RO */ +- if (!ddr) +- dcrc &= ~SDC_DCRC_STS_NEG; +- ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>", +- (result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc, +- readl(host->base + MSDC_DAT_RDDLY0), +- readl(host->base + MSDC_DAT_RDDLY1), cur_dsmpl); +- +- /* Fix me: result is 0, but dcrc is still exist */ +- if (result == 0 && dcrc == 0) { +- goto done; +- } else { +- /* there is a case: command timeout, and data phase not processed */ +- if (mrq->data->error != 0 && +- mrq->data->error != -EIO) { +- ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", +- result, mrq->cmd->error, mrq->data->error); +- goto done; +- } +- } +- } +- +- cur_rxdly0 = readl(host->base + MSDC_DAT_RDDLY0); +- cur_rxdly1 = readl(host->base + MSDC_DAT_RDDLY1); +- +- /* E1 ECO. YD: Reverse */ +- if (readl(host->base + MSDC_ECO_VER) >= 4) { +- orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; +- orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; +- orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; +- orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; +- orig_dat4 = (cur_rxdly1 >> 24) & 0x1F; +- orig_dat5 = (cur_rxdly1 >> 16) & 0x1F; +- orig_dat6 = (cur_rxdly1 >> 8) & 0x1F; +- orig_dat7 = (cur_rxdly1 >> 0) & 0x1F; +- } else { +- orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; +- orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; +- orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; +- orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; +- orig_dat4 = (cur_rxdly1 >> 0) & 0x1F; +- orig_dat5 = (cur_rxdly1 >> 8) & 0x1F; +- orig_dat6 = (cur_rxdly1 >> 16) & 0x1F; +- orig_dat7 = (cur_rxdly1 >> 24) & 0x1F; +- } +- +- if (ddr) { +- cur_dat0 = (dcrc & (1 << 0) || dcrc & (1 << 8)) ? ((orig_dat0 + 1) % 32) : orig_dat0; +- cur_dat1 = (dcrc & (1 << 1) || dcrc & (1 << 9)) ? ((orig_dat1 + 1) % 32) : orig_dat1; +- cur_dat2 = (dcrc & (1 << 2) || dcrc & (1 << 10)) ? ((orig_dat2 + 1) % 32) : orig_dat2; +- cur_dat3 = (dcrc & (1 << 3) || dcrc & (1 << 11)) ? ((orig_dat3 + 1) % 32) : orig_dat3; +- } else { +- cur_dat0 = (dcrc & (1 << 0)) ? ((orig_dat0 + 1) % 32) : orig_dat0; +- cur_dat1 = (dcrc & (1 << 1)) ? ((orig_dat1 + 1) % 32) : orig_dat1; +- cur_dat2 = (dcrc & (1 << 2)) ? ((orig_dat2 + 1) % 32) : orig_dat2; +- cur_dat3 = (dcrc & (1 << 3)) ? ((orig_dat3 + 1) % 32) : orig_dat3; +- } +- cur_dat4 = (dcrc & (1 << 4)) ? ((orig_dat4 + 1) % 32) : orig_dat4; +- cur_dat5 = (dcrc & (1 << 5)) ? ((orig_dat5 + 1) % 32) : orig_dat5; +- cur_dat6 = (dcrc & (1 << 6)) ? ((orig_dat6 + 1) % 32) : orig_dat6; +- cur_dat7 = (dcrc & (1 << 7)) ? ((orig_dat7 + 1) % 32) : orig_dat7; +- +- cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); +- cur_rxdly1 = (cur_dat4 << 24) | (cur_dat5 << 16) | (cur_dat6 << 8) | (cur_dat7 << 0); +- +- writel(cur_rxdly0, host->base + MSDC_DAT_RDDLY0); +- writel(cur_rxdly1, host->base + MSDC_DAT_RDDLY1); +- +- } while (++rxdly < 32); +- +-done: +- return result; +-} +- +-static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- +- u32 wrrdly, cur_wrrdly = 0xffffffff, orig_wrrdly; +- u32 dsmpl, cur_dsmpl, orig_dsmpl; +- u32 rxdly, cur_rxdly0; +- u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; +- u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; +- int result = -1; +- u32 skip = 1; +- +- // MSDC_IOCON_DDR50CKD need to check. [Fix me] +- +- sdr_get_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, +- &orig_wrrdly); +- sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl); +- +- /* Tune Method 2. just DAT0 */ +- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); +- cur_rxdly0 = readl(host->base + MSDC_DAT_RDDLY0); +- +- /* E1 ECO. YD: Reverse */ +- if (readl(host->base + MSDC_ECO_VER) >= 4) { +- orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; +- orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; +- orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; +- orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; +- } else { +- orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; +- orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; +- orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; +- orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; +- } +- +- rxdly = 0; +- do { +- wrrdly = 0; +- do { +- for (dsmpl = 0; dsmpl < 2; dsmpl++) { +- cur_dsmpl = (orig_dsmpl + dsmpl) % 2; +- if (skip == 1) { +- skip = 0; +- continue; +- } +- sdr_set_field(host->base + MSDC_IOCON, +- MSDC_IOCON_DSPL, cur_dsmpl); +- +- if (host->app_cmd) { +- result = msdc_app_cmd(host->mmc, host); +- if (result) { +- ERR_MSG("TUNE_BWRITE app_cmd<%d> failed", host->mrq->cmd->opcode); +- continue; +- } +- } +- result = msdc_do_request(mmc, mrq); +- +- ERR_MSG("TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>", +- result == 0 ? "PASS" : "FAIL", +- cur_dsmpl, cur_wrrdly, cur_rxdly0); +- +- if (result == 0) { +- goto done; +- } else { +- /* there is a case: command timeout, and data phase not processed */ +- if (mrq->data->error != -EIO) { +- ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", +- result, mrq->cmd->error, mrq->data->error); +- goto done; +- } +- } +- } +- cur_wrrdly = (orig_wrrdly + wrrdly + 1) % 32; +- sdr_set_field(host->base + MSDC_PAD_TUNE, +- MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly); +- } while (++wrrdly < 32); +- +- cur_dat0 = (orig_dat0 + rxdly) % 32; /* only adjust bit-1 for crc */ +- cur_dat1 = orig_dat1; +- cur_dat2 = orig_dat2; +- cur_dat3 = orig_dat3; +- +- cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); +- writel(cur_rxdly0, host->base + MSDC_DAT_RDDLY0); +- } while (++rxdly < 32); +- +-done: +- return result; +-} +- +-static int msdc_get_card_status(struct mmc_host *mmc, struct msdc_host *host, u32 *status) +-{ +- struct mmc_command cmd; +- struct mmc_request mrq; +- u32 err; +- +- memset(&cmd, 0, sizeof(struct mmc_command)); +- cmd.opcode = MMC_SEND_STATUS; +- if (mmc->card) { +- cmd.arg = mmc->card->rca << 16; +- } else { +- ERR_MSG("cmd13 mmc card is null"); +- cmd.arg = host->app_cmd_arg; +- } +- cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; +- +- memset(&mrq, 0, sizeof(struct mmc_request)); +- mrq.cmd = &cmd; cmd.mrq = &mrq; +- cmd.data = NULL; +- +- err = msdc_do_command(host, &cmd, 1, CMD_TIMEOUT); +- +- if (status) +- *status = cmd.resp[0]; +- +- return err; +-} +- +-static int msdc_check_busy(struct mmc_host *mmc, struct msdc_host *host) +-{ +- u32 err = 0; +- u32 status = 0; +- +- do { +- err = msdc_get_card_status(mmc, host, &status); +- if (err) +- return err; +- /* need cmd12? */ +- ERR_MSG("cmd<13> resp<0x%x>", status); +- } while (R1_CURRENT_STATE(status) == 7); +- +- return err; +-} +- +-/* failed when msdc_do_request */ +-static int msdc_tune_request(struct mmc_host *mmc, struct mmc_request *mrq) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- struct mmc_data *data; +- //u32 base = host->base; +- int ret = 0, read; +- +- data = mrq->cmd->data; +- +- read = data->flags & MMC_DATA_READ ? 1 : 0; +- +- if (read) { +- if (data->error == -EIO) +- ret = msdc_tune_bread(mmc, mrq); +- } else { +- ret = msdc_check_busy(mmc, host); +- if (ret) { +- ERR_MSG("XXX cmd13 wait program done failed"); +- return ret; +- } +- /* CRC and TO */ +- /* Fix me: don't care card status? */ +- ret = msdc_tune_bwrite(mmc, mrq); +- } +- +- return ret; +-} +- +-/* ops.request */ +-static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- +- //=== for sdio profile === +-#if 0 /* --- by chhung */ +- u32 old_H32, old_L32, new_H32, new_L32; +- u32 ticks = 0, opcode = 0, sizes = 0, bRx = 0; +-#endif /* end of --- */ +- +- WARN_ON(host->mrq); +- +- /* start to process */ +- spin_lock(&host->lock); +-#if 0 /* --- by chhung */ +- if (sdio_pro_enable) { //=== for sdio profile === +- if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) +- GPT_GetCounter64(&old_L32, &old_H32); +- } +-#endif /* end of --- */ +- +- host->mrq = mrq; +- +- if (msdc_do_request(mmc, mrq)) { +- if (host->hw->flags & MSDC_REMOVABLE && ralink_soc == MT762X_SOC_MT7621AT && mrq->data && mrq->data->error) +- msdc_tune_request(mmc, mrq); +- } +- +- /* ==== when request done, check if app_cmd ==== */ +- if (mrq->cmd->opcode == MMC_APP_CMD) { +- host->app_cmd = 1; +- host->app_cmd_arg = mrq->cmd->arg; /* save the RCA */ +- } else { +- host->app_cmd = 0; +- //host->app_cmd_arg = 0; +- } +- +- host->mrq = NULL; +- +-#if 0 /* --- by chhung */ +- //=== for sdio profile === +- if (sdio_pro_enable) { +- if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) { +- GPT_GetCounter64(&new_L32, &new_H32); +- ticks = msdc_time_calc(old_L32, old_H32, new_L32, new_H32); +- +- opcode = mrq->cmd->opcode; +- if (mrq->cmd->data) { +- sizes = mrq->cmd->data->blocks * mrq->cmd->data->blksz; +- bRx = mrq->cmd->data->flags & MMC_DATA_READ ? 1 : 0; +- } else { +- bRx = mrq->cmd->arg & 0x80000000 ? 1 : 0; +- } +- +- if (!mrq->cmd->error) +- msdc_performance(opcode, sizes, bRx, ticks); +- } +- } +-#endif /* end of --- */ +- spin_unlock(&host->lock); +- +- mmc_request_done(mmc, mrq); +- +- return; +-} +- +-/* called by ops.set_ios */ +-static void msdc_set_buswidth(struct msdc_host *host, u32 width) +-{ +- u32 val = readl(host->base + SDC_CFG); +- +- val &= ~SDC_CFG_BUSWIDTH; +- +- switch (width) { +- default: +- case MMC_BUS_WIDTH_1: +- width = 1; +- val |= (MSDC_BUS_1BITS << 16); +- break; +- case MMC_BUS_WIDTH_4: +- val |= (MSDC_BUS_4BITS << 16); +- break; +- case MMC_BUS_WIDTH_8: +- val |= (MSDC_BUS_8BITS << 16); +- break; +- } +- +- writel(val, host->base + SDC_CFG); +- +- N_MSG(CFG, "Bus Width = %d", width); +-} +- +-/* ops.set_ios */ +-static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- u32 ddr = 0; +- +-#ifdef MT6575_SD_DEBUG +- static char *vdd[] = { +- "1.50v", "1.55v", "1.60v", "1.65v", "1.70v", "1.80v", "1.90v", +- "2.00v", "2.10v", "2.20v", "2.30v", "2.40v", "2.50v", "2.60v", +- "2.70v", "2.80v", "2.90v", "3.00v", "3.10v", "3.20v", "3.30v", +- "3.40v", "3.50v", "3.60v" +- }; +- static char *power_mode[] = { +- "OFF", "UP", "ON" +- }; +- static char *bus_mode[] = { +- "UNKNOWN", "OPENDRAIN", "PUSHPULL" +- }; +- static char *timing[] = { +- "LEGACY", "MMC_HS", "SD_HS" +- }; +- +- printk("SET_IOS: CLK(%dkHz), BUS(%s), BW(%u), PWR(%s), VDD(%s), TIMING(%s)", +- ios->clock / 1000, bus_mode[ios->bus_mode], +- (ios->bus_width == MMC_BUS_WIDTH_4) ? 4 : 1, +- power_mode[ios->power_mode], vdd[ios->vdd], timing[ios->timing]); +-#endif +- +- msdc_set_buswidth(host, ios->bus_width); +- +- /* Power control ??? */ +- switch (ios->power_mode) { +- case MMC_POWER_OFF: +- case MMC_POWER_UP: +- // msdc_set_power_mode(host, ios->power_mode); /* --- by chhung */ +- break; +- case MMC_POWER_ON: +- host->power_mode = MMC_POWER_ON; +- break; +- default: +- break; +- } +- +- /* Clock control */ +- if (host->mclk != ios->clock) { +- if (ios->clock > 25000000) { +- //if (!(host->hw->flags & MSDC_REMOVABLE)) { +- INIT_MSG("SD data latch edge<%d>", MSDC_SMPL_FALLING); +- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, +- MSDC_SMPL_FALLING); +- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, +- MSDC_SMPL_FALLING); +- //} /* for tuning debug */ +- } else { /* default value */ +- writel(0x00000000, host->base + MSDC_IOCON); +- // writel(0x00000000, host->base + MSDC_DAT_RDDLY0); +- +- // for MT7620 E2 and afterward +- writel(0x10101010, host->base + MSDC_DAT_RDDLY0); +- +- writel(0x00000000, host->base + MSDC_DAT_RDDLY1); +- // writel(0x00000000, host->base + MSDC_PAD_TUNE); +- +- // for MT7620 E2 and afterward +- writel(0x84101010, host->base + MSDC_PAD_TUNE); +- } +- msdc_set_mclk(host, ddr, ios->clock); +- } +-} +- +-/* ops.get_ro */ +-static int msdc_ops_get_ro(struct mmc_host *mmc) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- unsigned long flags; +- int ro = 0; +- +- if (host->hw->flags & MSDC_WP_PIN_EN) { /* set for card */ +- spin_lock_irqsave(&host->lock, flags); +- ro = (readl(host->base + MSDC_PS) >> 31); +- spin_unlock_irqrestore(&host->lock, flags); +- } +- return ro; +-} +- +-/* ops.get_cd */ +-static int msdc_ops_get_cd(struct mmc_host *mmc) +-{ +- struct msdc_host *host = mmc_priv(mmc); +- unsigned long flags; +- int present = 1; +- +- /* for sdio, MSDC_REMOVABLE not set, always return 1 */ +- if (!(host->hw->flags & MSDC_REMOVABLE)) { +- /* For sdio, read H/W always get<1>, but may timeout some times */ +-#if 1 +- host->card_inserted = 1; +- return 1; +-#else +- host->card_inserted = (host->pm_state.event == PM_EVENT_USER_RESUME) ? 1 : 0; +- INIT_MSG("sdio ops_get_cd<%d>", host->card_inserted); +- return host->card_inserted; +-#endif +- } +- +- /* MSDC_CD_PIN_EN set for card */ +- if (host->hw->flags & MSDC_CD_PIN_EN) { +- spin_lock_irqsave(&host->lock, flags); +-#if 0 +- present = host->card_inserted; /* why not read from H/W: Fix me*/ +-#else +- // CD +- present = readl(host->base + MSDC_PS) & MSDC_PS_CDSTS; +- if (cd_active_low) +- present = present ? 0 : 1; +- else +- present = present ? 1 : 0; +- host->card_inserted = present; +-#endif +- spin_unlock_irqrestore(&host->lock, flags); +- } else { +- present = 0; /* TODO? Check DAT3 pins for card detection */ +- } +- +- INIT_MSG("ops_get_cd return<%d>", present); +- return present; +-} +- +-static struct mmc_host_ops mt_msdc_ops = { +- .request = msdc_ops_request, +- .set_ios = msdc_ops_set_ios, +- .get_ro = msdc_ops_get_ro, +- .get_cd = msdc_ops_get_cd, +-}; +- +-/*--------------------------------------------------------------------------*/ +-/* interrupt handler */ +-/*--------------------------------------------------------------------------*/ +-static irqreturn_t msdc_irq(int irq, void *dev_id) +-{ +- struct msdc_host *host = (struct msdc_host *)dev_id; +- struct mmc_data *data = host->data; +- struct mmc_command *cmd = host->cmd; +- +- u32 cmdsts = MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | MSDC_INT_CMDRDY | +- MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | MSDC_INT_ACMDRDY | +- MSDC_INT_ACMD19_DONE; +- u32 datsts = MSDC_INT_DATCRCERR | MSDC_INT_DATTMO; +- +- u32 intsts = readl(host->base + MSDC_INT); +- u32 inten = readl(host->base + MSDC_INTEN); inten &= intsts; +- +- writel(intsts, host->base + MSDC_INT); /* clear interrupts */ +- /* MSG will cause fatal error */ +- +- /* card change interrupt */ +- if (intsts & MSDC_INT_CDSC) { +- if (host->mmc->caps & MMC_CAP_NEEDS_POLL) +- return IRQ_HANDLED; +- IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts); +- schedule_delayed_work(&host->card_delaywork, HZ); +- /* tuning when plug card ? */ +- } +- +- /* sdio interrupt */ +- if (intsts & MSDC_INT_SDIOIRQ) { +- IRQ_MSG("XXX MSDC_INT_SDIOIRQ"); /* seems not sdio irq */ +- //mmc_signal_sdio_irq(host->mmc); +- } +- +- /* transfer complete interrupt */ +- if (data != NULL) { +- if (inten & MSDC_INT_XFER_COMPL) { +- data->bytes_xfered = host->xfer_size; +- complete(&host->xfer_done); +- } +- +- if (intsts & datsts) { +- /* do basic reset, or stop command will sdc_busy */ +- msdc_reset_hw(host); +- msdc_clr_fifo(host); +- msdc_clr_int(); +- +- if (intsts & MSDC_INT_DATTMO) { +- IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode); +- data->error = -ETIMEDOUT; +- } else if (intsts & MSDC_INT_DATCRCERR) { +- IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, readl(host->base + SDC_DCRC_STS)); +- data->error = -EIO; +- } +- +- //if(readl(MSDC_INTEN) & MSDC_INT_XFER_COMPL) { +- complete(&host->xfer_done); /* Read CRC come fast, XFER_COMPL not enabled */ +- } +- } +- +- /* command interrupts */ +- if ((cmd != NULL) && (intsts & cmdsts)) { +- if ((intsts & MSDC_INT_CMDRDY) || (intsts & MSDC_INT_ACMDRDY) || +- (intsts & MSDC_INT_ACMD19_DONE)) { +- u32 *rsp = &cmd->resp[0]; +- +- switch (host->cmd_rsp) { +- case RESP_NONE: +- break; +- case RESP_R2: +- *rsp++ = readl(host->base + SDC_RESP3); +- *rsp++ = readl(host->base + SDC_RESP2); +- *rsp++ = readl(host->base + SDC_RESP1); +- *rsp++ = readl(host->base + SDC_RESP0); +- break; +- default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ +- if ((intsts & MSDC_INT_ACMDRDY) || (intsts & MSDC_INT_ACMD19_DONE)) +- *rsp = readl(host->base + SDC_ACMD_RESP); +- else +- *rsp = readl(host->base + SDC_RESP0); +- break; +- } +- } else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) { +- if (intsts & MSDC_INT_ACMDCRCERR) +- IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR", cmd->opcode); +- else +- IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR", cmd->opcode); +- cmd->error = -EIO; +- } else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) { +- if (intsts & MSDC_INT_ACMDTMO) +- IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO", cmd->opcode); +- else +- IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO", cmd->opcode); +- cmd->error = -ETIMEDOUT; +- msdc_reset_hw(host); +- msdc_clr_fifo(host); +- msdc_clr_int(); +- } +- complete(&host->cmd_done); +- } +- +- /* mmc irq interrupts */ +- if (intsts & MSDC_INT_MMCIRQ) +- printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n", +- host->id, readl(host->base + SDC_CSTS)); +- +-#ifdef MT6575_SD_DEBUG +- { +-/* msdc_int_reg *int_reg = (msdc_int_reg*)&intsts;*/ +- N_MSG(INT, "IRQ_EVT(0x%x): MMCIRQ(%d) CDSC(%d), ACRDY(%d), ACTMO(%d), ACCRE(%d) AC19DN(%d)", +- intsts, +- int_reg->mmcirq, +- int_reg->cdsc, +- int_reg->atocmdrdy, +- int_reg->atocmdtmo, +- int_reg->atocmdcrc, +- int_reg->atocmd19done); +- N_MSG(INT, "IRQ_EVT(0x%x): SDIO(%d) CMDRDY(%d), CMDTMO(%d), RSPCRC(%d), CSTA(%d)", +- intsts, +- int_reg->sdioirq, +- int_reg->cmdrdy, +- int_reg->cmdtmo, +- int_reg->rspcrc, +- int_reg->csta); +- N_MSG(INT, "IRQ_EVT(0x%x): XFCMP(%d) DXDONE(%d), DATTMO(%d), DATCRC(%d), DMAEMP(%d)", +- intsts, +- int_reg->xfercomp, +- int_reg->dxferdone, +- int_reg->dattmo, +- int_reg->datcrc, +- int_reg->dmaqempty); +- } +-#endif +- +- return IRQ_HANDLED; +-} +- +-/*--------------------------------------------------------------------------*/ +-/* platform_driver members */ +-/*--------------------------------------------------------------------------*/ +-/* called by msdc_drv_probe/remove */ +-static void msdc_enable_cd_irq(struct msdc_host *host, int enable) +-{ +- struct msdc_hw *hw = host->hw; +- +- /* for sdio, not set */ +- if ((hw->flags & MSDC_CD_PIN_EN) == 0) { +- /* Pull down card detection pin since it is not avaiable */ +- /* +- if (hw->config_gpio_pin) +- hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); +- */ +- sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); +- sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); +- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); +- return; +- } +- +- N_MSG(CFG, "CD IRQ Enable(%d)", enable); +- +- if (enable) { +- /* card detection circuit relies on the core power so that the core power +- * shouldn't be turned off. Here adds a reference count to keep +- * the core power alive. +- */ +- //msdc_vcore_on(host); //did in msdc_init_hw() +- +- if (hw->config_gpio_pin) /* NULL */ +- hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP); +- +- sdr_set_field(host->base + MSDC_PS, MSDC_PS_CDDEBOUNCE, +- DEFAULT_DEBOUNCE); +- sdr_set_bits(host->base + MSDC_PS, MSDC_PS_CDEN); +- sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); +- +- /* not in document! Fix me */ +- sdr_set_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); +- } else { +- if (hw->config_gpio_pin) /* NULL */ +- hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); +- +- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); +- sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); +- sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); +- +- /* Here decreases a reference count to core power since card +- * detection circuit is shutdown. +- */ +- //msdc_vcore_off(host); +- } +-} +- +-/* called by msdc_drv_probe */ +-static void msdc_init_hw(struct msdc_host *host) +-{ +- +- /* Power on */ +-#if 0 /* --- by chhung */ +- msdc_vcore_on(host); +- msdc_pin_reset(host, MSDC_PIN_PULL_UP); +- msdc_select_clksrc(host, hw->clk_src); +- enable_clock(PERI_MSDC0_PDN + host->id, "SD"); +- msdc_vdd_on(host); +-#endif /* end of --- */ +- /* Configure to MMC/SD mode */ +- sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC); +- +- /* Reset */ +- msdc_reset_hw(host); +- msdc_clr_fifo(host); +- +- /* Disable card detection */ +- sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); +- +- /* Disable and clear all interrupts */ +- sdr_clr_bits(host->base + MSDC_INTEN, readl(host->base + MSDC_INTEN)); +- writel(readl(host->base + MSDC_INT), host->base + MSDC_INT); +- +-#if 1 +- /* reset tuning parameter */ +- writel(0x00090000, host->base + MSDC_PAD_CTL0); +- writel(0x000A0000, host->base + MSDC_PAD_CTL1); +- writel(0x000A0000, host->base + MSDC_PAD_CTL2); +- // writel( 0x00000000, host->base + MSDC_PAD_TUNE); +- +- // for MT7620 E2 and afterward +- writel(0x84101010, host->base + MSDC_PAD_TUNE); +- +- // writel(0x00000000, host->base + MSDC_DAT_RDDLY0); +- +- // for MT7620 E2 and afterward +- writel(0x10101010, host->base + MSDC_DAT_RDDLY0); +- +- writel(0x00000000, host->base + MSDC_DAT_RDDLY1); +- writel(0x00000000, host->base + MSDC_IOCON); +-#if 0 // use MT7620 default value: 0x403c004f +- /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/ +- writel(0x003C000F, host->base + MSDC_PATCH_BIT0); +-#endif +- +- if (readl(host->base + MSDC_ECO_VER) >= 4) { +- if (host->id == 1) { +- sdr_set_field(host->base + MSDC_PATCH_BIT1, +- MSDC_PATCH_BIT1_WRDAT_CRCS, 1); +- sdr_set_field(host->base + MSDC_PATCH_BIT1, +- MSDC_PATCH_BIT1_CMD_RSP, 1); +- +- /* internal clock: latch read data */ +- sdr_set_bits(host->base + MSDC_PATCH_BIT0, +- MSDC_PATCH_BIT_CKGEN_CK); +- } +- } +-#endif +- +- /* for safety, should clear SDC_CFG.SDIO_INT_DET_EN & set SDC_CFG.SDIO in +- pre-loader,uboot,kernel drivers. and SDC_CFG.SDIO_INT_DET_EN will be only +- set when kernel driver wants to use SDIO bus interrupt */ +- /* Configure to enable SDIO mode. it's must otherwise sdio cmd5 failed */ +- sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO); +- +- /* disable detect SDIO device interupt function */ +- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE); +- +- /* eneable SMT for glitch filter */ +- sdr_set_bits(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT); +- sdr_set_bits(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT); +- sdr_set_bits(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT); +- +-#if 1 +- /* set clk, cmd, dat pad driving */ +- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 4); +- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 4); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 4); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 4); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 4); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 4); +-#else +- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0); +- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0); +-#endif +- +- /* set sampling edge */ +- +- /* write crc timeout detection */ +- sdr_set_field(host->base + MSDC_PATCH_BIT0, 1 << 30, 1); +- +- /* Configure to default data timeout */ +- sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC); +- +- msdc_set_buswidth(host, MMC_BUS_WIDTH_1); +- +- N_MSG(FUC, "init hardware done!"); +-} +- +-/* called by msdc_drv_remove */ +-static void msdc_deinit_hw(struct msdc_host *host) +-{ +- /* Disable and clear all interrupts */ +- sdr_clr_bits(host->base + MSDC_INTEN, readl(host->base + MSDC_INTEN)); +- writel(readl(host->base + MSDC_INT), host->base + MSDC_INT); +- +- /* Disable card detection */ +- msdc_enable_cd_irq(host, 0); +- // msdc_set_power_mode(host, MMC_POWER_OFF); /* make sure power down */ /* --- by chhung */ +-} +- +-/* init gpd and bd list in msdc_drv_probe */ +-static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma) +-{ +- struct gpd *gpd = dma->gpd; +- struct bd *bd = dma->bd; +- int i; +- +- /* we just support one gpd, but gpd->next must be set for desc +- * DMA. That's why we alloc 2 gpd structurs. +- */ +- +- memset(gpd, 0, sizeof(struct gpd) * 2); +- +- gpd->bdp = 1; /* hwo, cs, bd pointer */ +- gpd->ptr = (void *)dma->bd_addr; /* physical address */ +- gpd->next = (void *)((u32)dma->gpd_addr + sizeof(struct gpd)); +- +- memset(bd, 0, sizeof(struct bd) * MAX_BD_NUM); +- for (i = 0; i < (MAX_BD_NUM - 1); i++) +- bd[i].next = (void *)(dma->bd_addr + sizeof(*bd) * (i + 1)); +-} +- +-static int msdc_drv_probe(struct platform_device *pdev) +-{ +- struct resource *res; +- __iomem void *base; +- struct mmc_host *mmc; +- struct msdc_host *host; +- struct msdc_hw *hw; +- int ret; +- +- hw = &msdc0_hw; +- +- if (of_property_read_bool(pdev->dev.of_node, "mtk,wp-en")) +- msdc0_hw.flags |= MSDC_WP_PIN_EN; +- +- /* Allocate MMC host for this device */ +- mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); +- if (!mmc) +- return -ENOMEM; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- base = devm_ioremap_resource(&pdev->dev, res); +- if (IS_ERR(base)) { +- ret = PTR_ERR(base); +- goto host_free; +- } +- +- /* Set host parameters to mmc */ +- mmc->ops = &mt_msdc_ops; +- mmc->f_min = HOST_MIN_MCLK; +- mmc->f_max = HOST_MAX_MCLK; +- mmc->ocr_avail = MSDC_OCR_AVAIL; +- +- mmc->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; +- +- //TODO: read this as bus-width from dt (via mmc_of_parse) +- mmc->caps |= MMC_CAP_4_BIT_DATA; +- +- cd_active_low = !of_property_read_bool(pdev->dev.of_node, "mediatek,cd-high"); +- +- if (of_property_read_bool(pdev->dev.of_node, "mediatek,cd-poll")) +- mmc->caps |= MMC_CAP_NEEDS_POLL; +- +- /* MMC core transfer sizes tunable parameters */ +- mmc->max_segs = MAX_HW_SGMTS; +- +- mmc->max_seg_size = MAX_SGMT_SZ; +- mmc->max_blk_size = HOST_MAX_BLKSZ; +- mmc->max_req_size = MAX_REQ_SZ; +- mmc->max_blk_count = mmc->max_req_size; +- +- host = mmc_priv(mmc); +- host->hw = hw; +- host->mmc = mmc; +- host->id = pdev->id; +- if (host->id < 0 || host->id >= 4) +- host->id = 0; +- host->error = 0; +- +- host->irq = platform_get_irq(pdev, 0); +- if (host->irq < 0) { +- ret = -EINVAL; +- goto host_free; +- } +- +- host->base = base; +- host->mclk = 0; /* mclk: the request clock of mmc sub-system */ +- host->hclk = hclks[hw->clk_src]; /* hclk: clock of clock source to msdc controller */ +- host->sclk = 0; /* sclk: the really clock after divition */ +- host->pm_state = PMSG_RESUME; +- host->suspend = 0; +- host->core_clkon = 0; +- host->card_clkon = 0; +- host->core_power = 0; +- host->power_mode = MMC_POWER_OFF; +-// host->card_inserted = hw->flags & MSDC_REMOVABLE ? 0 : 1; +- host->timeout_ns = 0; +- host->timeout_clks = DEFAULT_DTOC * 65536; +- +- host->mrq = NULL; +- //init_MUTEX(&host->sem); /* we don't need to support multiple threads access */ +- +- mmc_dev(mmc)->dma_mask = NULL; +- +- /* using dma_alloc_coherent*/ /* todo: using 1, for all 4 slots */ +- host->dma.gpd = dma_alloc_coherent(&pdev->dev, +- MAX_GPD_NUM * sizeof(struct gpd), +- &host->dma.gpd_addr, GFP_KERNEL); +- host->dma.bd = dma_alloc_coherent(&pdev->dev, +- MAX_BD_NUM * sizeof(struct bd), +- &host->dma.bd_addr, GFP_KERNEL); +- if (!host->dma.gpd || !host->dma.bd) { +- ret = -ENOMEM; +- goto release_mem; +- } +- msdc_init_gpd_bd(host, &host->dma); +- +- INIT_DELAYED_WORK(&host->card_delaywork, msdc_tasklet_card); +- spin_lock_init(&host->lock); +- msdc_init_hw(host); +- +- /* TODO check weather flags 0 is correct, the mtk-sd driver uses +- * IRQF_TRIGGER_LOW | IRQF_ONESHOT for flags +- * +- * for flags 0 the trigger polarity is determined by the +- * device tree, but not the oneshot flag, but maybe it is also +- * not needed because the soc could be oneshot safe. +- */ +- ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, 0, pdev->name, +- host); +- if (ret) +- goto release; +- +- platform_set_drvdata(pdev, mmc); +- +- ret = mmc_add_host(mmc); +- if (ret) +- goto release; +- +- /* Config card detection pin and enable interrupts */ +- if (hw->flags & MSDC_CD_PIN_EN) { /* set for card */ +- msdc_enable_cd_irq(host, 1); +- } else { +- msdc_enable_cd_irq(host, 0); +- } +- +- return 0; +- +-release: +- platform_set_drvdata(pdev, NULL); +- msdc_deinit_hw(host); +- cancel_delayed_work_sync(&host->card_delaywork); +- +-release_mem: +- if (host->dma.gpd) +- dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd), +- host->dma.gpd, host->dma.gpd_addr); +- if (host->dma.bd) +- dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd), +- host->dma.bd, host->dma.bd_addr); +-host_free: +- mmc_free_host(mmc); +- +- return ret; +-} +- +-/* 4 device share one driver, using "drvdata" to show difference */ +-static int msdc_drv_remove(struct platform_device *pdev) +-{ +- struct mmc_host *mmc; +- struct msdc_host *host; +- +- mmc = platform_get_drvdata(pdev); +- BUG_ON(!mmc); +- +- host = mmc_priv(mmc); +- BUG_ON(!host); +- +- ERR_MSG("removed !!!"); +- +- platform_set_drvdata(pdev, NULL); +- mmc_remove_host(host->mmc); +- msdc_deinit_hw(host); +- +- cancel_delayed_work_sync(&host->card_delaywork); +- +- dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd), +- host->dma.gpd, host->dma.gpd_addr); +- dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd), +- host->dma.bd, host->dma.bd_addr); +- +- mmc_free_host(host->mmc); +- +- return 0; +-} +- +-/* Fix me: Power Flow */ +-#ifdef CONFIG_PM +- +-static void msdc_drv_pm(struct platform_device *pdev, pm_message_t state) +-{ +- struct mmc_host *mmc = platform_get_drvdata(pdev); +- if (mmc) { +- struct msdc_host *host = mmc_priv(mmc); +- msdc_pm(state, (void *)host); +- } +-} +- +-static int msdc_drv_suspend(struct platform_device *pdev, pm_message_t state) +-{ +- if (state.event == PM_EVENT_SUSPEND) +- msdc_drv_pm(pdev, state); +- return 0; +-} +- +-static int msdc_drv_resume(struct platform_device *pdev) +-{ +- struct pm_message state; +- +- state.event = PM_EVENT_RESUME; +- msdc_drv_pm(pdev, state); +- return 0; +-} +-#endif +- +-static const struct of_device_id mt7620_sdhci_match[] = { +- { .compatible = "ralink,mt7620-sdhci" }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, mt7620_sdhci_match); +- +-static struct platform_driver mt_msdc_driver = { +- .probe = msdc_drv_probe, +- .remove = msdc_drv_remove, +-#ifdef CONFIG_PM +- .suspend = msdc_drv_suspend, +- .resume = msdc_drv_resume, +-#endif +- .driver = { +- .name = DRV_NAME, +- .of_match_table = mt7620_sdhci_match, +- }, +-}; +- +-/*--------------------------------------------------------------------------*/ +-/* module init/exit */ +-/*--------------------------------------------------------------------------*/ +-static int __init mt_msdc_init(void) +-{ +- int ret; +- u32 reg; +- +- // Set the pins for sdxc to sdxc mode +- //FIXME: this should be done by pinctl and not by the sd driver +- reg = readl((void __iomem *)(RALINK_SYSCTL_BASE + 0x60)) & ~(0x3 << 18); +- writel(reg, (void __iomem *)(RALINK_SYSCTL_BASE + 0x60)); +- +- ret = platform_driver_register(&mt_msdc_driver); +- if (ret) { +- printk(KERN_ERR DRV_NAME ": Can't register driver"); +- return ret; +- } +- +-#if defined(MT6575_SD_DEBUG) +- msdc_debug_proc_init(); +-#endif +- return 0; +-} +- +-static void __exit mt_msdc_exit(void) +-{ +- platform_driver_unregister(&mt_msdc_driver); +-} +- +-module_init(mt_msdc_init); +-module_exit(mt_msdc_exit); +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("MediaTek MT6575 SD/MMC Card Driver"); +-MODULE_AUTHOR("Infinity Chen "); +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index 8c577f0ae2bb3..b370144682ed5 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -1782,7 +1782,7 @@ static void lateeoi_ack_dynirq(struct irq_data *data) + + if (VALID_EVTCHN(evtchn)) { + do_mask(info, EVT_MASK_REASON_EOI_PENDING); +- event_handler_exit(info); ++ ack_dynirq(data); + } + } + +@@ -1793,7 +1793,7 @@ static void lateeoi_mask_ack_dynirq(struct irq_data *data) + + if (VALID_EVTCHN(evtchn)) { + do_mask(info, EVT_MASK_REASON_EXPLICIT); +- event_handler_exit(info); ++ ack_dynirq(data); + } + } + +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index 22cd68bd8c9b0..3cc2237e58967 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1000,11 +1000,13 @@ void gfs2_freeze_func(struct work_struct *work) + static int gfs2_freeze(struct super_block *sb) + { + struct gfs2_sbd *sdp = sb->s_fs_info; +- int error = 0; ++ int error; + + mutex_lock(&sdp->sd_freeze_mutex); +- if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) ++ if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) { ++ error = -EBUSY; + goto out; ++ } + + if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + error = -EINVAL; +@@ -1046,10 +1048,10 @@ static int gfs2_unfreeze(struct super_block *sb) + struct gfs2_sbd *sdp = sb->s_fs_info; + + mutex_lock(&sdp->sd_freeze_mutex); +- if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || ++ if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || + !gfs2_holder_initialized(&sdp->sd_freeze_gh)) { + mutex_unlock(&sdp->sd_freeze_mutex); +- return 0; ++ return -EINVAL; + } + + gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); +diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c +index 10d8f95eb7712..fba56cd958961 100644 +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -1195,6 +1195,8 @@ static int translate_compat_table(struct net *net, + if (!newinfo) + goto out_unlock; + ++ memset(newinfo->entries, 0, size); ++ + newinfo->number = compatr->num_entries; + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { + newinfo->hook_entry[i] = compatr->hook_entry[i]; +diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c +index e77872c93c206..730a40dc829aa 100644 +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -1433,6 +1433,8 @@ translate_compat_table(struct net *net, + if (!newinfo) + goto out_unlock; + ++ memset(newinfo->entries, 0, size); ++ + newinfo->number = compatr->num_entries; + for (i = 0; i < NF_INET_NUMHOOKS; i++) { + newinfo->hook_entry[i] = compatr->hook_entry[i]; +diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c +index daf2e9e9193d1..dd0c1073dc8ee 100644 +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -1448,6 +1448,8 @@ translate_compat_table(struct net *net, + if (!newinfo) + goto out_unlock; + ++ memset(newinfo->entries, 0, size); ++ + newinfo->number = compatr->num_entries; + for (i = 0; i < NF_INET_NUMHOOKS; i++) { + newinfo->hook_entry[i] = compatr->hook_entry[i]; +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index c9fe35118b33a..5dd6f6ce92e6b 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -738,7 +738,7 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, + { + const struct xt_match *match = m->u.kernel.match; + struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m; +- int pad, off = xt_compat_match_offset(match); ++ int off = xt_compat_match_offset(match); + u_int16_t msize = cm->u.user.match_size; + char name[sizeof(m->u.user.name)]; + +@@ -748,9 +748,6 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, + match->compat_from_user(m->data, cm->data); + else + memcpy(m->data, cm->data, msize - sizeof(*cm)); +- pad = XT_ALIGN(match->matchsize) - match->matchsize; +- if (pad > 0) +- memset(m->data + match->matchsize, 0, pad); + + msize += off; + m->u.user.match_size = msize; +@@ -1121,7 +1118,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, + { + const struct xt_target *target = t->u.kernel.target; + struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t; +- int pad, off = xt_compat_target_offset(target); ++ int off = xt_compat_target_offset(target); + u_int16_t tsize = ct->u.user.target_size; + char name[sizeof(t->u.user.name)]; + +@@ -1131,9 +1128,6 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, + target->compat_from_user(t->data, ct->data); + else + memcpy(t->data, ct->data, tsize - sizeof(*ct)); +- pad = XT_ALIGN(target->targetsize) - target->targetsize; +- if (pad > 0) +- memset(t->data + target->targetsize, 0, pad); + + tsize += off; + t->u.user.target_size = tsize; +diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c +index d3d3601f41cc6..769d11575a7b3 100644 +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -88,8 +88,7 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) + if (!strncmp(filename, "/system/lib/", 12)) { + char *ndk, *app; + const char *arch; +- size_t ndk_length; +- size_t app_length; ++ int ndk_length, app_length; + + ndk = getenv("NDK_ROOT"); + app = getenv("APP_PLATFORM"); +@@ -117,8 +116,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) + if (new_length > PATH_MAX) + return false; + snprintf(newfilename, new_length, +- "%s/platforms/%s/arch-%s/usr/lib/%s", +- ndk, app, arch, libname); ++ "%.*s/platforms/%.*s/arch-%s/usr/lib/%s", ++ ndk_length, ndk, app_length, app, arch, libname); + + return true; + }