* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
[not found] ` <20101021141302.GA11912@void.printf.net>
@ 2010-10-21 14:52 ` Chris Ball
2010-10-22 0:20 ` Marek Vasut
2010-10-22 8:44 ` Haojian Zhuang
0 siblings, 2 replies; 13+ messages in thread
From: Chris Ball @ 2010-10-21 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On Thu, Oct 21, 2010 at 03:13:02PM +0100, Chris Ball wrote:
> On Mon, Oct 18, 2010 at 08:32:46AM -0400, zhangfei gao wrote:
> > Update with comments from Matt and Eric.
> > Test with sd and emmc.
> >
> > >From e5dd554ed4d3488a83d9a4888d68d1d85482f747 Mon Sep 17 00:00:00 2001
> > From: Zhangfei Gao <zhangfei.gao@marvell.com>
> > Date: Mon, 20 Sep 2010 10:51:28 -0400
> > Subject: [PATCH] mmc: add support of sdhci-pxa driver
> >
> > Support Marvell PXA168/PXA910/MMP2 SD Host Controller
> >
> > Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
> > ---
> > arch/arm/plat-pxa/include/plat/sdhci.h | 32 ++++
> > drivers/mmc/host/Kconfig | 12 ++
> > drivers/mmc/host/Makefile | 1 +
> > drivers/mmc/host/sdhci-pxa.c | 259 ++++++++++++++++++++++++++++++++
> > 4 files changed, 304 insertions(+), 0 deletions(-)
> > create mode 100644 arch/arm/plat-pxa/include/plat/sdhci.h
> > create mode 100644 drivers/mmc/host/sdhci-pxa.c
>
> I'll take the drivers/mmc/ hunks, but you should send the plat-pxa/
> patch through the ARM tree.
Oh. If we do that then the driver won't compile until everything's
together, because it #includes <plat/sdhci.h>. Haojian/Eric, what do
you prefer here? Should I take the arch/arm/ hunk via the MMC tree?
(If so, please provide ACKs.)
Thanks,
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-21 14:52 ` [PATCH V3 1/1]MMC: add support of sdhci-pxa driver Chris Ball
@ 2010-10-22 0:20 ` Marek Vasut
2010-10-22 0:27 ` Chris Ball
2010-10-22 8:44 ` Haojian Zhuang
1 sibling, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2010-10-22 0:20 UTC (permalink / raw)
To: linux-arm-kernel
Dne ?t 21. ??jna 2010 16:52:49 Chris Ball napsal(a):
> Hi,
>
> On Thu, Oct 21, 2010 at 03:13:02PM +0100, Chris Ball wrote:
> > On Mon, Oct 18, 2010 at 08:32:46AM -0400, zhangfei gao wrote:
> > > Update with comments from Matt and Eric.
> > > Test with sd and emmc.
> > >
> > > >From e5dd554ed4d3488a83d9a4888d68d1d85482f747 Mon Sep 17 00:00:00 2001
> > >
> > > From: Zhangfei Gao <zhangfei.gao@marvell.com>
> > > Date: Mon, 20 Sep 2010 10:51:28 -0400
> > > Subject: [PATCH] mmc: add support of sdhci-pxa driver
> > >
> > > Support Marvell PXA168/PXA910/MMP2 SD Host Controller
> > >
> > > Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
> > > ---
> > >
> > > arch/arm/plat-pxa/include/plat/sdhci.h | 32 ++++
> > > drivers/mmc/host/Kconfig | 12 ++
> > > drivers/mmc/host/Makefile | 1 +
> > > drivers/mmc/host/sdhci-pxa.c | 259
> > > ++++++++++++++++++++++++++++++++ 4 files changed, 304 insertions(+),
> > > 0 deletions(-)
> > > create mode 100644 arch/arm/plat-pxa/include/plat/sdhci.h
> > > create mode 100644 drivers/mmc/host/sdhci-pxa.c
> >
> > I'll take the drivers/mmc/ hunks, but you should send the plat-pxa/
> > patch through the ARM tree.
>
> Oh. If we do that then the driver won't compile until everything's
> together, because it #includes <plat/sdhci.h>. Haojian/Eric, what do
> you prefer here? Should I take the arch/arm/ hunk via the MMC tree?
> (If so, please provide ACKs.)
>
> Thanks,
Hi, where can I find the whole driver so I can take a look? It didn't crash into
linux-arm-kernel for some reason.
Thanks
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-22 0:20 ` Marek Vasut
@ 2010-10-22 0:27 ` Chris Ball
0 siblings, 0 replies; 13+ messages in thread
From: Chris Ball @ 2010-10-22 0:27 UTC (permalink / raw)
To: linux-arm-kernel
Hi Marek,
On Fri, Oct 22, 2010 at 02:20:10AM +0200, Marek Vasut wrote:
> > > I'll take the drivers/mmc/ hunks, but you should send the plat-pxa/
> > > patch through the ARM tree.
> >
> > Oh. If we do that then the driver won't compile until everything's
> > together, because it #includes <plat/sdhci.h>. Haojian/Eric, what do
> > you prefer here? Should I take the arch/arm/ hunk via the MMC tree?
> > (If so, please provide ACKs.)
>
> Hi, where can I find the whole driver so I can take a look? It didn't
> crash into linux-arm-kernel for some reason.
Here it is:
http://thread.gmane.org/gmane.linux.kernel.mmc/4190
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-21 14:52 ` [PATCH V3 1/1]MMC: add support of sdhci-pxa driver Chris Ball
2010-10-22 0:20 ` Marek Vasut
@ 2010-10-22 8:44 ` Haojian Zhuang
2010-10-22 9:58 ` Chris Ball
1 sibling, 1 reply; 13+ messages in thread
From: Haojian Zhuang @ 2010-10-22 8:44 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Oct 21, 2010 at 10:52 PM, Chris Ball <cjb@laptop.org> wrote:
> Hi,
>
> On Thu, Oct 21, 2010 at 03:13:02PM +0100, Chris Ball wrote:
>> On Mon, Oct 18, 2010 at 08:32:46AM -0400, zhangfei gao wrote:
>> > Update with comments from Matt and Eric.
>> > Test with sd and emmc.
>> >
>> > >From e5dd554ed4d3488a83d9a4888d68d1d85482f747 Mon Sep 17 00:00:00 2001
>> > From: Zhangfei Gao <zhangfei.gao@marvell.com>
>> > Date: Mon, 20 Sep 2010 10:51:28 -0400
>> > Subject: [PATCH] mmc: add support of sdhci-pxa driver
>> >
>> > ? ? Support Marvell PXA168/PXA910/MMP2 SD Host Controller
>> >
>> > Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
>> > ---
>> > ?arch/arm/plat-pxa/include/plat/sdhci.h | ? 32 ++++
>> > ?drivers/mmc/host/Kconfig ? ? ? ? ? ? ? | ? 12 ++
>> > ?drivers/mmc/host/Makefile ? ? ? ? ? ? ?| ? ?1 +
>> > ?drivers/mmc/host/sdhci-pxa.c ? ? ? ? ? | ?259 ++++++++++++++++++++++++++++++++
>> > ?4 files changed, 304 insertions(+), 0 deletions(-)
>> > ?create mode 100644 arch/arm/plat-pxa/include/plat/sdhci.h
>> > ?create mode 100644 drivers/mmc/host/sdhci-pxa.c
>>
>> I'll take the drivers/mmc/ hunks, but you should send the plat-pxa/
>> patch through the ARM tree.
>
> Oh. ?If we do that then the driver won't compile until everything's
> together, because it #includes <plat/sdhci.h>. ?Haojian/Eric, what do
> you prefer here? ?Should I take the arch/arm/ hunk via the MMC tree?
> (If so, please provide ACKs.)
>
Acked-by: Haojian Zhuang.
I'm fine on this. Please merge it via the MMC tree.
Thanks
Haojian
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-22 8:44 ` Haojian Zhuang
@ 2010-10-22 9:58 ` Chris Ball
2010-10-22 11:04 ` Chris Ball
0 siblings, 1 reply; 13+ messages in thread
From: Chris Ball @ 2010-10-22 9:58 UTC (permalink / raw)
To: linux-arm-kernel
Hi Russell,
On Fri, Oct 22, 2010 at 04:44:07PM +0800, Haojian Zhuang wrote:
> I'm fine on this. Please merge it via the MMC tree.
I'm planning on merging this patch via the MMC tree, please let me know
if you object. Thanks.
From: Zhangfei Gao <zhangfei.gao@marvell.com>
Date: Mon, 20 Sep 2010 10:51:28 -0400
Subject: [PATCH] mmc: add new sdhci-pxa driver for Marvell SoCs
Support Marvell PXA168/PXA910/MMP2 SD Host Controller.
Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
Acked-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
---
arch/arm/plat-pxa/include/plat/sdhci.h | 32 ++++
drivers/mmc/host/Kconfig | 12 ++
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-pxa.c | 258 ++++++++++++++++++++++++++++++++
4 files changed, 303 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-pxa/include/plat/sdhci.h
create mode 100644 drivers/mmc/host/sdhci-pxa.c
diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h
new file mode 100644
index 0000000..3e3c728
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/sdhci.h
@@ -0,0 +1,32 @@
+/* linux/arch/arm/plat-pxa/include/plat/sdhci.h
+ *
+ * Copyright 2010 Marvell
+ * Zhangfei Gao <zhangfei.gao@marvell.com>
+ *
+ * PXA Platform - SDHCI platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_PXA_SDHCI_H
+#define __PLAT_PXA_SDHCI_H
+
+/* pxa specific flag */
+/* Require clock free running */
+#define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
+
+/**
+ * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
+ * @max_speed: the maximum speed supported
+ * @quirks: quirks of specific device
+ * @flags: flags for platform requirement
+*/
+struct sdhci_pxa_platdata {
+ unsigned int max_speed;
+ unsigned int quirks;
+ unsigned int flags;
+};
+
+#endif /* __PLAT_PXA_SDHCI_H */
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index c9c2520..40b0fb9 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -155,6 +155,18 @@ config MMC_SDHCI_S3C
If unsure, say N.
+config MMC_SDHCI_PXA
+ tristate "Marvell PXA168/PXA910/MMP2 SD Host Controller support"
+ depends on ARCH_PXA || ARCH_MMP
+ select MMC_SDHCI
+ select MMC_SDHCI_IO_ACCESSORS
+ help
+ This selects the Marvell(R) PXA168/PXA910/MMP2 SD Host Controller.
+ If you have a PXA168/PXA910/MMP2 platform with SD Host Controller
+ and a card slot, say Y or M here.
+
+ If unsure, say N.
+
config MMC_SDHCI_SPEAR
tristate "SDHCI support on ST SPEAr platform"
depends on MMC_SDHCI && PLAT_SPEAR
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 6c4ac67..7b645ff 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o
obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
+obj-$(CONFIG_MMC_SDHCI_PXA) += sdhci-pxa.o
obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c
new file mode 100644
index 0000000..aeba3e3
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pxa.c
@@ -0,0 +1,258 @@
+/* linux/drivers/mmc/host/sdhci-pxa.c
+ *
+ * Copyright (C) 2010 Marvell International Ltd.
+ * Zhangfei Gao <zhangfei.gao@marvell.com>
+ * Kevin Wang <dwang4@marvell.com>
+ * Mingwei Wang <mwwang@marvell.com>
+ * Philip Rakity <prakity@marvell.com>
+ * Mark Brown <markb@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Supports:
+ * SDHCI support for MMP2/PXA910/PXA168
+ *
+ * Refer to sdhci-s3c.c.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <plat/sdhci.h>
+#include "sdhci.h"
+
+#define DRIVER_NAME "sdhci-pxa"
+
+#define SD_FIFO_PARAM 0x104
+#define DIS_PAD_SD_CLK_GATE 0x400
+
+struct sdhci_pxa {
+ struct sdhci_host *host;
+ struct sdhci_pxa_platdata *pdata;
+ struct clk *clk;
+ struct resource *res;
+
+ u8 clk_enable;
+};
+
+/*****************************************************************************\
+ * *
+ * SDHCI core callbacks *
+ * *
+\*****************************************************************************/
+static void set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ struct sdhci_pxa *pxa = sdhci_priv(host);
+ u32 tmp = 0;
+
+ if (clock == 0) {
+ if (pxa->clk_enable) {
+ clk_disable(pxa->clk);
+ pxa->clk_enable = 0;
+ }
+ } else {
+ if (0 == pxa->clk_enable) {
+ if (pxa->pdata->flags & PXA_FLAG_DISABLE_CLOCK_GATING) {
+ tmp = readl(host->ioaddr + SD_FIFO_PARAM);
+ tmp |= DIS_PAD_SD_CLK_GATE;
+ writel(tmp, host->ioaddr + SD_FIFO_PARAM);
+ }
+ clk_enable(pxa->clk);
+ pxa->clk_enable = 1;
+ }
+ }
+}
+
+static struct sdhci_ops sdhci_pxa_ops = {
+ .set_clock = set_clock,
+};
+
+/*****************************************************************************\
+ * *
+ * Device probing/removal *
+ * *
+\*****************************************************************************/
+
+static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
+{
+ struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct sdhci_host *host = NULL;
+ struct resource *iomem = NULL;
+ struct sdhci_pxa *pxa = NULL;
+ int ret, irq;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "no irq specified\n");
+ return irq;
+ }
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iomem) {
+ dev_err(dev, "no memory specified\n");
+ return -ENOENT;
+ }
+
+ host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
+ if (IS_ERR(host)) {
+ dev_err(dev, "failed to alloc host\n");
+ return PTR_ERR(host);
+ }
+
+ pxa = sdhci_priv(host);
+ pxa->host = host;
+ pxa->pdata = pdata;
+ pxa->clk_enable = 0;
+
+ pxa->clk = clk_get(dev, "PXA-SDHCLK");
+ if (IS_ERR(pxa->clk)) {
+ dev_err(dev, "failed to get io clock\n");
+ ret = PTR_ERR(pxa->clk);
+ goto out;
+ }
+
+ pxa->res = request_mem_region(iomem->start, resource_size(iomem),
+ mmc_hostname(host->mmc));
+ if (!pxa->res) {
+ dev_err(&pdev->dev, "cannot request region\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ host->ioaddr = ioremap(iomem->start, resource_size(iomem));
+ if (!host->ioaddr) {
+ dev_err(&pdev->dev, "failed to remap registers\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ host->hw_name = "MMC";
+ host->ops = &sdhci_pxa_ops;
+ host->irq = irq;
+ host->quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
+ if (pdata->quirks)
+ host->quirks |= pdata->quirks;
+
+ ret = sdhci_add_host(host);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add host\n");
+ goto out;
+ }
+
+ if (pxa->pdata->max_speed)
+ host->mmc->f_max = pxa->pdata->max_speed;
+
+ platform_set_drvdata(pdev, host);
+
+ return 0;
+out:
+ if (host) {
+ clk_put(pxa->clk);
+ if (host->ioaddr)
+ iounmap(host->ioaddr);
+ if (pxa->res)
+ release_mem_region(pxa->res->start,
+ resource_size(pxa->res));
+ sdhci_free_host(host);
+ }
+
+ return ret;
+}
+
+static int __devexit sdhci_pxa_remove(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ struct sdhci_pxa *pxa = sdhci_priv(host);
+ int dead = 0;
+ u32 scratch;
+
+ if (host) {
+ scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+ if (scratch == (u32)-1)
+ dead = 1;
+
+ sdhci_remove_host(host, dead);
+
+ if (host->ioaddr)
+ iounmap(host->ioaddr);
+ if (pxa->res)
+ release_mem_region(pxa->res->start,
+ resource_size(pxa->res));
+ if (pxa->clk_enable) {
+ clk_disable(pxa->clk);
+ pxa->clk_enable = 0;
+ }
+ clk_put(pxa->clk);
+
+ sdhci_free_host(host);
+ platform_set_drvdata(pdev, NULL);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdhci_pxa_suspend(struct platform_device *dev)
+{
+ struct sdhci_host *host = platform_get_drvdata(to_platform_device(dev));
+
+ return sdhci_suspend_host(host, state);
+}
+
+static int sdhci_pxa_resume(struct platform_device *dev)
+{
+ struct sdhci_host *host = platform_get_drvdata(to_platform_device(dev));
+
+ return sdhci_resume_host(host);
+}
+#else
+#define sdhci_pxa_suspend NULL
+#define sdhci_pxa_resume NULL
+#endif
+
+static const struct dev_pm_ops sdhci_pxa_pm_ops = {
+ .suspend = sdhci_pxa_suspend,
+ .resume = sdhci_pxa_resume,
+};
+
+
+static struct platform_driver sdhci_pxa_driver = {
+ .probe = sdhci_pxa_probe,
+ .remove = __devexit_p(sdhci_pxa_remove),
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .pm = &sdhci_pxa_pm_ops,
+ },
+};
+
+/*****************************************************************************\
+ * *
+ * Driver init/exit *
+ * *
+\*****************************************************************************/
+
+static int __init sdhci_pxa_init(void)
+{
+ return platform_driver_register(&sdhci_pxa_driver);
+}
+
+static void __exit sdhci_pxa_exit(void)
+{
+ platform_driver_unregister(&sdhci_pxa_driver);
+}
+
+module_init(sdhci_pxa_init);
+module_exit(sdhci_pxa_exit);
+
+MODULE_DESCRIPTION("SDH controller driver for PXA168/PXA910/MMP2");
+MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");
+MODULE_LICENSE("GPL v2");
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-22 9:58 ` Chris Ball
@ 2010-10-22 11:04 ` Chris Ball
2010-10-22 14:09 ` zhangfei gao
0 siblings, 1 reply; 13+ messages in thread
From: Chris Ball @ 2010-10-22 11:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On Fri, Oct 22, 2010 at 10:58:14AM +0100, Chris Ball wrote:
[...]
> +#ifdef CONFIG_PM
> +static int sdhci_pxa_suspend(struct platform_device *dev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(to_platform_device(dev));
> +
> + return sdhci_suspend_host(host, state);
> +}
> +
> +static int sdhci_pxa_resume(struct platform_device *dev)
> +{
These prototypes are not correct, leading to:
CC [M] drivers/mmc/host/sdhci-pxa.o
drivers/mmc/host/sdhci-pxa.c: In function ?sdhci_pxa_suspend?:
drivers/mmc/host/sdhci-pxa.c:205: warning: initialization from incompatible pointer type
drivers/mmc/host/sdhci-pxa.c:207: error: ?state? undeclared (first use in this function)
drivers/mmc/host/sdhci-pxa.c:207: error: (Each undeclared identifier is reported only once
drivers/mmc/host/sdhci-pxa.c:207: error: for each function it appears in.)
drivers/mmc/host/sdhci-pxa.c: In function ?sdhci_pxa_resume?:
drivers/mmc/host/sdhci-pxa.c:212: warning: initialization from incompatible pointer type
drivers/mmc/host/sdhci-pxa.c: At top level:
drivers/mmc/host/sdhci-pxa.c:222: warning: initialization from incompatible pointer type
drivers/mmc/host/sdhci-pxa.c:223: warning: initialization from incompatible pointer type
when compiled with CONFIG_PM=y.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-22 11:04 ` Chris Ball
@ 2010-10-22 14:09 ` zhangfei gao
2010-10-23 14:24 ` Marek Vasut
0 siblings, 1 reply; 13+ messages in thread
From: zhangfei gao @ 2010-10-22 14:09 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Oct 22, 2010 at 7:04 AM, Chris Ball <cjb@laptop.org> wrote:
> Hi,
>
> On Fri, Oct 22, 2010 at 10:58:14AM +0100, Chris Ball wrote:
> [...]
>> +#ifdef CONFIG_PM
>> +static int sdhci_pxa_suspend(struct platform_device *dev)
>> +{
>> + ? ? struct sdhci_host *host = platform_get_drvdata(to_platform_device(dev));
>> +
>> + ? ? return sdhci_suspend_host(host, state);
>> +}
>> +
>> +static int sdhci_pxa_resume(struct platform_device *dev)
>> +{
>
> These prototypes are not correct, leading to:
>
> ?CC [M] ?drivers/mmc/host/sdhci-pxa.o
> drivers/mmc/host/sdhci-pxa.c: In function ?sdhci_pxa_suspend?:
> drivers/mmc/host/sdhci-pxa.c:205: warning: initialization from incompatible pointer type
> drivers/mmc/host/sdhci-pxa.c:207: error: ?state? undeclared (first use in this function)
> drivers/mmc/host/sdhci-pxa.c:207: error: (Each undeclared identifier is reported only once
> drivers/mmc/host/sdhci-pxa.c:207: error: for each function it appears in.)
> drivers/mmc/host/sdhci-pxa.c: In function ?sdhci_pxa_resume?:
> drivers/mmc/host/sdhci-pxa.c:212: warning: initialization from incompatible pointer type
> drivers/mmc/host/sdhci-pxa.c: At top level:
> drivers/mmc/host/sdhci-pxa.c:222: warning: initialization from incompatible pointer type
> drivers/mmc/host/sdhci-pxa.c:223: warning: initialization from incompatible pointer type
>
> when compiled with CONFIG_PM=y.
>
> --
> Chris Ball ? <cjb@laptop.org> ? <http://printf.net/>
> One Laptop Per Child
>
Sorry, forgot open CONFIG_PM.
Updated patch, thanks
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-22 14:09 ` zhangfei gao
@ 2010-10-23 14:24 ` Marek Vasut
2010-10-23 16:47 ` zhangfei gao
0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2010-10-23 14:24 UTC (permalink / raw)
To: linux-arm-kernel
Dne P? 22. ??jna 2010 16:09:03 zhangfei gao napsal(a):
> On Fri, Oct 22, 2010 at 7:04 AM, Chris Ball <cjb@laptop.org> wrote:
> > Hi,
> >
> > On Fri, Oct 22, 2010 at 10:58:14AM +0100, Chris Ball wrote:
> > [...]
> >
> >> +#ifdef CONFIG_PM
> >> +static int sdhci_pxa_suspend(struct platform_device *dev)
> >> +{
> >> + struct sdhci_host *host =
> >> platform_get_drvdata(to_platform_device(dev)); +
> >> + return sdhci_suspend_host(host, state);
> >> +}
> >> +
> >> +static int sdhci_pxa_resume(struct platform_device *dev)
> >> +{
> >
> > These prototypes are not correct, leading to:
> >
> > CC [M] drivers/mmc/host/sdhci-pxa.o
> > drivers/mmc/host/sdhci-pxa.c: In function ?sdhci_pxa_suspend?:
> > drivers/mmc/host/sdhci-pxa.c:205: warning: initialization from
> > incompatible pointer type drivers/mmc/host/sdhci-pxa.c:207: error:
> > ?state? undeclared (first use in this function)
> > drivers/mmc/host/sdhci-pxa.c:207: error: (Each undeclared identifier is
> > reported only once drivers/mmc/host/sdhci-pxa.c:207: error: for each
> > function it appears in.) drivers/mmc/host/sdhci-pxa.c: In function
> > ?sdhci_pxa_resume?:
> > drivers/mmc/host/sdhci-pxa.c:212: warning: initialization from
> > incompatible pointer type drivers/mmc/host/sdhci-pxa.c: At top level:
> > drivers/mmc/host/sdhci-pxa.c:222: warning: initialization from
> > incompatible pointer type drivers/mmc/host/sdhci-pxa.c:223: warning:
> > initialization from incompatible pointer type
> >
> > when compiled with CONFIG_PM=y.
> >
> > --
> > Chris Ball <cjb@laptop.org> <http://printf.net/>
> > One Laptop Per Child
>
> Sorry, forgot open CONFIG_PM.
> Updated patch, thanks
>
> From 88e7f028433fe87b211bf3d75b54261979d0d176 Mon Sep 17 00:00:00 2001
> From: Zhangfei Gao <zhangfei.gao@marvell.com>
> Date: Mon, 20 Sep 2010 10:51:28 -0400
> Subject: [PATCH] mmc: add support of sdhci-pxa driver
>
> Support Marvell PXA168/PXA910/MMP2 SD Host Controller
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
> Acked-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> ---
> arch/arm/plat-pxa/include/plat/sdhci.h | 32 ++++
> drivers/mmc/host/Kconfig | 12 ++
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-pxa.c | 254
> ++++++++++++++++++++++++++++++++ 4 files changed, 299 insertions(+), 0
> deletions(-)
> create mode 100644 arch/arm/plat-pxa/include/plat/sdhci.h
> create mode 100644 drivers/mmc/host/sdhci-pxa.c
>
> diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h
> b/arch/arm/plat-pxa/include/plat/sdhci.h
> new file mode 100644
> index 0000000..38e86ad
> --- /dev/null
> +++ b/arch/arm/plat-pxa/include/plat/sdhci.h
> @@ -0,0 +1,32 @@
> +/* linux/arch/arm/plat-pxa/include/plat/sdhci.h
> + *
> + * Copyright 2010 Marvell
> + * Zhangfei Gao <zhangfei.gao@marvell.com>
> + *
> + * PXA Platform - SDHCI platform data definitions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#ifndef __PLAT_PXA_SDHCI_H
> +#define __PLAT_PXA_SDHCI_H
> +
> +/* pxa specific flag */
> +/* Require clock free running */
> +#define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
> +
> +/**
> + * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
> + * @max_speed: The maximum speed supported.
> + * @quirks: quirks of specific device
> + * @flags: flags for platfrom requirement
> +*/
> +struct sdhci_pxa_platdata {
> + unsigned int max_speed;
> + unsigned int quirks;
> + unsigned int flags;
> +};
> +
> +#endif /* __PLAT_PXA_SDHCI_H */
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index c9c2520..c387402 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -155,6 +155,18 @@ config MMC_SDHCI_S3C
>
> If unsure, say N.
>
> +config MMC_SDHCI_PXA
> + tristate "Marvell PXA168/PXA910/MMP2 SD Host Controller support"
> + depends on ARCH_PXA || ARCH_MMP
> + select MMC_SDHCI
> + select MMC_SDHCI_IO_ACCESSORS
> + help
> + This selects the Marvell(R) PXA168/PXA910/MMP2 SD Host Controller.
> + If you have a PXA168/PXA910/MMP2 platform with SD Host Controller and a
> + card slot,say Y or M here.
> +
> + If unsure, say N.
> +
> config MMC_SDHCI_SPEAR
> tristate "SDHCI support on ST SPEAr platform"
> depends on MMC_SDHCI && PLAT_SPEAR
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 6c4ac67..7b645ff 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o
> obj-$(CONFIG_MMC_MXC) += mxcmmc.o
> obj-$(CONFIG_MMC_SDHCI) += sdhci.o
> obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
> +obj-$(CONFIG_MMC_SDHCI_PXA) += sdhci-pxa.o
> obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
> obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
> obj-$(CONFIG_MMC_WBSD) += wbsd.o
> diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c
> new file mode 100644
> index 0000000..abf208c
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-pxa.c
> @@ -0,0 +1,254 @@
> +/* linux/drivers/mmc/host/sdhci-pxa.c
> + *
> + * Copyright (C) 2010 Marvell International Ltd.
> + * Zhangfei Gao <zhangfei.gao@marvell.com>
> + * Kevin Wang <dwang4@marvell.com>
> + * Mingwei Wang <mwwang@marvell.com>
> + * Philip Rakity <prakity@marvell.com>
> + * Mark Brown <markb@marvell.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +/* Supports:
> + * SDHCI support for MMP2/PXA910/PXA168
> + *
> + * Refer sdhci-s3c.c
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/mmc/host.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <plat/sdhci.h>
> +#include "sdhci.h"
> +
> +#define DRIVER_NAME "sdhci-pxa"
> +
> +#define SD_FIFO_PARAM 0x104
> +#define DIS_PAD_SD_CLK_GATE 0x400
> +
> +struct sdhci_pxa {
> + struct sdhci_host *host;
> + struct sdhci_pxa_platdata *pdata;
> + struct clk *clk;
> + struct resource *res;
> +
> + u8 clk_enable;
> +};
> +
> +/*************************************************************************
> ****\ + *
> * + * SDHCI core callbacks
> * + *
> *
> +\************************************************************************
> *****/ +static void set_clock(struct sdhci_host *host, unsigned int clock)
> +{
> + struct sdhci_pxa *pxa = sdhci_priv(host);
> + u32 tmp = 0;
> +
> + if (clock == 0) {
> + if (pxa->clk_enable) {
> + clk_disable(pxa->clk);
> + pxa->clk_enable = 0;
> + }
> + } else {
> + if (0 == pxa->clk_enable) {
> + if (pxa->pdata->flags
> + & PXA_FLAG_DISABLE_CLOCK_GATING) {
> + tmp = readl(host->ioaddr + SD_FIFO_PARAM);
> + tmp |= DIS_PAD_SD_CLK_GATE;
> + writel(tmp, host->ioaddr + SD_FIFO_PARAM);
> + }
> + clk_enable(pxa->clk);
> + pxa->clk_enable = 1;
> + }
> + }
> +}
Doesn't the clock framework have something like clk_is_already_enabled()
function ?
> +
> +static struct sdhci_ops sdhci_pxa_ops = {
> + .set_clock = set_clock,
> +};
> +
> +/*************************************************************************
> ****\ + *
> * + * Device probing/removal
> * + *
> *
> +\************************************************************************
> *****/ +
> +static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
> +{
> + struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
> + struct device *dev = &pdev->dev;
> + struct sdhci_host *host = NULL;
> + struct resource *iomem = NULL;
> + struct sdhci_pxa *pxa = NULL;
> + int ret, irq;
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(dev, "no irq specified\n");
> + return irq;
> + }
> +
> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!iomem) {
> + dev_err(dev, "no memory specified\n");
> + return -ENOENT;
> + }
> +
> + host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
> + if (IS_ERR(host)) {
> + dev_err(dev, "failed to alloc host\n");
> + return PTR_ERR(host);
> + }
> +
> + pxa = sdhci_priv(host);
> + pxa->host = host;
> + pxa->pdata = pdata;
> + pxa->clk_enable = 0;
> +
> + pxa->clk = clk_get(dev, "PXA-SDHCLK");
> + if (IS_ERR(pxa->clk)) {
> + dev_err(dev, "failed to get io clock\n");
> + ret = PTR_ERR(pxa->clk);
> + goto out;
> + }
> +
> + pxa->res = request_mem_region(iomem->start, resource_size(iomem),
> + mmc_hostname(host->mmc));
> + if (!pxa->res) {
> + dev_err(&pdev->dev, "cannot request region\n");
> + ret = -EBUSY;
> + goto out;
> + }
> +
> + host->ioaddr = ioremap(iomem->start, resource_size(iomem));
> + if (!host->ioaddr) {
> + dev_err(&pdev->dev, "failed to remap registers\n");
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + host->hw_name = "MMC";
> + host->ops = &sdhci_pxa_ops;
> + host->irq = irq;
> + host->quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
> +
Maybe check if these aren't already set in pdata and warn user ?
> + if (pdata->quirks)
> + host->quirks |= pdata->quirks;
> +
> + ret = sdhci_add_host(host);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to add host\n");
> + goto out;
> + }
> +
> + if (pxa->pdata->max_speed)
> + host->mmc->f_max = pxa->pdata->max_speed;
What happens otherwise ?
> +
> + platform_set_drvdata(pdev, host);
> +
> + return 0;
> +out:
> + if (host) {
> + clk_put(pxa->clk);
> + if (host->ioaddr)
> + iounmap(host->ioaddr);
> + if (pxa->res)
> + release_mem_region(pxa->res->start,
> + resource_size(pxa->res));
> + sdhci_free_host(host);
> + }
> +
> + return ret;
> +}
> +
> +static int __devexit sdhci_pxa_remove(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + struct sdhci_pxa *pxa = sdhci_priv(host);
> + int dead = 0;
> + u32 scratch;
> +
> + if (host) {
> + scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
> + if (scratch == (u32)-1)
> + dead = 1;
> +
> + sdhci_remove_host(host, dead);
> +
> + if (host->ioaddr)
> + iounmap(host->ioaddr);
> + if (pxa->res)
> + release_mem_region(pxa->res->start,
> + resource_size(pxa->res));
> + if (pxa->clk_enable) {
> + clk_disable(pxa->clk);
> + pxa->clk_enable = 0;
> + }
> + clk_put(pxa->clk);
> +
> + sdhci_free_host(host);
> + platform_set_drvdata(pdev, NULL);
> + }
> +
> + return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int sdhci_pxa_suspend(struct platform_device *dev, pm_message_t
> state) +{
> + struct sdhci_host *host = platform_get_drvdata(dev);
> +
> + return sdhci_suspend_host(host, state);
> +}
> +
> +static int sdhci_pxa_resume(struct platform_device *dev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(dev);
> +
> + return sdhci_resume_host(host);
> +}
> +#else
> +#define sdhci_pxa_suspend NULL
> +#define sdhci_pxa_resume NULL
> +#endif
> +
> +static struct platform_driver sdhci_pxa_driver = {
> + .probe = sdhci_pxa_probe,
> + .remove = __devexit_p(sdhci_pxa_remove),
> + .suspend = sdhci_pxa_suspend,
> + .resume = sdhci_pxa_resume,
> + .driver = {
> + .name = DRIVER_NAME,
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +/*************************************************************************
> ****\ + *
> * + * Driver init/exit
> * + *
> *
> +\************************************************************************
> *****/ +
> +static int __init sdhci_pxa_init(void)
> +{
> + return platform_driver_register(&sdhci_pxa_driver);
> +}
> +
> +static void __exit sdhci_pxa_exit(void)
> +{
> + platform_driver_unregister(&sdhci_pxa_driver);
> +}
> +
> +module_init(sdhci_pxa_init);
> +module_exit(sdhci_pxa_exit);
> +
> +MODULE_DESCRIPTION("SDH controller driver for PXA168/PXA910/MMP2");
> +MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");
> +MODULE_LICENSE("GPL v2");
Thanks!
Cheers
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-23 14:24 ` Marek Vasut
@ 2010-10-23 16:47 ` zhangfei gao
2010-10-23 17:50 ` Marek Vasut
0 siblings, 1 reply; 13+ messages in thread
From: zhangfei gao @ 2010-10-23 16:47 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Oct 23, 2010 at 10:24 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> +/*************************************************************************
>> ****\ + *
>> ? ? ? ? * + * Device probing/removal
>> ? ? ? ? ? ? ?* + *
>> ? ? ? ? ? ? ? ? ? *
>> +\************************************************************************
>> *****/ +
>> +static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
>> +{
>> + ? ? struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
>> + ? ? struct device *dev = &pdev->dev;
>> + ? ? struct sdhci_host *host = NULL;
>> + ? ? struct resource *iomem = NULL;
>> + ? ? struct sdhci_pxa *pxa = NULL;
>> + ? ? int ret, irq;
>> +
>> + ? ? irq = platform_get_irq(pdev, 0);
>> + ? ? if (irq < 0) {
>> + ? ? ? ? ? ? dev_err(dev, "no irq specified\n");
>> + ? ? ? ? ? ? return irq;
>> + ? ? }
>> +
>> + ? ? iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + ? ? if (!iomem) {
>> + ? ? ? ? ? ? dev_err(dev, "no memory specified\n");
>> + ? ? ? ? ? ? return -ENOENT;
>> + ? ? }
>> +
>> + ? ? host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
>> + ? ? if (IS_ERR(host)) {
>> + ? ? ? ? ? ? dev_err(dev, "failed to alloc host\n");
>> + ? ? ? ? ? ? return PTR_ERR(host);
>> + ? ? }
>> +
>> + ? ? pxa = sdhci_priv(host);
>> + ? ? pxa->host = host;
>> + ? ? pxa->pdata = pdata;
>> + ? ? pxa->clk_enable = 0;
>> +
>> + ? ? pxa->clk = clk_get(dev, "PXA-SDHCLK");
>> + ? ? if (IS_ERR(pxa->clk)) {
>> + ? ? ? ? ? ? dev_err(dev, "failed to get io clock\n");
>> + ? ? ? ? ? ? ret = PTR_ERR(pxa->clk);
>> + ? ? ? ? ? ? goto out;
>> + ? ? }
>> +
>> + ? ? pxa->res = request_mem_region(iomem->start, resource_size(iomem),
>> + ? ? ? ? ? ? mmc_hostname(host->mmc));
>> + ? ? if (!pxa->res) {
>> + ? ? ? ? ? ? dev_err(&pdev->dev, "cannot request region\n");
>> + ? ? ? ? ? ? ret = -EBUSY;
>> + ? ? ? ? ? ? goto out;
>> + ? ? }
>> +
>> + ? ? host->ioaddr = ioremap(iomem->start, resource_size(iomem));
>> + ? ? if (!host->ioaddr) {
>> + ? ? ? ? ? ? dev_err(&pdev->dev, "failed to remap registers\n");
>> + ? ? ? ? ? ? ret = -ENOMEM;
>> + ? ? ? ? ? ? goto out;
>> + ? ? }
>> +
>> + ? ? host->hw_name = "MMC";
>> + ? ? host->ops = &sdhci_pxa_ops;
>> + ? ? host->irq = irq;
>> + ? ? host->quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
>> +
>
> Maybe check if these aren't already set in pdata and warn user ?
Here pdata->quirks only provide specific quirk like
SDHCI_QUIRK_BROKEN_CARD_DETECTION for on-chip device, the common quirk
is provided above.
In sdhci-s3c, host->quirks is modified here via pdata->cd_type, which
is also a good method.
Here we transfer SDHCI_QUIRK_BROKEN_CARD_DETECTION directly from pdata
since it already move to include folder.
>
>> + ? ? if (pdata->quirks)
>> + ? ? ? ? ? ? host->quirks |= pdata->quirks;
>> +
>> + ? ? ret = sdhci_add_host(host);
>> + ? ? if (ret) {
>> + ? ? ? ? ? ? dev_err(&pdev->dev, "failed to add host\n");
>> + ? ? ? ? ? ? goto out;
>> + ? ? }
>> +
>> + ? ? if (pxa->pdata->max_speed)
>> + ? ? ? ? ? ? host->mmc->f_max = pxa->pdata->max_speed;
>
> What happens otherwise ?
Otherwise, host->mmc->f_max = host->max_clk set in sdhci_add_host,
host->max_clk is 50M in 2.0 controller, and 200M in 3.0 controller, if
controller does not need to provide get_max_clock.
it's better add defalut value in else condition.
Thanks Marek for review.
>
>> +
>> + ? ? platform_set_drvdata(pdev, host);
>> +
>> + ? ? return 0;
>> +out:
>> + ? ? if (host) {
>> + ? ? ? ? ? ? clk_put(pxa->clk);
>> + ? ? ? ? ? ? if (host->ioaddr)
>> + ? ? ? ? ? ? ? ? ? ? iounmap(host->ioaddr);
>> + ? ? ? ? ? ? if (pxa->res)
>> + ? ? ? ? ? ? ? ? ? ? release_mem_region(pxa->res->start,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? resource_size(pxa->res));
>> + ? ? ? ? ? ? sdhci_free_host(host);
>> + ? ? }
>> +
>> + ? ? return ret;
>> +}
>> +
>
> Thanks!
>
> Cheers
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-23 16:47 ` zhangfei gao
@ 2010-10-23 17:50 ` Marek Vasut
2010-10-24 3:26 ` zhangfei gao
0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2010-10-23 17:50 UTC (permalink / raw)
To: linux-arm-kernel
Dne So 23. ??jna 2010 18:47:10 zhangfei gao napsal(a):
> On Sat, Oct 23, 2010 at 10:24 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
> >> +/**********************************************************************
> >> *** ****\ + *
> >> * + * Device probing/removal
> >> * + *
> >> *
> >> +\**********************************************************************
> >> ** *****/ +
> >> +static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
> >> +{
> >> + struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
> >> + struct device *dev = &pdev->dev;
> >> + struct sdhci_host *host = NULL;
> >> + struct resource *iomem = NULL;
> >> + struct sdhci_pxa *pxa = NULL;
> >> + int ret, irq;
> >> +
> >> + irq = platform_get_irq(pdev, 0);
> >> + if (irq < 0) {
> >> + dev_err(dev, "no irq specified\n");
> >> + return irq;
> >> + }
> >> +
> >> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> + if (!iomem) {
> >> + dev_err(dev, "no memory specified\n");
> >> + return -ENOENT;
> >> + }
> >> +
> >> + host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
> >> + if (IS_ERR(host)) {
> >> + dev_err(dev, "failed to alloc host\n");
> >> + return PTR_ERR(host);
> >> + }
> >> +
> >> + pxa = sdhci_priv(host);
> >> + pxa->host = host;
> >> + pxa->pdata = pdata;
> >> + pxa->clk_enable = 0;
> >> +
> >> + pxa->clk = clk_get(dev, "PXA-SDHCLK");
> >> + if (IS_ERR(pxa->clk)) {
> >> + dev_err(dev, "failed to get io clock\n");
> >> + ret = PTR_ERR(pxa->clk);
> >> + goto out;
> >> + }
> >> +
> >> + pxa->res = request_mem_region(iomem->start, resource_size(iomem),
> >> + mmc_hostname(host->mmc));
> >> + if (!pxa->res) {
> >> + dev_err(&pdev->dev, "cannot request region\n");
> >> + ret = -EBUSY;
> >> + goto out;
> >> + }
> >> +
> >> + host->ioaddr = ioremap(iomem->start, resource_size(iomem));
> >> + if (!host->ioaddr) {
> >> + dev_err(&pdev->dev, "failed to remap registers\n");
> >> + ret = -ENOMEM;
> >> + goto out;
> >> + }
> >> +
> >> + host->hw_name = "MMC";
> >> + host->ops = &sdhci_pxa_ops;
> >> + host->irq = irq;
> >> + host->quirks = SDHCI_QUIRK_BROKEN_ADMA |
> >> SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; +
> >
> > Maybe check if these aren't already set in pdata and warn user ?
>
> Here pdata->quirks only provide specific quirk like
> SDHCI_QUIRK_BROKEN_CARD_DETECTION for on-chip device, the common quirk
> is provided above.
Right, but what if the user also provides such a quirk? It's unnecessary ... and
in case the quirk was removed from here later, it'd have to be removed from
user's code too ...
> In sdhci-s3c, host->quirks is modified here via pdata->cd_type, which
> is also a good method.
> Here we transfer SDHCI_QUIRK_BROKEN_CARD_DETECTION directly from pdata
> since it already move to include folder.
>
> >> + if (pdata->quirks)
> >> + host->quirks |= pdata->quirks;
> >> +
> >> + ret = sdhci_add_host(host);
> >> + if (ret) {
> >> + dev_err(&pdev->dev, "failed to add host\n");
> >> + goto out;
> >> + }
> >> +
> >> + if (pxa->pdata->max_speed)
> >> + host->mmc->f_max = pxa->pdata->max_speed;
> >
> > What happens otherwise ?
>
> Otherwise, host->mmc->f_max = host->max_clk set in sdhci_add_host,
> host->max_clk is 50M in 2.0 controller, and 200M in 3.0 controller, if
> controller does not need to provide get_max_clock.
> it's better add defalut value in else condition.
Thanks for clearing this
>
> Thanks Marek for review.
>
> >> +
> >> + platform_set_drvdata(pdev, host);
> >> +
> >> + return 0;
> >> +out:
> >> + if (host) {
> >> + clk_put(pxa->clk);
> >> + if (host->ioaddr)
> >> + iounmap(host->ioaddr);
> >> + if (pxa->res)
> >> + release_mem_region(pxa->res->start,
> >> + resource_size(pxa->res));
> >> + sdhci_free_host(host);
> >> + }
> >> +
> >> + return ret;
> >> +}
> >> +
> >
> > Thanks!
> >
> > Cheers
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-23 17:50 ` Marek Vasut
@ 2010-10-24 3:26 ` zhangfei gao
2010-10-24 4:02 ` Marek Vasut
0 siblings, 1 reply; 13+ messages in thread
From: zhangfei gao @ 2010-10-24 3:26 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Oct 24, 2010 at 1:50 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
> Dne So 23. ??jna 2010 18:47:10 zhangfei gao napsal(a):
>> On Sat, Oct 23, 2010 at 10:24 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> >> +/**********************************************************************
>> >> *** ****\ + *
>> >> ? ? ? ? * + * Device probing/removal
>> >> ? ? ? ? ? ? ?* + *
>> >> ? ? ? ? ? ? ? ? ? *
>> >> +\**********************************************************************
>> >> ** *****/ +
>> >> +static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
>> >> +{
>> >> + ? ? struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
>> >> + ? ? struct device *dev = &pdev->dev;
>> >> + ? ? struct sdhci_host *host = NULL;
>> >> + ? ? struct resource *iomem = NULL;
>> >> + ? ? struct sdhci_pxa *pxa = NULL;
>> >> + ? ? int ret, irq;
>> >> +
>> >> + ? ? irq = platform_get_irq(pdev, 0);
>> >> + ? ? if (irq < 0) {
>> >> + ? ? ? ? ? ? dev_err(dev, "no irq specified\n");
>> >> + ? ? ? ? ? ? return irq;
>> >> + ? ? }
>> >> +
>> >> + ? ? iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> >> + ? ? if (!iomem) {
>> >> + ? ? ? ? ? ? dev_err(dev, "no memory specified\n");
>> >> + ? ? ? ? ? ? return -ENOENT;
>> >> + ? ? }
>> >> +
>> >> + ? ? host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
>> >> + ? ? if (IS_ERR(host)) {
>> >> + ? ? ? ? ? ? dev_err(dev, "failed to alloc host\n");
>> >> + ? ? ? ? ? ? return PTR_ERR(host);
>> >> + ? ? }
>> >> +
>> >> + ? ? pxa = sdhci_priv(host);
>> >> + ? ? pxa->host = host;
>> >> + ? ? pxa->pdata = pdata;
>> >> + ? ? pxa->clk_enable = 0;
>> >> +
>> >> + ? ? pxa->clk = clk_get(dev, "PXA-SDHCLK");
>> >> + ? ? if (IS_ERR(pxa->clk)) {
>> >> + ? ? ? ? ? ? dev_err(dev, "failed to get io clock\n");
>> >> + ? ? ? ? ? ? ret = PTR_ERR(pxa->clk);
>> >> + ? ? ? ? ? ? goto out;
>> >> + ? ? }
>> >> +
>> >> + ? ? pxa->res = request_mem_region(iomem->start, resource_size(iomem),
>> >> + ? ? ? ? ? ? mmc_hostname(host->mmc));
>> >> + ? ? if (!pxa->res) {
>> >> + ? ? ? ? ? ? dev_err(&pdev->dev, "cannot request region\n");
>> >> + ? ? ? ? ? ? ret = -EBUSY;
>> >> + ? ? ? ? ? ? goto out;
>> >> + ? ? }
>> >> +
>> >> + ? ? host->ioaddr = ioremap(iomem->start, resource_size(iomem));
>> >> + ? ? if (!host->ioaddr) {
>> >> + ? ? ? ? ? ? dev_err(&pdev->dev, "failed to remap registers\n");
>> >> + ? ? ? ? ? ? ret = -ENOMEM;
>> >> + ? ? ? ? ? ? goto out;
>> >> + ? ? }
>> >> +
>> >> + ? ? host->hw_name = "MMC";
>> >> + ? ? host->ops = &sdhci_pxa_ops;
>> >> + ? ? host->irq = irq;
>> >> + ? ? host->quirks = SDHCI_QUIRK_BROKEN_ADMA |
>> >> SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; +
>> >
>> > Maybe check if these aren't already set in pdata and warn user ?
>>
>> Here pdata->quirks only provide specific quirk like
>> SDHCI_QUIRK_BROKEN_CARD_DETECTION for on-chip device, the common quirk
>> is provided above.
>
> Right, but what if the user also provides such a quirk? It's unnecessary ... and
> in case the quirk was removed from here later, it'd have to be removed from
> user's code too ...
What do you mean 'in case the quirk was removed from here later'.
SDHCI_QUIRK_* is just move from drivers/mmc/host/sdhci.h to
include/linux/mmc/sdhci.h, so code in arch/arm could access them
directly.
We also consider use one flag here, like sdhci-s3c.c.
Code like this,
if (pdata->flags & PXA_FLAG_CARD_PERMENT)
host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
If SDHCI_QUIRK_* not permitted to access, it would be better to use this method.
>
>> In sdhci-s3c, host->quirks is modified here via pdata->cd_type, which
>> is also a good method.
>> Here we transfer SDHCI_QUIRK_BROKEN_CARD_DETECTION directly from pdata
>> since it already move to include folder.
>>
>> >> + ? ? if (pdata->quirks)
>> >> + ? ? ? ? ? ? host->quirks |= pdata->quirks;
>> >> +
>> >> + ? ? ret = sdhci_add_host(host);
>> >> + ? ? if (ret) {
>> >> + ? ? ? ? ? ? dev_err(&pdev->dev, "failed to add host\n");
>> >> + ? ? ? ? ? ? goto out;
>> >> + ? ? }
>> >> +
>> >> + ? ? if (pxa->pdata->max_speed)
>> >> + ? ? ? ? ? ? host->mmc->f_max = pxa->pdata->max_speed;
>> >
>> > What happens otherwise ?
>>
>> Otherwise, host->mmc->f_max = host->max_clk set in sdhci_add_host,
>> host->max_clk is 50M in 2.0 controller, and 200M in 3.0 controller, if
>> controller does not need to provide get_max_clock.
>> it's better add defalut value in else condition.
>
> Thanks for clearing this
>>
>> Thanks Marek for review.
>>
>> >> +
>> >> + ? ? platform_set_drvdata(pdev, host);
>> >> +
>> >> + ? ? return 0;
>> >> +out:
>> >> + ? ? if (host) {
>> >> + ? ? ? ? ? ? clk_put(pxa->clk);
>> >> + ? ? ? ? ? ? if (host->ioaddr)
>> >> + ? ? ? ? ? ? ? ? ? ? iounmap(host->ioaddr);
>> >> + ? ? ? ? ? ? if (pxa->res)
>> >> + ? ? ? ? ? ? ? ? ? ? release_mem_region(pxa->res->start,
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? resource_size(pxa->res));
>> >> + ? ? ? ? ? ? sdhci_free_host(host);
>> >> + ? ? }
>> >> +
>> >> + ? ? return ret;
>> >> +}
>> >> +
>> >
>> > Thanks!
>> >
>> > Cheers
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-24 3:26 ` zhangfei gao
@ 2010-10-24 4:02 ` Marek Vasut
2010-10-25 5:48 ` zhangfei gao
0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2010-10-24 4:02 UTC (permalink / raw)
To: linux-arm-kernel
Dne Ne 24. ??jna 2010 05:26:38 zhangfei gao napsal(a):
> On Sun, Oct 24, 2010 at 1:50 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
> > Dne So 23. ??jna 2010 18:47:10 zhangfei gao napsal(a):
> >> On Sat, Oct 23, 2010 at 10:24 PM, Marek Vasut <marek.vasut@gmail.com>
wrote:
> >> >> +/*******************************************************************
> >> >> *** *** ****\ + *
> >> >> * + * Device probing/removal
> >> >> * + *
> >> >> *
> >> >> +\*******************************************************************
> >> >> *** ** *****/ +
> >> >> +static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
> >> >> +{
> >> >> + struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
> >> >> + struct device *dev = &pdev->dev;
> >> >> + struct sdhci_host *host = NULL;
> >> >> + struct resource *iomem = NULL;
> >> >> + struct sdhci_pxa *pxa = NULL;
> >> >> + int ret, irq;
> >> >> +
> >> >> + irq = platform_get_irq(pdev, 0);
> >> >> + if (irq < 0) {
> >> >> + dev_err(dev, "no irq specified\n");
> >> >> + return irq;
> >> >> + }
> >> >> +
> >> >> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> >> + if (!iomem) {
> >> >> + dev_err(dev, "no memory specified\n");
> >> >> + return -ENOENT;
> >> >> + }
> >> >> +
> >> >> + host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
> >> >> + if (IS_ERR(host)) {
> >> >> + dev_err(dev, "failed to alloc host\n");
> >> >> + return PTR_ERR(host);
> >> >> + }
> >> >> +
> >> >> + pxa = sdhci_priv(host);
> >> >> + pxa->host = host;
> >> >> + pxa->pdata = pdata;
> >> >> + pxa->clk_enable = 0;
> >> >> +
> >> >> + pxa->clk = clk_get(dev, "PXA-SDHCLK");
> >> >> + if (IS_ERR(pxa->clk)) {
> >> >> + dev_err(dev, "failed to get io clock\n");
> >> >> + ret = PTR_ERR(pxa->clk);
> >> >> + goto out;
> >> >> + }
> >> >> +
> >> >> + pxa->res = request_mem_region(iomem->start,
> >> >> resource_size(iomem), + mmc_hostname(host->mmc));
> >> >> + if (!pxa->res) {
> >> >> + dev_err(&pdev->dev, "cannot request region\n");
> >> >> + ret = -EBUSY;
> >> >> + goto out;
> >> >> + }
> >> >> +
> >> >> + host->ioaddr = ioremap(iomem->start, resource_size(iomem));
> >> >> + if (!host->ioaddr) {
> >> >> + dev_err(&pdev->dev, "failed to remap registers\n");
> >> >> + ret = -ENOMEM;
> >> >> + goto out;
> >> >> + }
> >> >> +
> >> >> + host->hw_name = "MMC";
> >> >> + host->ops = &sdhci_pxa_ops;
> >> >> + host->irq = irq;
> >> >> + host->quirks = SDHCI_QUIRK_BROKEN_ADMA |
> >> >> SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; +
> >> >
> >> > Maybe check if these aren't already set in pdata and warn user ?
> >>
> >> Here pdata->quirks only provide specific quirk like
> >> SDHCI_QUIRK_BROKEN_CARD_DETECTION for on-chip device, the common quirk
> >> is provided above.
> >
> > Right, but what if the user also provides such a quirk? It's unnecessary
> > ... and in case the quirk was removed from here later, it'd have to be
> > removed from user's code too ...
>
> What do you mean 'in case the quirk was removed from here later'.
I mean ... if setting the quirk was removed from the driver source, it'd have to
be removed from user code that uses the driver as well -- in case user also set
such a quirk in pdata->quirks. So it might be a good idea to warn user that he's
setting something that's getting set elsewhere (in the driver) anyway.
> SDHCI_QUIRK_* is just move from drivers/mmc/host/sdhci.h to
> include/linux/mmc/sdhci.h, so code in arch/arm could access them
> directly.
>
> We also consider use one flag here, like sdhci-s3c.c.
> Code like this,
> if (pdata->flags & PXA_FLAG_CARD_PERMENT)
> host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
>
> If SDHCI_QUIRK_* not permitted to access, it would be better to use this
> method.
>
> >> In sdhci-s3c, host->quirks is modified here via pdata->cd_type, which
> >> is also a good method.
> >> Here we transfer SDHCI_QUIRK_BROKEN_CARD_DETECTION directly from pdata
> >> since it already move to include folder.
> >>
> >> >> + if (pdata->quirks)
> >> >> + host->quirks |= pdata->quirks;
> >> >> +
> >> >> + ret = sdhci_add_host(host);
> >> >> + if (ret) {
> >> >> + dev_err(&pdev->dev, "failed to add host\n");
> >> >> + goto out;
> >> >> + }
> >> >> +
> >> >> + if (pxa->pdata->max_speed)
> >> >> + host->mmc->f_max = pxa->pdata->max_speed;
> >> >
> >> > What happens otherwise ?
> >>
> >> Otherwise, host->mmc->f_max = host->max_clk set in sdhci_add_host,
> >> host->max_clk is 50M in 2.0 controller, and 200M in 3.0 controller, if
> >> controller does not need to provide get_max_clock.
> >> it's better add defalut value in else condition.
> >
> > Thanks for clearing this
> >
> >> Thanks Marek for review.
> >>
> >> >> +
> >> >> + platform_set_drvdata(pdev, host);
> >> >> +
> >> >> + return 0;
> >> >> +out:
> >> >> + if (host) {
> >> >> + clk_put(pxa->clk);
> >> >> + if (host->ioaddr)
> >> >> + iounmap(host->ioaddr);
> >> >> + if (pxa->res)
> >> >> + release_mem_region(pxa->res->start,
> >> >> + resource_size(pxa->res));
> >> >> + sdhci_free_host(host);
> >> >> + }
> >> >> +
> >> >> + return ret;
> >> >> +}
> >> >> +
> >> >
> >> > Thanks!
> >> >
> >> > Cheers
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 1/1]MMC: add support of sdhci-pxa driver
2010-10-24 4:02 ` Marek Vasut
@ 2010-10-25 5:48 ` zhangfei gao
0 siblings, 0 replies; 13+ messages in thread
From: zhangfei gao @ 2010-10-25 5:48 UTC (permalink / raw)
To: linux-arm-kernel
2010/10/24 Marek Vasut <marek.vasut@gmail.com>:
> Dne Ne 24. ??jna 2010 05:26:38 zhangfei gao napsal(a):
>> On Sun, Oct 24, 2010 at 1:50 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> > Dne So 23. ??jna 2010 18:47:10 zhangfei gao napsal(a):
>> >> On Sat, Oct 23, 2010 at 10:24 PM, Marek Vasut <marek.vasut@gmail.com>
> wrote:
>> >> >> +/*******************************************************************
>> >> >> *** *** ****\ + *
>> >> >> ? ? ? ? * + * Device probing/removal
>> >> >> ? ? ? ? ? ? ?* + *
>> >> >> ? ? ? ? ? ? ? ? ? *
>> >> >> +\*******************************************************************
>> >> >> *** ** *****/ +
>> >> >> +static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
>> >> >> +{
>> >> >> + ? ? struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
>> >> >> + ? ? struct device *dev = &pdev->dev;
>> >> >> + ? ? struct sdhci_host *host = NULL;
>> >> >> + ? ? struct resource *iomem = NULL;
>> >> >> + ? ? struct sdhci_pxa *pxa = NULL;
>> >> >> + ? ? int ret, irq;
>> >> >> +
>> >> >> + ? ? irq = platform_get_irq(pdev, 0);
>> >> >> + ? ? if (irq < 0) {
>> >> >> + ? ? ? ? ? ? dev_err(dev, "no irq specified\n");
>> >> >> + ? ? ? ? ? ? return irq;
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> >> >> + ? ? if (!iomem) {
>> >> >> + ? ? ? ? ? ? dev_err(dev, "no memory specified\n");
>> >> >> + ? ? ? ? ? ? return -ENOENT;
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pxa));
>> >> >> + ? ? if (IS_ERR(host)) {
>> >> >> + ? ? ? ? ? ? dev_err(dev, "failed to alloc host\n");
>> >> >> + ? ? ? ? ? ? return PTR_ERR(host);
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? pxa = sdhci_priv(host);
>> >> >> + ? ? pxa->host = host;
>> >> >> + ? ? pxa->pdata = pdata;
>> >> >> + ? ? pxa->clk_enable = 0;
>> >> >> +
>> >> >> + ? ? pxa->clk = clk_get(dev, "PXA-SDHCLK");
>> >> >> + ? ? if (IS_ERR(pxa->clk)) {
>> >> >> + ? ? ? ? ? ? dev_err(dev, "failed to get io clock\n");
>> >> >> + ? ? ? ? ? ? ret = PTR_ERR(pxa->clk);
>> >> >> + ? ? ? ? ? ? goto out;
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? pxa->res = request_mem_region(iomem->start,
>> >> >> resource_size(iomem), + ? ? ? ? ? ? mmc_hostname(host->mmc));
>> >> >> + ? ? if (!pxa->res) {
>> >> >> + ? ? ? ? ? ? dev_err(&pdev->dev, "cannot request region\n");
>> >> >> + ? ? ? ? ? ? ret = -EBUSY;
>> >> >> + ? ? ? ? ? ? goto out;
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? host->ioaddr = ioremap(iomem->start, resource_size(iomem));
>> >> >> + ? ? if (!host->ioaddr) {
>> >> >> + ? ? ? ? ? ? dev_err(&pdev->dev, "failed to remap registers\n");
>> >> >> + ? ? ? ? ? ? ret = -ENOMEM;
>> >> >> + ? ? ? ? ? ? goto out;
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? host->hw_name = "MMC";
>> >> >> + ? ? host->ops = &sdhci_pxa_ops;
>> >> >> + ? ? host->irq = irq;
>> >> >> + ? ? host->quirks = SDHCI_QUIRK_BROKEN_ADMA |
>> >> >> SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; +
>> >> >
>> >> > Maybe check if these aren't already set in pdata and warn user ?
>> >>
>> >> Here pdata->quirks only provide specific quirk like
>> >> SDHCI_QUIRK_BROKEN_CARD_DETECTION for on-chip device, the common quirk
>> >> is provided above.
>> >
>> > Right, but what if the user also provides such a quirk? It's unnecessary
>> > ... and in case the quirk was removed from here later, it'd have to be
>> > removed from user's code too ...
>>
>> What do you mean 'in case the quirk was removed from here later'.
>
> I mean ... if setting the quirk was removed from the driver source, it'd have to
> be removed from user code that uses the driver as well -- in case user also set
> such a quirk in pdata->quirks. So it might be a good idea to warn user that he's
> setting something that's getting set elsewhere (in the driver) anyway.
Thanks for suggestion, but I think it is OK here.
In our design, driver set common limitation quirk, and pdata set
specific quirk for some device.
>
>> SDHCI_QUIRK_* is just move from drivers/mmc/host/sdhci.h to
>> include/linux/mmc/sdhci.h, so code in arch/arm could access them
>> directly.
>>
>> We also consider use one flag here, like sdhci-s3c.c.
>> Code like this,
>> if (pdata->flags & PXA_FLAG_CARD_PERMENT)
>> ? ? ?host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
>>
>> If SDHCI_QUIRK_* not permitted to access, it would be better to use this
>> method.
>>
>> >> In sdhci-s3c, host->quirks is modified here via pdata->cd_type, which
>> >> is also a good method.
>> >> Here we transfer SDHCI_QUIRK_BROKEN_CARD_DETECTION directly from pdata
>> >> since it already move to include folder.
>> >>
>> >> >> + ? ? if (pdata->quirks)
>> >> >> + ? ? ? ? ? ? host->quirks |= pdata->quirks;
>> >> >> +
>> >> >> + ? ? ret = sdhci_add_host(host);
>> >> >> + ? ? if (ret) {
>> >> >> + ? ? ? ? ? ? dev_err(&pdev->dev, "failed to add host\n");
>> >> >> + ? ? ? ? ? ? goto out;
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? if (pxa->pdata->max_speed)
>> >> >> + ? ? ? ? ? ? host->mmc->f_max = pxa->pdata->max_speed;
>> >> >
>> >> > What happens otherwise ?
>> >>
>> >> Otherwise, host->mmc->f_max = host->max_clk set in sdhci_add_host,
>> >> host->max_clk is 50M in 2.0 controller, and 200M in 3.0 controller, if
>> >> controller does not need to provide get_max_clock.
>> >> it's better add defalut value in else condition.
>> >
>> > Thanks for clearing this
>> >
>> >> Thanks Marek for review.
>> >>
>> >> >> +
>> >> >> + ? ? platform_set_drvdata(pdev, host);
>> >> >> +
>> >> >> + ? ? return 0;
>> >> >> +out:
>> >> >> + ? ? if (host) {
>> >> >> + ? ? ? ? ? ? clk_put(pxa->clk);
>> >> >> + ? ? ? ? ? ? if (host->ioaddr)
>> >> >> + ? ? ? ? ? ? ? ? ? ? iounmap(host->ioaddr);
>> >> >> + ? ? ? ? ? ? if (pxa->res)
>> >> >> + ? ? ? ? ? ? ? ? ? ? release_mem_region(pxa->res->start,
>> >> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? resource_size(pxa->res));
>> >> >> + ? ? ? ? ? ? sdhci_free_host(host);
>> >> >> + ? ? }
>> >> >> +
>> >> >> + ? ? return ret;
>> >> >> +}
>> >> >> +
>> >> >
>> >> > Thanks!
>> >> >
>> >> > Cheers
>
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-10-25 5:48 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <AANLkTikivxhU6Lzxe0Xn9r9hOSPLwuySRkTdGif4F_xo@mail.gmail.com>
[not found] ` <20101021141302.GA11912@void.printf.net>
2010-10-21 14:52 ` [PATCH V3 1/1]MMC: add support of sdhci-pxa driver Chris Ball
2010-10-22 0:20 ` Marek Vasut
2010-10-22 0:27 ` Chris Ball
2010-10-22 8:44 ` Haojian Zhuang
2010-10-22 9:58 ` Chris Ball
2010-10-22 11:04 ` Chris Ball
2010-10-22 14:09 ` zhangfei gao
2010-10-23 14:24 ` Marek Vasut
2010-10-23 16:47 ` zhangfei gao
2010-10-23 17:50 ` Marek Vasut
2010-10-24 3:26 ` zhangfei gao
2010-10-24 4:02 ` Marek Vasut
2010-10-25 5:48 ` zhangfei gao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).