Re: [PATCH 1/3] mmc: sdhci-esdhc-imx: get rid of the uses of cpu_is_mx()
On Sun, Jul 03, 2011 at 04:30:49PM +0800, Shawn Guo wrote: The patch removes all the uses of cpu_is_mx(). Instead, it utilizes platform_device_id to distinguish the esdhc differences among SoCs. Signed-off-by: Shawn Guo shawn@linaro.org Cc: Wolfram Sang w.s...@pengutronix.de Cc: Chris Ball c...@laptop.org Same comments apply to this patch as on the others. Minor implementation detail comments that I won't bother repeating, but in general I like the approach. g. --- arch/arm/mach-imx/clock-imx25.c|4 +- arch/arm/mach-imx/clock-imx35.c|6 +- arch/arm/mach-mx5/clock-mx51-mx53.c| 16 arch/arm/mach-mx5/mx51_efika.c |4 +- .../plat-mxc/devices/platform-sdhci-esdhc-imx.c| 17 arch/arm/plat-mxc/include/mach/devices-common.h|1 + drivers/mmc/host/sdhci-esdhc-imx.c | 45 ++-- 7 files changed, 66 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c index a65838f..2955afa 100644 --- a/arch/arm/mach-imx/clock-imx25.c +++ b/arch/arm/mach-imx/clock-imx25.c @@ -300,8 +300,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(imx2-wdt.0, NULL, wdt_clk) _REGISTER_CLOCK(imx-ssi.0, NULL, ssi1_clk) _REGISTER_CLOCK(imx-ssi.1, NULL, ssi2_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx25.0, NULL, esdhc1_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx25.1, NULL, esdhc2_clk) _REGISTER_CLOCK(mx2-camera.0, NULL, csi_clk) _REGISTER_CLOCK(NULL, audmux, audmux_clk) _REGISTER_CLOCK(flexcan.0, NULL, can1_clk) diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c index 5a4cc1e..2f80f14 100644 --- a/arch/arm/mach-imx/clock-imx35.c +++ b/arch/arm/mach-imx/clock-imx35.c @@ -458,9 +458,9 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(imx-epit.0, NULL, epit1_clk) _REGISTER_CLOCK(imx-epit.1, NULL, epit2_clk) _REGISTER_CLOCK(NULL, esai, esai_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.2, NULL, esdhc3_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx35.0, NULL, esdhc1_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx35.1, NULL, esdhc2_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx35.2, NULL, esdhc3_clk) _REGISTER_CLOCK(fec.0, NULL, fec_clk) _REGISTER_CLOCK(NULL, gpio, gpio1_clk) _REGISTER_CLOCK(NULL, gpio, gpio2_clk) diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 699b0d2..fd60e2c 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -1453,10 +1453,10 @@ static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK(imx51-ecspi.0, NULL, ecspi1_clk) _REGISTER_CLOCK(imx51-ecspi.1, NULL, ecspi2_clk) _REGISTER_CLOCK(imx51-cspi.0, NULL, cspi_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.2, NULL, esdhc3_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.3, NULL, esdhc4_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx51.0, NULL, esdhc1_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx51.1, NULL, esdhc2_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx51.2, NULL, esdhc3_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx51.3, NULL, esdhc4_clk) _REGISTER_CLOCK(NULL, cpu_clk, cpu_clk) _REGISTER_CLOCK(NULL, iim_clk, iim_clk) _REGISTER_CLOCK(imx2-wdt.0, NULL, dummy_clk) @@ -1480,10 +1480,10 @@ static struct clk_lookup mx53_lookups[] = { _REGISTER_CLOCK(imx-i2c.0, NULL, i2c1_clk) _REGISTER_CLOCK(imx-i2c.1, NULL, i2c2_clk) _REGISTER_CLOCK(imx-i2c.2, NULL, i2c3_mx53_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_mx53_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.2, NULL, esdhc3_mx53_clk) - _REGISTER_CLOCK(sdhci-esdhc-imx.3, NULL, esdhc4_mx53_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx53.0, NULL, esdhc1_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx53.1, NULL, esdhc2_mx53_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx53.2, NULL, esdhc3_mx53_clk) + _REGISTER_CLOCK(sdhci-esdhc-imx53.3, NULL, esdhc4_mx53_clk) _REGISTER_CLOCK(imx53-ecspi.0, NULL, ecspi1_clk) _REGISTER_CLOCK(imx53-ecspi.1, NULL, ecspi2_clk) _REGISTER_CLOCK(imx53-cspi.0, NULL, cspi_clk) diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c index 56739c2..4435e03 100644 --- a/arch/arm/mach-mx5/mx51_efika.c +++ b/arch/arm/mach-mx5/mx51_efika.c @@ -260,8 +260,8 @@ static struct regulator_consumer_supply vvideo_consumers[] = { }; static struct
Re: [PATCH 2/3] mmc: sdhci-pltfm: dt device does not pass parent to sdhci_alloc_host
On Sun, Jul 03, 2011 at 04:30:50PM +0800, Shawn Guo wrote: Neither platform based nor dt based device needs to pass the parent to sdhci_alloc_host. There is no difference between platform and dt on this point. The patch makes the change to pass device itself than its parent to sdhci_alloc_host for dt case too. Otherwise the probe function of sdhci based drivers which is shared between platform and dt will fail on dt case. Signed-off-by: Shawn Guo shawn@linaro.org Cc: Chris Ball c...@laptop.org Cc: Grant Likely grant.lik...@secretlab.ca Acked-by: Grant Likely grant.lik...@secretlab.ca --- drivers/mmc/host/sdhci-pltfm.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 71c0ce1..6414efe 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -85,6 +85,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, { struct sdhci_host *host; struct sdhci_pltfm_host *pltfm_host; + struct device_node *np = pdev-dev.of_node; struct resource *iomem; int ret; @@ -98,7 +99,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, dev_err(pdev-dev, Invalid iomem size!\n); /* Some PCI-based MFD need the parent here */ - if (pdev-dev.parent != platform_bus) + if (pdev-dev.parent != platform_bus !np) host = sdhci_alloc_host(pdev-dev.parent, sizeof(*pltfm_host)); else host = sdhci_alloc_host(pdev-dev, sizeof(*pltfm_host)); -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] mmc: sdhci-esdhc-imx: add device tree probe support
On Sun, Jul 03, 2011 at 04:30:51PM +0800, Shawn Guo wrote: The patch adds device tree probe support for sdhci-esdhc-imx driver. Signed-off-by: Shawn Guo shawn@linaro.org Cc: Wolfram Sang w.s...@pengutronix.de Cc: Chris Ball c...@laptop.org Cc: Grant Likely grant.lik...@secretlab.ca --- .../devicetree/bindings/mmc/fsl-imx-esdhc.txt | 40 drivers/mmc/host/sdhci-esdhc-imx.c | 99 +++- 2 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt new file mode 100644 index 000..e182e7c --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -0,0 +1,40 @@ +* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX + +The Enhanced Secure Digital Host Controller on Freescale i.MX family +provides an interface for MMC, SD, and SDIO types of memory cards. + +Required properties: +- compatible : Should be fsl,chip-esdhc +- reg : Should contain eSDHC registers location and length +- interrupts : Should contain eSDHC interrupt +- cd-type : String, card detection (CD) method. Supported values are: Similar to previous comments, use the fsl, prefix to this property name. +none : No CD +controller : Uses eSDHC controller internal CD signal +gpio : Uses GPIO pin for CD I would say the presence of a cd-gpios property would implicitly mean gpio is to be used for the CD pin. +permanent : No CD because card is permanently wired to host +- wp-type : String, write protection (WP) method. Supported values are: +none : No WP +controller : Uses eSDHC controller internal WP signal +gpio : Uses GPIO pin for WP Ditto comments here. +- gpios : Should specify GPIOs in this order: CD GPIO, WP GPIO, if + properties cd-type and wp-type are gpio. The gpios binding has been extended to allow named gpios now. You can uses something like cd-gpios and wp-gpios. + +Examples: + +esdhc@70004000 { + compatible = fsl,imx51-esdhc; + reg = 0x70004000 0x4000; + interrupts = 1; + cd-type = controller; + wp-type = controller; +}; + +esdhc@70008000 { + compatible = fsl,imx51-esdhc; + reg = 0x70008000 0x4000; + interrupts = 2; + cd-type = gpio; + wp-type = gpio; + gpios = gpio0 6 0, /* CD, GPIO1_6 */ + gpio0 5 0; /* WP, GPIO1_5 */ +}; diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 705d670..57793e3 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -20,6 +20,9 @@ #include linux/mmc/host.h #include linux/mmc/mmc.h #include linux/mmc/sdio.h +#include linux/of.h +#include linux/of_device.h +#include linux/of_gpio.h #include mach/esdhc.h #include sdhci-pltfm.h #include sdhci-esdhc.h @@ -78,6 +81,14 @@ static struct platform_device_id imx_esdhc_devtype[] = { }; MODULE_DEVICE_TABLE(platform, imx_esdhc_devtype); +static const struct of_device_id imx_esdhc_dt_ids[] = { + { .compatible = fsl,imx25-esdhc, .data = imx_esdhc_devtype[IMX25_ESDHC], }, + { .compatible = fsl,imx35-esdhc, .data = imx_esdhc_devtype[IMX35_ESDHC], }, + { .compatible = fsl,imx51-esdhc, .data = imx_esdhc_devtype[IMX51_ESDHC], }, + { .compatible = fsl,imx53-esdhc, .data = imx_esdhc_devtype[IMX53_ESDHC], }, + { /* sentinel */ }, +}; + static unsigned int esdhc_pltfm_get_max_blk_size(struct sdhci_host *host) { /* Force 2048 bytes, which is the maximum supported size in SDHCI. */ @@ -290,24 +301,93 @@ static irqreturn_t cd_irq(int irq, void *data) return IRQ_HANDLED; }; +#ifdef CONFIG_OF +static int __devinit sdhci_esdhc_imx_probe_dt(struct platform_device *pdev) +{ + const struct of_device_id *of_id = + of_match_device(imx_esdhc_dt_ids, pdev-dev); + struct device_node *np = pdev-dev.of_node; + struct esdhc_platform_data *boarddata; + int err, i; + const char *cd, *cd_types[] = { + [ESDHC_CD_NONE] = none, + [ESDHC_CD_CONTROLLER] = controller, + [ESDHC_CD_GPIO] = gpio, + [ESDHC_CD_PERMANENT]= permanent, + }; + const char *wp, *wp_types[] = { + [ESDHC_WP_NONE] = none, + [ESDHC_WP_CONTROLLER] = controller, + [ESDHC_WP_GPIO] = gpio, + }; + + if (!np) + return -ENODEV; + + boarddata = kzalloc(sizeof(*boarddata), GFP_KERNEL); + if (!boarddata) + return -ENOMEM; + pdev-dev.platform_data = boarddata; + + err = of_property_read_string(np, cd-type, cd); + if (err) + return err; + for (i = 0; i ARRAY_SIZE(cd_types); i++) +
mmc: dw_mmc: Add the function call for board-specific initialization.
Need to call init() function of dw_mci_board. It seems to be omitted to call this function. Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a524416..688d58a 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1585,6 +1585,15 @@ static void dw_mci_work_routine_card(struct work_struct *work) } } +static irqreturn_t dw_mci_detect_interrupt(int irq, void *dev_id) +{ + struct dw_mci_slot *slot = dev_id; + + queue_work(dw_mci_card_workqueue, slot-host-card_work); + + return IRQ_HANDLED; +} + static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) { struct mmc_host *mmc; @@ -1657,6 +1666,8 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) } else regulator_enable(host-vmmc); + host-pdata-init(id, dw_mci_detect_interrupt, host); + if (dw_mci_get_cd(mmc)) set_bit(DW_MMC_CARD_PRESENT, slot-flags); else -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: mmc: dw_mmc: Add the function call for board-specific initialization.
Hi, Yes it's defined and checked, but not used. Can you describe the reason why init call is required? and If required, what's the meaning? Thank you, Kyungmin Park On Mon, Jul 4, 2011 at 4:07 PM, Seungwon Jeon tgih@samsung.com wrote: Need to call init() function of dw_mci_board. It seems to be omitted to call this function. Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a524416..688d58a 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1585,6 +1585,15 @@ static void dw_mci_work_routine_card(struct work_struct *work) } } +static irqreturn_t dw_mci_detect_interrupt(int irq, void *dev_id) +{ + struct dw_mci_slot *slot = dev_id; + + queue_work(dw_mci_card_workqueue, slot-host-card_work); + + return IRQ_HANDLED; +} + static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) { struct mmc_host *mmc; @@ -1657,6 +1666,8 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) } else regulator_enable(host-vmmc); + host-pdata-init(id, dw_mci_detect_interrupt, host); + if (dw_mci_get_cd(mmc)) set_bit(DW_MMC_CARD_PRESENT, slot-flags); else -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: mmc: dw_mmc: Add the function call for board-specific initialization.
Hi, -Original Message- From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc- ow...@vger.kernel.org] On Behalf Of Kyungmin Park Sent: Monday, July 04, 2011 4:50 PM To: Seungwon Jeon Cc: linux-mmc@vger.kernel.org; Chris Ball; Will Newton; Jaehoon Chung; James Hogan Subject: Re: mmc: dw_mmc: Add the function call for board-specific initialization. Hi, Yes it's defined and checked, but not used. Can you describe the reason why init call is required? and If required, what's the meaning? I think some board specific init-routine may be needed, e.g. external IRQ for card detection. But there is no call for this in dw_mmc.c currently. If init function is just checked registration of definition and real call is performed outside, we don't need to call this function explicitly. Thank you for comment Best regards, Seungwon. Thank you, Kyungmin Park On Mon, Jul 4, 2011 at 4:07 PM, Seungwon Jeon tgih@samsung.com wrote: Need to call init() function of dw_mci_board. It seems to be omitted to call this function. Signed-off-by: Seungwon Jeon tgih@samsung.com --- drivers/mmc/host/dw_mmc.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a524416..688d58a 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1585,6 +1585,15 @@ static void dw_mci_work_routine_card(struct work_struct *work) } } +static irqreturn_t dw_mci_detect_interrupt(int irq, void *dev_id) +{ + struct dw_mci_slot *slot = dev_id; + + queue_work(dw_mci_card_workqueue, slot-host-card_work); + + return IRQ_HANDLED; +} + static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) { struct mmc_host *mmc; @@ -1657,6 +1666,8 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) } else regulator_enable(host-vmmc); + host-pdata-init(id, dw_mci_detect_interrupt, host); + if (dw_mci_get_cd(mmc)) set_bit(DW_MMC_CARD_PRESENT, slot-flags); else -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] MMC: OMAP: change HSMMC maintainence to Orphan
On Fri, Jul 1, 2011 at 11:06 PM, Kevin Hilman khil...@ti.com wrote: From: Madhusudhan Chikkature madhu...@ti.com Update the OMAP HS MMC entry from the MAINTAINERS file as I will no longer be able to maintain this driver. Signed-off-by: Madhusudhan Chikkature madhu...@ti.com [khil...@ti.com: change to Orphan rather than complete removal] Signed-off-by: Kevin Hilman khil...@ti.com --- Applies to v3.0-rc5 MAINTAINERS | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f0358cd..2f238b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4574,9 +4574,8 @@ S: Maintained F: drivers/mmc/host/omap.c OMAP HS MMC SUPPORT -M: Madhusudhan Chikkature madhu...@ti.com L: linux-o...@vger.kernel.org -S: Maintained +S: Orphan F: drivers/mmc/host/omap_hsmmc.c OMAP RANDOM NUMBER GENERATOR SUPPORT -- 1.7.6 Note for the record: I am interested in making sure that this driver is well supported, even if not designated as 'official' maintainer due to other commitments (as of now). Patches are welcome. Acked-by: Venkatraman S svenk...@ti.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3] MMC: PM: add suspend/resume in atmel-mci
Take care of slots while going to suspend state. Signed-off-by: Nicolas Ferre nicolas.fe...@atmel.com --- V3: take care of each slot SUSPENDED state (adding a status bit in the slot flags) V2: move to pm_ops drivers/mmc/host/atmel-mci.c | 60 ++ 1 files changed, 60 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index aa8039f..ed63bcd 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -203,6 +203,7 @@ struct atmel_mci_slot { #define ATMCI_CARD_PRESENT 0 #define ATMCI_CARD_NEED_INIT 1 #define ATMCI_SHUTDOWN 2 +#define ATMCI_SUSPENDED3 int detect_pin; int wp_pin; @@ -1878,10 +1879,69 @@ static int __exit atmci_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int atmci_suspend(struct device *dev) +{ + struct atmel_mci *host = dev_get_drvdata(dev); + int i; + +for (i = 0; i ATMEL_MCI_MAX_NR_SLOTS; i++) { + struct atmel_mci_slot *slot = host-slot[i]; + int ret; + + if (!slot) + continue; + ret = mmc_suspend_host(slot-mmc); + if (ret 0) { + while (--i = 0) { + slot = host-slot[i]; + if (slot +test_bit(ATMCI_SUSPENDED, slot-flags)) { + mmc_resume_host(host-slot[i]-mmc); + clear_bit(ATMCI_SUSPENDED, slot-flags); + } + } + return ret; + } else { + set_bit(ATMCI_SUSPENDED, slot-flags); + } + } + + return 0; +} + +static int atmci_resume(struct device *dev) +{ + struct atmel_mci *host = dev_get_drvdata(dev); + int i; + int ret = 0; + + for (i = 0; i ATMEL_MCI_MAX_NR_SLOTS; i++) { + struct atmel_mci_slot *slot = host-slot[i]; + int err; + + slot = host-slot[i]; + if (!slot) + continue; + if (!test_bit(ATMCI_SUSPENDED, slot-flags)) + continue; + err = mmc_resume_host(slot-mmc); + if (err 0) + ret = err; + else + clear_bit(ATMCI_SUSPENDED, slot-flags); + } + + return ret; +} +#endif +static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume); + static struct platform_driver atmci_driver = { .remove = __exit_p(atmci_remove), .driver = { .name = atmel_mci, + .pm = atmci_pm, }, }; -- 1.7.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mxs-mmc: fix clock rate setting
Well, maybe not. My colleague complained and I think he is right that we are mapping div2 from the range 0 to 256 (inclusive!) to an 8-bit range. This must be wrong for one value per se. If you look at the context of the patch, you will find it's 'div2 - 1' than 'div2' gets written into register. Exactly. The '- 1' is why Koen changed the upper limit from 256 to = 256. The lower limit fix is currently 'if (div2 == 0) div2 == 1', which is a 2:1 mapping. Not good, or? So you are saying the patch is a right fix but not the most optimal one? In that case, it does not concern me. I acked it as an valid fix. The patches fixes a few things, but for div2, it is curing the symptoms, not the cause, I think. If you look at the formula in the datasheet: rate = ssp / (clock_divide * (1 + clock_rate)); In the code, the calculation of div2 is equal to '1 + clock_rate' (the 1 gets subtracted when the value is written to the register which is a bit unfortunate; doing it earlier would reduce confusion IMO). So that can never be 0, it is a divisor. We should really use DIV_ROUND_UP here. Even when not dealing with 0, this seems needed. Assume: ssp = 5760, wanted_rate = 2500, div1 = 2 will give div2 = int(1.152) = 1 (meaning 0 + 1, because div2 - 1 will be written) The rate will thus be: actual_rate = 5760 / 2 * (0 + 1) = 2880 - too fast! Or did I get something wrong? Regards, Wolfram -- Pengutronix e.K. | Wolfram Sang| Industrial Linux Solutions | http://www.pengutronix.de/ | signature.asc Description: Digital signature
Re: [PATCH] mxs-mmc: fix clock rate setting
On Sun, Jul 3, 2011 at 1:54 PM, Shawn Guo shawn@freescale.com wrote: On Sun, Jul 03, 2011 at 12:31:24PM +0200, Wolfram Sang wrote: On Sun, Jul 03, 2011 at 05:28:52PM +0800, Shawn Guo wrote: On Sat, Jul 02, 2011 at 03:12:25PM +0200, Wolfram Sang wrote: On Fri, Jul 01, 2011 at 11:46:29PM +0800, Shawn Guo wrote: On Fri, Jul 01, 2011 at 04:44:09PM +0200, Wolfram Sang wrote: Hi, On Fri, Jul 01, 2011 at 03:26:39PM +0200, Koen Beel wrote: I send the patch as attachment for now. Fine with me in this case... But I'll have to look into another way of doing this. Corporate mail system is adding stupid disclaimers, gmail web ui is not working ok and corporate firewalls avoid using a different smtp server... Good luck with that! About the patch itself: I didn't verify the formulas, but it does solve one special problem here. Thanks a lot! So: Tested-by: Wolfram Sang w.s...@pengutronix.de @chris: If Shawn also likes the patch, I think this is a stable candidate. Thanks for the fixing, Koen. Acked-by: Shawn Guo shawn@freescale.com Well, maybe not. My colleague complained and I think he is right that we are mapping div2 from the range 0 to 256 (inclusive!) to an 8-bit range. This must be wrong for one value per se. If you look at the context of the patch, you will find it's 'div2 - 1' than 'div2' gets written into register. Exactly. The '- 1' is why Koen changed the upper limit from 256 to = 256. The lower limit fix is currently 'if (div2 == 0) div2 == 1', which is a 2:1 mapping. Not good, or? So you are saying the patch is a right fix but not the most optimal one? In that case, it does not concern me. I acked it as an valid fix. According to the mx23/28 datasheet: - actual mmc/sdio clock = ssp_sck = (sspclk) / ( clock_divide * (1+clock_rate) ) - clock_divide ranges from 2 to 254, by steps of 2 - clock_rate ranges from 0 to 255, so div2 ranges from 1 to 256 - if div2 is the range [0..1[, the only thing we can do is setting it on 1. It just can't be lower. The actual clock rate will be lower then requested. - div2 will only be 1 if div1 is 2. This is because div1 is tested for a good value starting at the lowest possible value (2). Making div2 higher will not solve the issue, it will only result in an even lower actual clock - you could choose the give dev_err (cannot set clock to ...) but i would not do that. Default requested clock for high speed sdio is 50 MHz and the default configuration for mx23 does not support this, so you will also get an error. And having a lower clock then requested is not that bad as having a higher clock. In the code (as before): - div1 = clock_divide (just written in hw) - div2 = 1+clock_rate (clock_rate = div2 - 1 is written in hw) So i think its correct. It work here in all tested condition. Regards, Koen -- Regards, Shawn -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mxs-mmc: fix clock rate setting
On Mon, Jul 4, 2011 at 12:34 PM, Wolfram Sang w.s...@pengutronix.de wrote: Well, maybe not. My colleague complained and I think he is right that we are mapping div2 from the range 0 to 256 (inclusive!) to an 8-bit range. This must be wrong for one value per se. If you look at the context of the patch, you will find it's 'div2 - 1' than 'div2' gets written into register. Exactly. The '- 1' is why Koen changed the upper limit from 256 to = 256. The lower limit fix is currently 'if (div2 == 0) div2 == 1', which is a 2:1 mapping. Not good, or? So you are saying the patch is a right fix but not the most optimal one? In that case, it does not concern me. I acked it as an valid fix. The patches fixes a few things, but for div2, it is curing the symptoms, not the cause, I think. If you look at the formula in the datasheet: rate = ssp / (clock_divide * (1 + clock_rate)); In the code, the calculation of div2 is equal to '1 + clock_rate' (the 1 gets subtracted when the value is written to the register which is a bit unfortunate; doing it earlier would reduce confusion IMO). So that can never be 0, it is a divisor. We should really use DIV_ROUND_UP here. Even when not dealing with 0, this seems needed. Assume: ssp = 5760, wanted_rate = 2500, div1 = 2 will give div2 = int(1.152) = 1 (meaning 0 + 1, because div2 - 1 will be written) The rate will thus be: actual_rate = 5760 / 2 * (0 + 1) = 2880 - too fast! Or did I get something wrong? Regards, Wolfram Well, right now the clock freq. is set to the minimum clock value reaching the requested rate. In current implementation, the rate will be higher in lot's of cases (all cases where the requested clock freq. cannot exactly be made). But the thing is, the driver now enters dev_err, and returns without changing anything when the clock cannot be made as low as requested. In that case you will almost certainly end up with a clock being even higher then the lowest possible. So that not good I think. I might be better to set the clock as low as possible not matter what you to after that. About the rounding. I don't think rounding is good. I think it would be better to choose between having at least the requested rate (as it is now; will result is somewhat higher clock then requested in many cases), or having at maximum the requested clock rate. Both have there problems. -- Pengutronix e.K. | Wolfram Sang | Industrial Linux Solutions | http://www.pengutronix.de/ | -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAk4RlxoACgkQD27XaX1/VRuf7ACgqQ4PvBf9d0am2ButvDT0ZHy1 CQwAn1iHNXcl6t46IW7L/l3UkW7J2nxb =kbX8 -END PGP SIGNATURE- -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mxs-mmc: fix clock rate setting
On Fri, Jul 1, 2011 at 4:44 PM, Wolfram Sang w.s...@pengutronix.de wrote: Hi, On Fri, Jul 01, 2011 at 03:26:39PM +0200, Koen Beel wrote: I send the patch as attachment for now. Fine with me in this case... But I'll have to look into another way of doing this. Corporate mail system is adding stupid disclaimers, gmail web ui is not working ok and corporate firewalls avoid using a different smtp server... Good luck with that! About the patch itself: I didn't verify the formulas, but it does solve one special problem here. Thanks a lot! So: Does it solve any other special problem except for the wrong clock rate setting? Tested-by: Wolfram Sang w.s...@pengutronix.de @chris: If Shawn also likes the patch, I think this is a stable candidate. Very minor nits: From ab610437fade5b30fdeacd9e959ddf95bc42587a Mon Sep 17 00:00:00 2001 From: Koen Beel koen.b...@barco.com Date: Thu, 30 Jun 2011 12:00:19 +0200 Subject: [PATCH] mxs-mmc: fix clock rate setting Fix clock rate setting on mxs-mmc driver. Previously, if div2 was zero the value for TIMING_CLOCK_RATE would have been 255 instead of 0. Also the limits for div1 (TIMING_CLOCK_DIVIDE) and div2 (TIMING_CLOCK_RATE + 1) where not correctly defined. Can easily be reproduced on mx23evk: default clock for high speed sdio cards is 50 MHz. With a SSP_CLK of 28.8 MHz (default), this resulted in an actual clock rate of about 56 kHz. Commit msg should linebreak at 72. Signed-off-by: Koen beel koen.b...@barco.com Capital 'B'? Indeed, it should have been: Signed-off-by: Koen Beel koen.b...@barco.com Regards, Wolfram -- Pengutronix e.K. | Wolfram Sang | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V3] MMC: PM: add suspend/resume in atmel-mci
Hi, On Mon, Jul 04, 2011 at 01:38:25PM +0200, Nicolas Ferre wrote: Take care of slots while going to suspend state. Signed-off-by: Nicolas Ferre nicolas.fe...@atmel.com --- V3: take care of each slot SUSPENDED state (adding a status bit in the slot flags) V2: move to pm_ops drivers/mmc/host/atmel-mci.c | 60 ++ 1 files changed, 60 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index aa8039f..ed63bcd 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -203,6 +203,7 @@ struct atmel_mci_slot { #define ATMCI_CARD_PRESENT 0 #define ATMCI_CARD_NEED_INIT 1 #define ATMCI_SHUTDOWN 2 +#define ATMCI_SUSPENDED 3 int detect_pin; int wp_pin; @@ -1878,10 +1879,69 @@ static int __exit atmci_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int atmci_suspend(struct device *dev) +{ + struct atmel_mci *host = dev_get_drvdata(dev); + int i; + + for (i = 0; i ATMEL_MCI_MAX_NR_SLOTS; i++) { + struct atmel_mci_slot *slot = host-slot[i]; + int ret; + + if (!slot) + continue; + ret = mmc_suspend_host(slot-mmc); + if (ret 0) { + while (--i = 0) { + slot = host-slot[i]; + if (slot + test_bit(ATMCI_SUSPENDED, slot-flags)) { + mmc_resume_host(host-slot[i]-mmc); + clear_bit(ATMCI_SUSPENDED, slot-flags); + } + } + return ret; + } else { + set_bit(ATMCI_SUSPENDED, slot-flags); + } + } + + return 0; +} + +static int atmci_resume(struct device *dev) +{ + struct atmel_mci *host = dev_get_drvdata(dev); + int i; + int ret = 0; + + for (i = 0; i ATMEL_MCI_MAX_NR_SLOTS; i++) { + struct atmel_mci_slot *slot = host-slot[i]; + int err; + + slot = host-slot[i]; + if (!slot) + continue; + if (!test_bit(ATMCI_SUSPENDED, slot-flags)) + continue; + err = mmc_resume_host(slot-mmc); + if (err 0) + ret = err; + else + clear_bit(ATMCI_SUSPENDED, slot-flags); + } + + return ret; +} +#endif +static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume); if you disable CONFIG_PM this won't work. atmci_resume and atmci_suspend will be undefined. static struct platform_driver atmci_driver = { .remove = __exit_p(atmci_remove), .driver = { .name = atmel_mci, + .pm = atmci_pm, this pointer will also be invalid. what most people do is: #ifdef CONFIG_PM suspend() resume() static SIMPLE_DEV_PM_OPS(atmci_pm, suspend, resume); #define DEV_PM_OPS (atmci_pm) #else #define DEV_PM_OPS NULL #endif -- balbi signature.asc Description: Digital signature
Re: [PATCH V3] MMC: PM: add suspend/resume in atmel-mci
Le 04/07/2011 13:06, Felipe Balbi : Hi, On Mon, Jul 04, 2011 at 01:38:25PM +0200, Nicolas Ferre wrote: Take care of slots while going to suspend state. Signed-off-by: Nicolas Ferre nicolas.fe...@atmel.com --- V3: take care of each slot SUSPENDED state (adding a status bit in the slot flags) V2: move to pm_ops drivers/mmc/host/atmel-mci.c | 60 ++ 1 files changed, 60 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index aa8039f..ed63bcd 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -203,6 +203,7 @@ struct atmel_mci_slot { #define ATMCI_CARD_PRESENT 0 #define ATMCI_CARD_NEED_INIT1 #define ATMCI_SHUTDOWN 2 +#define ATMCI_SUSPENDED 3 int detect_pin; int wp_pin; @@ -1878,10 +1879,69 @@ static int __exit atmci_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int atmci_suspend(struct device *dev) +{ +struct atmel_mci *host = dev_get_drvdata(dev); +int i; + + for (i = 0; i ATMEL_MCI_MAX_NR_SLOTS; i++) { +struct atmel_mci_slot *slot = host-slot[i]; +int ret; + +if (!slot) +continue; +ret = mmc_suspend_host(slot-mmc); +if (ret 0) { +while (--i = 0) { +slot = host-slot[i]; +if (slot + test_bit(ATMCI_SUSPENDED, slot-flags)) { +mmc_resume_host(host-slot[i]-mmc); +clear_bit(ATMCI_SUSPENDED, slot-flags); +} +} +return ret; +} else { +set_bit(ATMCI_SUSPENDED, slot-flags); +} +} + +return 0; +} + +static int atmci_resume(struct device *dev) +{ +struct atmel_mci *host = dev_get_drvdata(dev); +int i; +int ret = 0; + +for (i = 0; i ATMEL_MCI_MAX_NR_SLOTS; i++) { +struct atmel_mci_slot *slot = host-slot[i]; +int err; + +slot = host-slot[i]; +if (!slot) +continue; +if (!test_bit(ATMCI_SUSPENDED, slot-flags)) +continue; +err = mmc_resume_host(slot-mmc); +if (err 0) +ret = err; +else +clear_bit(ATMCI_SUSPENDED, slot-flags); +} + +return ret; +} +#endif +static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume); if you disable CONFIG_PM this won't work. atmci_resume and atmci_suspend will be undefined. static struct platform_driver atmci_driver = { .remove = __exit_p(atmci_remove), .driver = { .name = atmel_mci, +.pm = atmci_pm, this pointer will also be invalid. what most people do is: #ifdef CONFIG_PM suspend() resume() static SIMPLE_DEV_PM_OPS(atmci_pm, suspend, resume); #define DEV_PM_OPS(atmci_pm) #else #define DEV_PM_OPSNULL #endif Yes, sure that makes sense. Thanks, I will cook a V4. Best regards, -- Nicolas Ferre -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 0/3] OMAP: HSMMC: cleanup and runtime pm
From: Kevin Hilman khil...@ti.com Date: Fri, Jul 1, 2011 at 11:24 PM Subject: Re: [PATCHv4 0/3] OMAP: HSMMC: cleanup and runtime pm To: c...@laptop.org Cc: Balaji T K balaj...@ti.com, linux-o...@vger.kernel.org, linux-mmc@vger.kernel.org, t...@atomide.com, madhu...@ti.com, b-cous...@ti.com, p...@pwsan.com, kishore.kadiy...@ti.com Chris, Balaji T K balaj...@ti.com writes: Removing the custom state machine - lazy disable framework in omap_hsmmc to make way for runtime pm to handle host controller power states. This allows mmc_host_enable/mmc_host_disable to be replaced by runtime get_sync and put_sync at host controller driver. Enable runtime PM in omap_hsmmc Rebased to MMC tree : mmc-next branch Tested on OMAP4430SDP, OMAP3430SDP, OMAP2430SDP Reviewed-by: Kevin Hilman khil...@ti.com Tested-by: Kevin Hilman khil...@ti.com Could you queue this series for the v3.1 merge window? Or, with your ack, we are happy to take this through the OMAP tree along with the other dependecies mentioned below. I've also tested this on OMAP4430/Blaze, OMAP3630/Zoom3 and OMAP3430/n900. We have OMAP PM core code changes queued for v3.1 which require the MMC driver to correctly use runtime PM or we can get hangs if MMC is used during boot. Kevin Kevin, Another series from Per Forlin [1] is also modifying the same file, and might result in merge conflict if this series is queued under OMAP and the other is queued by Chris. Chris, If you intend to queue [1] into mmc-next, Balaji / myself can repost this series on top of it or you'd like to practice some git merge ? Let me know if there is anything that I can do to help. [1] https://lkml.org/lkml/2011/7/1/303 MMC runtime patch has dependency on [PATCH 0/6] OMAP2+: hwmod framework fixes [1] for MMC1/MMC2 clock to get ungated after idle in OMAP4. Without [1] patches, MMC1/MMC2 fails to get detected on OMAP4. [1] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg51457.html Balaji T K (3): MMC: OMAP: HSMMC: Remove lazy_disable MMC: OMAP: HSMMC: add runtime pm support MMC: OMAP: HSMMC: Remove unused iclk drivers/mmc/host/omap_hsmmc.c | 365 +++-- 1 files changed, 57 insertions(+), 308 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] eSDHC: Access Freescale eSDHC registers by 32-bit
From: Xu lei b33...@freescale.com For Freescale eSDHC registers only support 32-bit accesses, this patch ensure that all Freescale eSDHC register accesses are 32-bit. Signed-off-by: Xu lei b33...@freescale.com Signed-off-by: Roy Zang tie-fei.z...@freescale.com Signed-off-by: Kumar Gala ga...@kernel.crashing.org --- drivers/mmc/host/sdhci-of-esdhc.c | 18 ++ 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index ba40d6d..c9a8519 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -1,7 +1,7 @@ /* * Freescale eSDHC controller driver. * - * Copyright (c) 2007 Freescale Semiconductor, Inc. + * Copyright (c) 2007, 2010 Freescale Semiconductor, Inc. * Copyright (c) 2009 MontaVista Software, Inc. * * Authors: Xiaobo Xie x@freescale.com @@ -23,11 +23,21 @@ static u16 esdhc_readw(struct sdhci_host *host, int reg) { u16 ret; + int base = reg ~0x3; + int shift = (reg 0x2) * 8; if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be16(host-ioaddr + reg); + ret = in_be32(host-ioaddr + base) 0x; else - ret = sdhci_be32bs_readw(host, reg); + ret = (in_be32(host-ioaddr + base) shift) 0x; + return ret; +} + +static u8 esdhc_readb(struct sdhci_host *host, int reg) +{ + int base = reg ~0x3; + int shift = (reg 0x3) * 8; + u8 ret = (in_be32(host-ioaddr + base) shift) 0xff; return ret; } @@ -79,7 +89,7 @@ struct sdhci_of_data sdhci_esdhc = { .ops = { .read_l = sdhci_be32bs_readl, .read_w = esdhc_readw, - .read_b = sdhci_be32bs_readb, + .read_b = esdhc_readb, .write_l = sdhci_be32bs_writel, .write_w = esdhc_writew, .write_b = esdhc_writeb, -- 1.6.0.6 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] eSDHC: fix incorrect default value of the capabilities register on P4080
P4080 eSDHC errata 12 describes incorrect default value of the the host controller capabilities register. The default value of the VS18 and VS30 fields in the host controller capabilities register (HOSTCAPBLT) are incorrect. The default of these bits should be zero instead of one in the eSDHC logic. This patch adds the workaround for these errata. Signed-off-by: Roy Zang tie-fei.z...@freescale.com --- drivers/mmc/host/sdhci-of-core.c |3 +++ drivers/mmc/host/sdhci.c |6 ++ include/linux/mmc/sdhci.h|4 3 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index fede43d..9bdd30d 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -182,6 +182,9 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev) if (of_device_is_compatible(np, fsl,esdhc)) host-quirks |= SDHCI_QUIRK_QORIQ_PROCTL_WEIRD; + if (of_device_is_compatible(np, fsl,p4080-esdhc)) + host-quirks |= SDHCI_QUIRK_QORIQ_HOSTCAPBLT_ONLY_VS33; + clk = of_get_property(np, clock-frequency, size); if (clk size == sizeof(*clk) *clk) of_host-clock = be32_to_cpup(clk); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 77174e5..7e0b4cd 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2396,6 +2396,12 @@ int sdhci_add_host(struct sdhci_host *host) caps[1] = (host-version = SDHCI_SPEC_300) ? sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0; +/* Make sure clean the VS18 and VS30 bit. P4080 incorrectly + * set the voltage capability bits + */ + if (host-quirks SDHCI_QUIRK_QORIQ_HOSTCAPBLT_ONLY_VS33) + caps[0] = ~(SDHCI_CAN_VDD_180 | SDHCI_CAN_VDD_300); + if (host-quirks SDHCI_QUIRK_FORCE_DMA) host-flags |= SDHCI_USE_SDMA; else if (!(caps[0] SDHCI_CAN_DO_SDMA)) diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index d87abc7..7ffd458 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -89,6 +89,10 @@ struct sdhci_host { #define SDHCI_QUIRK_UNSTABLE_RO_DETECT (1U31) /* Controller has weird bit setting for Protocol Control Register */ #define SDHCI_QUIRK_QORIQ_PROCTL_WEIRD (0x1U) +/* Controller can only supports 3.3V, but the capabilities register + * has incorrect set 1.8V and 3.0V + */ +#define SDHCI_QUIRK_QORIQ_HOSTCAPBLT_ONLY_VS33 (0x2U) int irq;/* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ -- 1.6.0.6 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] eSDHC: Fix errors when booting kernel with fsl esdhc
From: Xu lei b33...@freescale.com When esdhc module was enabled in p5020, there were following errors: mmc0: Timeout waiting for hardware interrupt. mmc0: error -110 whilst initialising SD card mmc0: Unexpected interrupt 0x0200. mmc0: Timeout waiting for hardware interrupt. mmc0: error -110 whilst initialising SD card mmc0: Unexpected interrupt 0x0200. It is because ESDHC controller has different bit setting for PROCTL register, when kernel sets Power Control Register by method for standard SD Host Specification, it would overwritten FSL ESDHC PROCTL[DMAS]; when it set Host Control Registers[DMAS], it sets PROCTL[EMODE] and PROCTL[D3CD]. These operations will set bad bits for PROCTL Register on FSL ESDHC Controller and cause errors, so this patch will make esdhc driver access FSL PROCTL Register according to block guide instead of standard SD Host Specification. For some FSL chips, such as MPC8536/P2020, PROCTL[VOLT_SEL] and PROCTL[DMAS] bits are reserved and even if they are set to wrong bits there is no error. But considering that all FSL ESDHC Controller register map is not fully compliant to standard SD Host Specification, we put the patch to all of FSL ESDHC Controllers. Signed-off-by: Lei Xu b33...@freescale.com Signed-off-by: Roy Zang tie-fei.z...@freescale.com Signed-off-by: Kumar Gala ga...@kernel.crashing.org --- drivers/mmc/host/sdhci-of-core.c |3 ++ drivers/mmc/host/sdhci.c | 62 ++--- include/linux/mmc/sdhci.h|6 ++- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index 60e4186..fede43d 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -179,6 +179,9 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev) if (sdhci_of_wp_inverted(np)) host-quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT; + if (of_device_is_compatible(np, fsl,esdhc)) + host-quirks |= SDHCI_QUIRK_QORIQ_PROCTL_WEIRD; + clk = of_get_property(np, clock-frequency, size); if (clk size == sizeof(*clk) *clk) of_host-clock = be32_to_cpup(clk); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 58d5436..77174e5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -674,7 +674,7 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) { u8 count; - u8 ctrl; + u32 ctrl; struct mmc_data *data = cmd-data; int ret; @@ -807,14 +807,28 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) * is ADMA. */ if (host-version = SDHCI_SPEC_200) { - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - ctrl = ~SDHCI_CTRL_DMA_MASK; - if ((host-flags SDHCI_REQ_USE_DMA) - (host-flags SDHCI_USE_ADMA)) - ctrl |= SDHCI_CTRL_ADMA32; - else - ctrl |= SDHCI_CTRL_SDMA; - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + if (host-quirks SDHCI_QUIRK_QORIQ_PROCTL_WEIRD) { +#define ESDHCI_PROCTL_DMAS_MASK0x0300 +#define ESDHCI_PROCTL_ADMA32 0x0200 +#define ESDHCI_PROCTL_SDMA 0x + ctrl = sdhci_readl(host, SDHCI_HOST_CONTROL); + ctrl = ~ESDHCI_PROCTL_DMAS_MASK; + if ((host-flags SDHCI_REQ_USE_DMA) + (host-flags SDHCI_USE_ADMA)) + ctrl |= ESDHCI_PROCTL_ADMA32; + else + ctrl |= ESDHCI_PROCTL_SDMA; + sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL); + } else { + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + ctrl = ~SDHCI_CTRL_DMA_MASK; + if ((host-flags SDHCI_REQ_USE_DMA) + (host-flags SDHCI_USE_ADMA)) + ctrl |= SDHCI_CTRL_ADMA32; + else + ctrl |= SDHCI_CTRL_SDMA; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } } if (!(host-flags SDHCI_REQ_USE_DMA)) { @@ -1138,19 +1152,32 @@ out: static void sdhci_set_power(struct sdhci_host *host, unsigned short power) { u8 pwr = 0; + u8 volt = 0; if (power != (unsigned short)-1) { switch (1 power) { +#defineESDHCI_FSL_POWER_MASK 0x40 +#defineESDHCI_FSL_POWER_1800x00 +#defineESDHCI_FSL_POWER_3000x40 case MMC_VDD_165_195: - pwr = SDHCI_POWER_180; + if