All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-06-22 14:09 Saeed Bishara
  2010-06-23 11:52 ` Matt Fleming
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Saeed Bishara @ 2010-06-22 14:09 UTC (permalink / raw)
  To: linux-mmc; +Cc: saeed.bishara, Saeed Bishara

This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.

Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
 drivers/mmc/host/Kconfig    |   12 ++
 drivers/mmc/host/Makefile   |    1 +
 drivers/mmc/host/sdhci-mv.c |  243 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-mv.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index f06d06e..a33bc29 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -121,6 +121,18 @@ config MMC_SDHCI_PLTFM
 
 	  If unsure, say N.
 
+config MMC_SDHCI_MV
+	tristate "SDHCI support on Marvell's soc"
+	depends on MMC_SDHCI
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Secure Digital Host Controller Interface in
+	  Marvell's SoC controllers.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_S3C
 	tristate "SDHCI support on Samsung S3C SoC"
 	depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX)
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e30c2ee..2061fbd 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PLTFM)	+= sdhci-pltfm.o
+obj-$(CONFIG_MMC_SDHCI_MV)	+= sdhci-mv.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-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 0000000..86951ef
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,243 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on  sdhci-pltfm.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_mv_host {
+#if defined(CONFIG_HAVE_CLK)
+	struct clk		*clk;
+#endif
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * SDHCI core callbacks                                                      *
+ *                                                                           *
+\*****************************************************************************/
+static u16 mv_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	switch (reg) {
+	case SDHCI_HOST_VERSION:
+	case SDHCI_SLOT_INT_STATUS:
+		/* those registers don't exist */
+		return 0;
+	default:
+		ret = readw(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static u32 mv_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	switch (reg) {
+	case SDHCI_CAPABILITIES:
+		ret = readl(host->ioaddr + reg);
+		/* Mask the support for 3.0V */
+		ret &= ~SDHCI_CAN_VDD_300;
+		break;
+	default:
+		ret = readl(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+	.read_w	= mv_readw,
+	.read_l	= mv_readl,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Device probing/removal                                                    *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __devinit sdhci_mv_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct sdhci_mv_host *mv_host;
+	struct resource *iomem;
+	int ret;
+
+	BUG_ON(pdev == NULL);
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	if (resource_size(iomem) != 0x100)
+		dev_err(&pdev->dev, "Invalid iomem size. You may "
+			"experience problems.\n");
+
+	if (pdev->dev.parent)
+		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*mv_host));
+	else
+		host = sdhci_alloc_host(&pdev->dev, sizeof(*mv_host));
+
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err;
+	}
+
+	mv_host = sdhci_priv(host);
+	host->hw_name = "marvell-sdhci";
+	host->ops = &sdhci_mv_ops;
+	host->irq = platform_get_irq(pdev, 0);
+	host->quirks =  SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+			SDHCI_QUIRK_NO_BUSY_IRQ |
+			SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+			SDHCI_QUIRK_FORCE_DMA;
+
+	if (!devm_request_mem_region(&pdev->dev, iomem->start,
+				     resource_size(iomem),
+				     mmc_hostname(host->mmc))) {
+		dev_err(&pdev->dev, "cannot request region\n");
+		ret = -EBUSY;
+		goto err_request;
+	}
+
+	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
+				    resource_size(iomem));
+	if (!host->ioaddr) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
+		goto err_request;
+	}
+
+#if defined(CONFIG_HAVE_CLK)
+	mv_host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mv_host->clk))
+		dev_notice(&pdev->dev, "cannot get clkdev\n");
+	else
+		clk_enable(mv_host->clk);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_request;
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+
+err_request:
+	sdhci_free_host(host);
+err:
+	printk(KERN_ERR"Probing of sdhci-mv failed: %d\n", ret);
+	return ret;
+}
+
+static int __devexit sdhci_mv_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+#if defined(CONFIG_HAVE_CLK)
+	struct sdhci_mv_host *mv_host = sdhci_priv(host);
+	struct clk *clk = mv_host->clk;
+#endif
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+
+	sdhci_remove_host(host, dead);
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+#if defined(CONFIG_HAVE_CLK)
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	}
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdhci_mv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_suspend_host(host, state);
+}
+
+static int sdhci_mv_resume(struct platform_device *pdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_resume_host(host);
+}
+#else
+#define sdhci_mv_suspend NULL
+#define sdhci_mv_resume NULL
+#endif
+
+static struct platform_driver sdhci_mv_driver = {
+	.driver = {
+		.name	= "sdhci-mv",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sdhci_mv_probe,
+	.remove		= __devexit_p(sdhci_mv_remove),
+	.suspend	= sdhci_mv_suspend,
+	.resume		= sdhci_mv_resume,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init sdhci_mv_init(void)
+{
+	return platform_driver_register(&sdhci_mv_driver);
+}
+
+static void __exit sdhci_mv_exit(void)
+{
+	platform_driver_unregister(&sdhci_mv_driver);
+}
+
+module_init(sdhci_mv_init);
+module_exit(sdhci_mv_exit);
+
+MODULE_DESCRIPTION("Marvell SDHCI platform driver");
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sdhci-mv");
+
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-06-22 14:09 [PATCH] MMC: add support for the Marvell platform SDHCI controller Saeed Bishara
@ 2010-06-23 11:52 ` Matt Fleming
  2010-06-23 12:11   ` saeed bishara
  2010-08-25 22:39 ` Matt Fleming
  2010-09-10 20:16 ` Chris Ball
  2 siblings, 1 reply; 18+ messages in thread
From: Matt Fleming @ 2010-06-23 11:52 UTC (permalink / raw)
  To: Saeed Bishara; +Cc: saeed.bishara, linux-mmc

On Tue, 22 Jun 2010 17:09:02 +0300, Saeed Bishara <saeed@marvell.com> wrote:
> This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.
> 
> Signed-off-by: Saeed Bishara <saeed@marvell.com>

That's a nice, small driver ;-)

[...]

> +
> +	if (!devm_request_mem_region(&pdev->dev, iomem->start,
> +				     resource_size(iomem),
> +				     mmc_hostname(host->mmc))) {
> +		dev_err(&pdev->dev, "cannot request region\n");
> +		ret = -EBUSY;
> +		goto err_request;
> +	}
> +
> +	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
> +				    resource_size(iomem));
> +	if (!host->ioaddr) {
> +		dev_err(&pdev->dev, "failed to remap registers\n");
> +		ret = -ENOMEM;
> +		goto err_request;
> +	}

If you fail to remap the registers shouldn't you release the mem_region
you've allocated above?

> +
> +#if defined(CONFIG_HAVE_CLK)
> +	mv_host->clk = clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(mv_host->clk))
> +		dev_notice(&pdev->dev, "cannot get clkdev\n");
> +	else
> +		clk_enable(mv_host->clk);
> +#endif
> +
> +	ret = sdhci_add_host(host);
> +	if (ret)
> +		goto err_request;

Likewise here, I think you should be iounmap()'ing the registers if this
fails. Otherwise this looks good.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-06-23 11:52 ` Matt Fleming
@ 2010-06-23 12:11   ` saeed bishara
  2010-06-23 14:06     ` Matt Fleming
  0 siblings, 1 reply; 18+ messages in thread
From: saeed bishara @ 2010-06-23 12:11 UTC (permalink / raw)
  To: Matt Fleming; +Cc: Saeed Bishara, linux-mmc

On Wed, Jun 23, 2010 at 2:52 PM, Matt Fleming <matt@console-pimps.org> wrote:
> On Tue, 22 Jun 2010 17:09:02 +0300, Saeed Bishara <saeed@marvell.com> wrote:
>> This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.
>>
>> Signed-off-by: Saeed Bishara <saeed@marvell.com>
>
> That's a nice, small driver ;-)
>
> [...]
>
>> +
>> +     if (!devm_request_mem_region(&pdev->dev, iomem->start,
>> +                                  resource_size(iomem),
>> +                                  mmc_hostname(host->mmc))) {
>> +             dev_err(&pdev->dev, "cannot request region\n");
>> +             ret = -EBUSY;
>> +             goto err_request;
>> +     }
>> +
>> +     host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
>> +                                 resource_size(iomem));
>> +     if (!host->ioaddr) {
>> +             dev_err(&pdev->dev, "failed to remap registers\n");
>> +             ret = -ENOMEM;
>> +             goto err_request;
>> +     }
>
> If you fail to remap the registers shouldn't you release the mem_region
> you've allocated above?
the point behind the devm_ (device managed) resouce allocation is not
to do the free explicitly, the kernel does that on behalf of the
driver.
>
>> +
>> +#if defined(CONFIG_HAVE_CLK)
>> +     mv_host->clk = clk_get(&pdev->dev, NULL);
>> +     if (IS_ERR(mv_host->clk))
>> +             dev_notice(&pdev->dev, "cannot get clkdev\n");
>> +     else
>> +             clk_enable(mv_host->clk);
>> +#endif
>> +
>> +     ret = sdhci_add_host(host);
>> +     if (ret)
>> +             goto err_request;
>
> Likewise here, I think you should be iounmap()'ing the registers if this
> fails. Otherwise this looks good.
ditto
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI  controller
  2010-06-23 12:11   ` saeed bishara
@ 2010-06-23 14:06     ` Matt Fleming
  0 siblings, 0 replies; 18+ messages in thread
From: Matt Fleming @ 2010-06-23 14:06 UTC (permalink / raw)
  To: saeed bishara; +Cc: Saeed Bishara, linux-mmc

On Wed, 23 Jun 2010 15:11:04 +0300, saeed bishara <saeed.bishara@gmail.com> wrote:
> the point behind the devm_ (device managed) resouce allocation is not
> to do the free explicitly, the kernel does that on behalf of the
> driver.

Oops, sorry I missed that. I must have been hungry, it was near lunchtime.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-06-22 14:09 [PATCH] MMC: add support for the Marvell platform SDHCI controller Saeed Bishara
  2010-06-23 11:52 ` Matt Fleming
@ 2010-08-25 22:39 ` Matt Fleming
  2010-08-25 23:16   ` Andrew Morton
  2010-09-10 20:16 ` Chris Ball
  2 siblings, 1 reply; 18+ messages in thread
From: Matt Fleming @ 2010-08-25 22:39 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mmc, saeed.bishara, Saeed Bishara

On Tue, 22 Jun 2010 17:09:02 +0300
Saeed Bishara <saeed@marvell.com> wrote:

> This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.
> 
> Signed-off-by: Saeed Bishara <saeed@marvell.com>
> ---
>  drivers/mmc/host/Kconfig    |   12 ++
>  drivers/mmc/host/Makefile   |    1 +
>  drivers/mmc/host/sdhci-mv.c |  243 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 256 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mmc/host/sdhci-mv.c

Andrew, any reason this hasn't been picked up? (I noticed you weren't
on the CC).

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-08-25 22:39 ` Matt Fleming
@ 2010-08-25 23:16   ` Andrew Morton
  0 siblings, 0 replies; 18+ messages in thread
From: Andrew Morton @ 2010-08-25 23:16 UTC (permalink / raw)
  To: Matt Fleming; +Cc: linux-mmc, saeed.bishara, Saeed Bishara

On Wed, 25 Aug 2010 23:39:58 +0100
Matt Fleming <matt@console-pimps.org> wrote:

> On Tue, 22 Jun 2010 17:09:02 +0300
> Saeed Bishara <saeed@marvell.com> wrote:
> 
> > This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.
> > 
> > Signed-off-by: Saeed Bishara <saeed@marvell.com>
> > ---
> >  drivers/mmc/host/Kconfig    |   12 ++
> >  drivers/mmc/host/Makefile   |    1 +
> >  drivers/mmc/host/sdhci-mv.c |  243 +++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 256 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/mmc/host/sdhci-mv.c
> 
> Andrew, any reason this hasn't been picked up?

I must have been hungry, it was near lunchtime. :)

> (I noticed you weren't on the CC).

That too.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-06-22 14:09 [PATCH] MMC: add support for the Marvell platform SDHCI controller Saeed Bishara
  2010-06-23 11:52 ` Matt Fleming
  2010-08-25 22:39 ` Matt Fleming
@ 2010-09-10 20:16 ` Chris Ball
  2 siblings, 0 replies; 18+ messages in thread
From: Chris Ball @ 2010-09-10 20:16 UTC (permalink / raw)
  To: Saeed Bishara; +Cc: linux-mmc, saeed.bishara

Hi Saeed,

On Tue, Jun 22, 2010 at 05:09:02PM +0300, Saeed Bishara wrote:
> This patch implements the driver for the platfrom SDHCI controllers
> that found on some of Marvell's SoC's.

Applied to mmc-next with some minor language fixes, thanks.

-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-10-27  8:46   ` Saeed Bishara
@ 2010-10-27  9:17     ` Mike Rapoport
  -1 siblings, 0 replies; 18+ messages in thread
From: Mike Rapoport @ 2010-10-27  9:17 UTC (permalink / raw)
  To: Saeed Bishara; +Cc: linux-mmc, linux-arm-kernel

On 10/27/10 10:46, Saeed Bishara wrote:
>  
>  
>> +config MMC_SDHCI_MV
>> +	bool "SDHCI support on Marvell's SoC"
>> +	depends on MMC_SDHCI
>> +	depends on MMC_SDHCI_PLTFM
>> +	select MMC_SDHCI_IO_ACCESSORS
>> +	help
>> +	  This selects the Secure Digital Host Controller Interface in
>> +	  Marvell's SoC controllers.
>> +
>> +	  If you have a controller with this interface, say Y or M here.
>> +
>> +	  If unsure, say N.
>> +
> Mike, the config name and description is too generic as there are several sdhci
> controllers on Marvell devices (see like pxa), I suggest to name it SDHCI_DOVE
> and make it depends on ARCH_DOVE and modify the description accordingly.

No problem. That said, no ARCH_MPP for now, like it was in [1]?

[1] http://marc.info/?l=linux-kernel&m=128458441031769&q=raw


>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/io.h>
>> +#include <linux/mmc/host.h>
>> +#include "sdhci.h"
>> +#include "sdhci-pltfm.h"
> are those includes are realy needed? At least the delay.h and clk.h not needed for now.
> 
> saeed


-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-10-27  9:17     ` Mike Rapoport
  0 siblings, 0 replies; 18+ messages in thread
From: Mike Rapoport @ 2010-10-27  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/27/10 10:46, Saeed Bishara wrote:
>  
>  
>> +config MMC_SDHCI_MV
>> +	bool "SDHCI support on Marvell's SoC"
>> +	depends on MMC_SDHCI
>> +	depends on MMC_SDHCI_PLTFM
>> +	select MMC_SDHCI_IO_ACCESSORS
>> +	help
>> +	  This selects the Secure Digital Host Controller Interface in
>> +	  Marvell's SoC controllers.
>> +
>> +	  If you have a controller with this interface, say Y or M here.
>> +
>> +	  If unsure, say N.
>> +
> Mike, the config name and description is too generic as there are several sdhci
> controllers on Marvell devices (see like pxa), I suggest to name it SDHCI_DOVE
> and make it depends on ARCH_DOVE and modify the description accordingly.

No problem. That said, no ARCH_MPP for now, like it was in [1]?

[1] http://marc.info/?l=linux-kernel&m=128458441031769&q=raw


>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/io.h>
>> +#include <linux/mmc/host.h>
>> +#include "sdhci.h"
>> +#include "sdhci-pltfm.h"
> are those includes are realy needed? At least the delay.h and clk.h not needed for now.
> 
> saeed


-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-10-27  8:07 ` Mike Rapoport
@ 2010-10-27  9:10   ` Chris Ball
  -1 siblings, 0 replies; 18+ messages in thread
From: Chris Ball @ 2010-10-27  9:10 UTC (permalink / raw)
  To: Mike Rapoport; +Cc: linux-mmc, linux-arm-kernel, Saeed Bishara

Hi Mike,

I concur with Saeed, and please also fold this patch into the submission:

   http://marc.info/?l=linux-kernel&m=128458441031769&q=raw

Thanks!

-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-10-27  9:10   ` Chris Ball
  0 siblings, 0 replies; 18+ messages in thread
From: Chris Ball @ 2010-10-27  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mike,

I concur with Saeed, and please also fold this patch into the submission:

   http://marc.info/?l=linux-kernel&m=128458441031769&q=raw

Thanks!

-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-10-27  8:07 ` Mike Rapoport
@ 2010-10-27  8:46   ` Saeed Bishara
  -1 siblings, 0 replies; 18+ messages in thread
From: Saeed Bishara @ 2010-10-27  8:46 UTC (permalink / raw)
  To: Mike Rapoport, linux-mmc; +Cc: linux-arm-kernel

 
 
>+config MMC_SDHCI_MV
>+	bool "SDHCI support on Marvell's SoC"
>+	depends on MMC_SDHCI
>+	depends on MMC_SDHCI_PLTFM
>+	select MMC_SDHCI_IO_ACCESSORS
>+	help
>+	  This selects the Secure Digital Host Controller Interface in
>+	  Marvell's SoC controllers.
>+
>+	  If you have a controller with this interface, say Y or M here.
>+
>+	  If unsure, say N.
>+
Mike, the config name and description is too generic as there are several sdhci controllers on Marvell devices (see like pxa), I suggest to name it SDHCI_DOVE and make it depends on ARCH_DOVE and modify the description accordingly.

>+#include <linux/clk.h>
>+#include <linux/delay.h>
>+#include <linux/err.h>
>+#include <linux/platform_device.h>
>+#include <linux/io.h>
>+#include <linux/mmc/host.h>
>+#include "sdhci.h"
>+#include "sdhci-pltfm.h"
are those includes are realy needed? At least the delay.h and clk.h not needed for now.

saeed

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-10-27  8:46   ` Saeed Bishara
  0 siblings, 0 replies; 18+ messages in thread
From: Saeed Bishara @ 2010-10-27  8:46 UTC (permalink / raw)
  To: linux-arm-kernel

 
 
>+config MMC_SDHCI_MV
>+	bool "SDHCI support on Marvell's SoC"
>+	depends on MMC_SDHCI
>+	depends on MMC_SDHCI_PLTFM
>+	select MMC_SDHCI_IO_ACCESSORS
>+	help
>+	  This selects the Secure Digital Host Controller Interface in
>+	  Marvell's SoC controllers.
>+
>+	  If you have a controller with this interface, say Y or M here.
>+
>+	  If unsure, say N.
>+
Mike, the config name and description is too generic as there are several sdhci controllers on Marvell devices (see like pxa), I suggest to name it SDHCI_DOVE and make it depends on ARCH_DOVE and modify the description accordingly.

>+#include <linux/clk.h>
>+#include <linux/delay.h>
>+#include <linux/err.h>
>+#include <linux/platform_device.h>
>+#include <linux/io.h>
>+#include <linux/mmc/host.h>
>+#include "sdhci.h"
>+#include "sdhci-pltfm.h"
are those includes are realy needed? At least the delay.h and clk.h not needed for now.

saeed

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-10-27  8:07 ` Mike Rapoport
  0 siblings, 0 replies; 18+ messages in thread
From: Mike Rapoport @ 2010-10-27  8:07 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-arm-kernel, Mike Rapoport, Saeed Bishara

Signed-off-by: Mike Rapoport <mike@compulab.co.il>
CC: Saeed Bishara <saeed@marvell.com>
---
 drivers/mmc/host/Kconfig       |   13 +++++++
 drivers/mmc/host/Makefile      |    1 +
 drivers/mmc/host/sdhci-mv.c    |   77 ++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-pltfm.c |    3 ++
 drivers/mmc/host/sdhci-pltfm.h |    1 +
 5 files changed, 95 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-mv.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 68d1279..1952fa9 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,19 @@ config MMC_SDHCI_CNS3XXX
 
 	  If unsure, say N.
 
+config MMC_SDHCI_MV
+	bool "SDHCI support on Marvell's SoC"
+	depends on MMC_SDHCI
+	depends on MMC_SDHCI_PLTFM
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Secure Digital Host Controller Interface in
+	  Marvell's SoC controllers.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_S3C
 	tristate "SDHCI support on Samsung S3C SoC"
 	depends on MMC_SDHCI && PLAT_SAMSUNG
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 840bcb5..fdb3e96 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_SDHCI_PLTFM)			+= sdhci-platform.o
 sdhci-platform-y				:= sdhci-pltfm.o
 sdhci-platform-$(CONFIG_MMC_SDHCI_CNS3XXX)	+= sdhci-cns3xxx.o
+sdhci-platform-$(CONFIG_MMC_SDHCI_MV)		+= sdhci-mv.o
 
 obj-$(CONFIG_MMC_SDHCI_OF)	+= sdhci-of.o
 sdhci-of-y				:= sdhci-of-core.o
diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 0000000..b461205
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,77 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * Author: Saeed Bishara <saeed@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on  sdhci-cns3xxx.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+
+static u16 sdhci_mv_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	switch (reg) {
+	case SDHCI_HOST_VERSION:
+	case SDHCI_SLOT_INT_STATUS:
+		/* those registers don't exist */
+		return 0;
+	default:
+		ret = readw(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static u32 sdhci_mv_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	switch (reg) {
+	case SDHCI_CAPABILITIES:
+		ret = readl(host->ioaddr + reg);
+		/* Mask the support for 3.0V */
+		ret &= ~SDHCI_CAN_VDD_300;
+		break;
+	default:
+		ret = readl(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+	.read_w	= sdhci_mv_readw,
+	.read_l	= sdhci_mv_readl,
+};
+
+struct sdhci_pltfm_data sdhci_mv_pdata = {
+	.ops	= &sdhci_mv_ops,
+	.quirks	= SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+		  SDHCI_QUIRK_NO_BUSY_IRQ |
+		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+		  SDHCI_QUIRK_FORCE_DMA,
+};
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index e045e3c..3a389c2 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -161,6 +161,9 @@ static const struct platform_device_id sdhci_pltfm_ids[] = {
 #ifdef CONFIG_MMC_SDHCI_CNS3XXX
 	{ "sdhci-cns3xxx", (kernel_ulong_t)&sdhci_cns3xxx_pdata },
 #endif
+#ifdef CONFIG_MMC_SDHCI_MV
+	{ "sdhci-mv", (kernel_ulong_t)&sdhci_mv_pdata },
+#endif
 	{ },
 };
 MODULE_DEVICE_TABLE(platform, sdhci_pltfm_ids);
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 900f329..17da875 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -14,5 +14,6 @@
 #include <linux/sdhci-pltfm.h>
 
 extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
+extern struct sdhci_pltfm_data sdhci_mv_pdata;
 
 #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
-- 
1.7.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-10-27  8:07 ` Mike Rapoport
  0 siblings, 0 replies; 18+ messages in thread
From: Mike Rapoport @ 2010-10-27  8:07 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Mike Rapoport <mike@compulab.co.il>
CC: Saeed Bishara <saeed@marvell.com>
---
 drivers/mmc/host/Kconfig       |   13 +++++++
 drivers/mmc/host/Makefile      |    1 +
 drivers/mmc/host/sdhci-mv.c    |   77 ++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-pltfm.c |    3 ++
 drivers/mmc/host/sdhci-pltfm.h |    1 +
 5 files changed, 95 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-mv.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 68d1279..1952fa9 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,19 @@ config MMC_SDHCI_CNS3XXX
 
 	  If unsure, say N.
 
+config MMC_SDHCI_MV
+	bool "SDHCI support on Marvell's SoC"
+	depends on MMC_SDHCI
+	depends on MMC_SDHCI_PLTFM
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Secure Digital Host Controller Interface in
+	  Marvell's SoC controllers.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_S3C
 	tristate "SDHCI support on Samsung S3C SoC"
 	depends on MMC_SDHCI && PLAT_SAMSUNG
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 840bcb5..fdb3e96 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_SDHCI_PLTFM)			+= sdhci-platform.o
 sdhci-platform-y				:= sdhci-pltfm.o
 sdhci-platform-$(CONFIG_MMC_SDHCI_CNS3XXX)	+= sdhci-cns3xxx.o
+sdhci-platform-$(CONFIG_MMC_SDHCI_MV)		+= sdhci-mv.o
 
 obj-$(CONFIG_MMC_SDHCI_OF)	+= sdhci-of.o
 sdhci-of-y				:= sdhci-of-core.o
diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 0000000..b461205
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,77 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * Author: Saeed Bishara <saeed@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on  sdhci-cns3xxx.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+
+static u16 sdhci_mv_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	switch (reg) {
+	case SDHCI_HOST_VERSION:
+	case SDHCI_SLOT_INT_STATUS:
+		/* those registers don't exist */
+		return 0;
+	default:
+		ret = readw(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static u32 sdhci_mv_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	switch (reg) {
+	case SDHCI_CAPABILITIES:
+		ret = readl(host->ioaddr + reg);
+		/* Mask the support for 3.0V */
+		ret &= ~SDHCI_CAN_VDD_300;
+		break;
+	default:
+		ret = readl(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+	.read_w	= sdhci_mv_readw,
+	.read_l	= sdhci_mv_readl,
+};
+
+struct sdhci_pltfm_data sdhci_mv_pdata = {
+	.ops	= &sdhci_mv_ops,
+	.quirks	= SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+		  SDHCI_QUIRK_NO_BUSY_IRQ |
+		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+		  SDHCI_QUIRK_FORCE_DMA,
+};
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index e045e3c..3a389c2 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -161,6 +161,9 @@ static const struct platform_device_id sdhci_pltfm_ids[] = {
 #ifdef CONFIG_MMC_SDHCI_CNS3XXX
 	{ "sdhci-cns3xxx", (kernel_ulong_t)&sdhci_cns3xxx_pdata },
 #endif
+#ifdef CONFIG_MMC_SDHCI_MV
+	{ "sdhci-mv", (kernel_ulong_t)&sdhci_mv_pdata },
+#endif
 	{ },
 };
 MODULE_DEVICE_TABLE(platform, sdhci_pltfm_ids);
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 900f329..17da875 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -14,5 +14,6 @@
 #include <linux/sdhci-pltfm.h>
 
 extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
+extern struct sdhci_pltfm_data sdhci_mv_pdata;
 
 #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
-- 
1.7.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-05-05 13:39 ` saeed bishara
@ 2010-05-25  7:21   ` saeed bishara
  0 siblings, 0 replies; 18+ messages in thread
From: saeed bishara @ 2010-05-25  7:21 UTC (permalink / raw)
  To: linux-mmc; +Cc: Saeed Bishara

[-- Attachment #1: Type: text/plain, Size: 50 bytes --]

guys, any comments for the attached patch?

saeed

[-- Attachment #2: 0001-MMC-add-support-for-the-Marvell-platform-SDHCI-cont.patch --]
[-- Type: application/octet-stream, Size: 8450 bytes --]

From 4d8abec442d94895d3d2c7d7f9d59c5e19d379b2 Mon Sep 17 00:00:00 2001
From: Saeed Bishara <saeed@marvell.com>
Date: Tue, 4 May 2010 19:13:24 +0300
Subject: [PATCHv2] MMC: add support for the Marvell platform SDHCI controller

This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.

Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
 drivers/mmc/host/Kconfig    |   12 ++
 drivers/mmc/host/Makefile   |    1 +
 drivers/mmc/host/sdhci-mv.c |  243 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-mv.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 2e13b94..d132256 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -146,6 +146,18 @@ config MMC_SDHCI_S3C_DMA
 
 	  YMMV.
 
+config MMC_SDHCI_MV
+	tristate "SDHCI support on Marvell's soc"
+	depends on MMC_SDHCI
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Secure Digital Host Controller Interface in
+	  Marvell's SoC controllers.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index f480397..3a5519a 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PLTFM)	+= sdhci-pltfm.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
+obj-$(CONFIG_MMC_SDHCI_MV)	+= sdhci-mv.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 0000000..93adf2a
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,243 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on  sdhci-pltfm.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_mv_host {
+#if defined(CONFIG_HAVE_CLK)
+	struct clk		*clk;
+#endif
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * SDHCI core callbacks                                                      *
+ *                                                                           *
+\*****************************************************************************/
+static u16 mv_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	switch (reg) {
+	case SDHCI_HOST_VERSION:
+	case SDHCI_SLOT_INT_STATUS:
+		/* those registers don't exist */
+		return 0;
+	default:
+		ret = readw(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static u32 mv_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	switch (reg) {
+	case SDHCI_CAPABILITIES:
+		ret = readl(host->ioaddr + reg);
+		/* Mask the support for 3.0V */
+		ret &= ~SDHCI_CAN_VDD_300;
+		break;
+	default:
+		ret = readl(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+	.read_w = mv_readw,
+	.read_l = mv_readl,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Device probing/removal                                                    *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __devinit sdhci_mv_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct sdhci_mv_host *mv_host;
+	struct resource *iomem;
+	int ret;
+
+	BUG_ON(pdev == NULL);
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	if (resource_size(iomem) != 0x100)
+		dev_err(&pdev->dev, "Invalid iomem size. You may "
+			"experience problems.\n");
+
+	if (pdev->dev.parent)
+		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*mv_host));
+	else
+		host = sdhci_alloc_host(&pdev->dev, sizeof(*mv_host));
+
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err;
+	}
+
+	mv_host = sdhci_priv(host);
+	host->hw_name = "marvell-sdhci";
+	host->ops = &sdhci_mv_ops;
+	host->irq = platform_get_irq(pdev, 0);
+	host->quirks =  SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+			SDHCI_QUIRK_NO_BUSY_IRQ |
+			SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+			SDHCI_QUIRK_FORCE_DMA;
+
+	if (!devm_request_mem_region(&pdev->dev, iomem->start,
+				     resource_size(iomem),
+				     mmc_hostname(host->mmc))) {
+		dev_err(&pdev->dev, "cannot request region\n");
+		ret = -EBUSY;
+		goto err_request;
+	}
+
+	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
+				    resource_size(iomem));
+	if (!host->ioaddr) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
+		goto err_request;
+	}
+
+#if defined(CONFIG_HAVE_CLK)
+	mv_host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mv_host->clk))
+		dev_notice(&pdev->dev, "cannot get clkdev\n");
+	else
+		clk_enable(mv_host->clk);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_request;
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+
+err_request:
+	sdhci_free_host(host);
+err:
+	printk(KERN_ERR"Probing of sdhci-mv failed: %d\n", ret);
+	return ret;
+}
+
+static int __devexit sdhci_mv_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+#if defined(CONFIG_HAVE_CLK)
+	struct sdhci_mv_host *mv_host = sdhci_priv(host);
+	struct clk *clk = mv_host->clk;
+#endif
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+
+	sdhci_remove_host(host, dead);
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+#if defined(CONFIG_HAVE_CLK)
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	}
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdhci_mv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_suspend_host(host, state);
+}
+
+static int sdhci_mv_resume(struct platform_device *pdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_resume_host(host);
+}
+#else
+#define sdhci_mv_suspend NULL
+#define sdhci_mv_resume NULL
+#endif
+
+static struct platform_driver sdhci_mv_driver = {
+	.driver = {
+		.name	= "sdhci-mv",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sdhci_mv_probe,
+	.remove		= __devexit_p(sdhci_mv_remove),
+	.suspend	= sdhci_mv_suspend,
+	.resume		= sdhci_mv_resume,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init sdhci_mv_init(void)
+{
+	return platform_driver_register(&sdhci_mv_driver);
+}
+
+static void __exit sdhci_mv_exit(void)
+{
+	platform_driver_unregister(&sdhci_mv_driver);
+}
+
+module_init(sdhci_mv_init);
+module_exit(sdhci_mv_exit);
+
+MODULE_DESCRIPTION("Marvell SDHCI platform driver");
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sdhci-mv");
+
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] MMC: add support for the Marvell platform SDHCI controller
  2010-05-04 16:24 Saeed Bishara
@ 2010-05-05 13:39 ` saeed bishara
  2010-05-25  7:21   ` saeed bishara
  0 siblings, 1 reply; 18+ messages in thread
From: saeed bishara @ 2010-05-05 13:39 UTC (permalink / raw)
  To: linux-mmc; +Cc: Saeed Bishara

[-- Attachment #1: Type: text/plain, Size: 10630 bytes --]

Attached v2 of the patch. changes:
1. added missing files (Makefile and Kconfig)
2. added the force dma quirk
3. removed special treatment for DATA register used fro pio mode

please review

saeed
On Tue, May 4, 2010 at 7:24 PM, Saeed Bishara <saeed@marvell.com> wrote:
> This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.
>
> Signed-off-by: Saeed Bishara <saeed@marvell.com>
> ---
>  drivers/mmc/host/sdhci-mv.c |  266 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 266 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mmc/host/sdhci-mv.c
>
> diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
> new file mode 100644
> index 0000000..a88cae1
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-mv.c
> @@ -0,0 +1,266 @@
> +/*
> + * sdhci-mv.c Support for SDHCI platform devices
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +/* Supports:
> + * SDHCI platform devices found on Marvell SoC's
> + *
> + * Based on  sdhci-pltfm.c
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +#include <linux/io.h>
> +#include <linux/mmc/host.h>
> +#include "sdhci.h"
> +
> +struct sdhci_mv_host {
> +#if defined(CONFIG_HAVE_CLK)
> +       struct clk              *clk;
> +#endif
> +};
> +
> +/*****************************************************************************\
> + *                                                                           *
> + * SDHCI core callbacks                                                      *
> + *                                                                           *
> +\*****************************************************************************/
> +static u16 mv_readw(struct sdhci_host *host, int reg)
> +{
> +       u16 ret;
> +
> +       switch (reg) {
> +       case SDHCI_HOST_VERSION:
> +       case SDHCI_SLOT_INT_STATUS:
> +               /* those registers don't exist */
> +               return 0;
> +       default:
> +               ret = readw(host->ioaddr + reg);
> +       }
> +       return ret;
> +}
> +
> +static u32 mv_readl(struct sdhci_host *host, int reg)
> +{
> +       u32 ret;
> +
> +       switch (reg) {
> +       case SDHCI_BUFFER:
> +               /*
> +                * This register can't be accessed with 32 bit access, solve
> +                * this issue by breaking it into two 16 bit accesses.
> +                */
> +               ret = readw(host->ioaddr + SDHCI_BUFFER);
> +               ret |= readw(host->ioaddr + SDHCI_BUFFER + 2) << 16;
> +               break;
> +       default:
> +               ret = readl(host->ioaddr + reg);
> +       }
> +       return ret;
> +}
> +
> +static void mv_writel(struct sdhci_host *host, u32 val, int reg)
> +{
> +       switch (reg) {
> +       case SDHCI_BUFFER:
> +       {
> +               /*
> +                * This register can't be accessed with 32 bit access, solve
> +                * this issue by breaking it into two 16 bit accesses.
> +                */
> +               u16 temp = reg & 0xFFFF;
> +               writew(temp, host->ioaddr + SDHCI_BUFFER);
> +               temp = (0xFFFF0000 & reg) >> 16;
> +               writew(temp, host->ioaddr + SDHCI_BUFFER + 2);
> +       }
> +       break;
> +       default:
> +               writel(val, host->ioaddr + reg);
> +       }
> +}
> +
> +static struct sdhci_ops sdhci_mv_ops = {
> +       .read_w = mv_readw,
> +       .read_l = mv_readl,
> +       .write_l = mv_writel,
> +};
> +
> +/*****************************************************************************\
> + *                                                                           *
> + * Device probing/removal                                                    *
> + *                                                                           *
> +\*****************************************************************************/
> +
> +static int __devinit sdhci_mv_probe(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host;
> +       struct sdhci_mv_host *mv_host;
> +       struct resource *iomem;
> +       int ret;
> +
> +       BUG_ON(pdev == NULL);
> +
> +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!iomem) {
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +
> +       if (resource_size(iomem) != 0x100)
> +               dev_err(&pdev->dev, "Invalid iomem size. You may "
> +                       "experience problems.\n");
> +
> +       if (pdev->dev.parent)
> +               host = sdhci_alloc_host(pdev->dev.parent, sizeof(*mv_host));
> +       else
> +               host = sdhci_alloc_host(&pdev->dev, sizeof(*mv_host));
> +
> +       if (IS_ERR(host)) {
> +               ret = PTR_ERR(host);
> +               goto err;
> +       }
> +
> +       mv_host = sdhci_priv(host);
> +       host->hw_name = "marvell-sdhci";
> +       host->ops = &sdhci_mv_ops;
> +       host->irq = platform_get_irq(pdev, 0);
> +       host->quirks =  SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
> +                       SDHCI_QUIRK_NO_BUSY_IRQ |
> +                       SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
> +
> +       if (!devm_request_mem_region(&pdev->dev, iomem->start,
> +                                    resource_size(iomem),
> +                                    mmc_hostname(host->mmc))) {
> +               dev_err(&pdev->dev, "cannot request region\n");
> +               ret = -EBUSY;
> +               goto err_request;
> +       }
> +
> +       host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
> +                                   resource_size(iomem));
> +       if (!host->ioaddr) {
> +               dev_err(&pdev->dev, "failed to remap registers\n");
> +               ret = -ENOMEM;
> +               goto err_request;
> +       }
> +
> +#if defined(CONFIG_HAVE_CLK)
> +       mv_host->clk = clk_get(&pdev->dev, NULL);
> +       if (IS_ERR(mv_host->clk))
> +               dev_notice(&pdev->dev, "cannot get clkdev\n");
> +       else
> +               clk_enable(mv_host->clk);
> +#endif
> +
> +       ret = sdhci_add_host(host);
> +       if (ret)
> +               goto err_request;
> +
> +       platform_set_drvdata(pdev, host);
> +
> +       return 0;
> +
> +err_request:
> +       sdhci_free_host(host);
> +err:
> +       printk(KERN_ERR"Probing of sdhci-mv failed: %d\n", ret);
> +       return ret;
> +}
> +
> +static int __devexit sdhci_mv_remove(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host = platform_get_drvdata(pdev);
> +#if defined(CONFIG_HAVE_CLK)
> +       struct sdhci_mv_host *mv_host = sdhci_priv(host);
> +       struct clk *clk = mv_host->clk;
> +#endif
> +       int dead;
> +       u32 scratch;
> +
> +       dead = 0;
> +       scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
> +       if (scratch == (u32)-1)
> +               dead = 1;
> +
> +       sdhci_remove_host(host, dead);
> +       sdhci_free_host(host);
> +       platform_set_drvdata(pdev, NULL);
> +#if defined(CONFIG_HAVE_CLK)
> +       if (!IS_ERR(clk)) {
> +               clk_disable(clk);
> +               clk_put(clk);
> +       }
> +#endif
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int sdhci_mv_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
> +
> +       return sdhci_suspend_host(host, state);
> +}
> +
> +static int sdhci_mv_resume(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
> +
> +       return sdhci_resume_host(host);
> +}
> +#else
> +#define sdhci_mv_suspend NULL
> +#define sdhci_mv_resume NULL
> +#endif
> +
> +static struct platform_driver sdhci_mv_driver = {
> +       .driver = {
> +               .name   = "sdhci-mv",
> +               .owner  = THIS_MODULE,
> +       },
> +       .probe          = sdhci_mv_probe,
> +       .remove         = __devexit_p(sdhci_mv_remove),
> +       .suspend        = sdhci_mv_suspend,
> +       .resume         = sdhci_mv_resume,
> +};
> +
> +/*****************************************************************************\
> + *                                                                           *
> + * Driver init/exit                                                          *
> + *                                                                           *
> +\*****************************************************************************/
> +
> +static int __init sdhci_mv_init(void)
> +{
> +       return platform_driver_register(&sdhci_mv_driver);
> +}
> +
> +static void __exit sdhci_mv_exit(void)
> +{
> +       platform_driver_unregister(&sdhci_mv_driver);
> +}
> +
> +module_init(sdhci_mv_init);
> +module_exit(sdhci_mv_exit);
> +
> +MODULE_DESCRIPTION("Marvell SDHCI platform driver");
> +MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:sdhci-mv");
> +
> --
> 1.6.0.4
>
>

[-- Attachment #2: 0001-MMC-add-support-for-the-Marvell-platform-SDHCI-cont.patch --]
[-- Type: application/octet-stream, Size: 8450 bytes --]

From 4d8abec442d94895d3d2c7d7f9d59c5e19d379b2 Mon Sep 17 00:00:00 2001
From: Saeed Bishara <saeed@marvell.com>
Date: Tue, 4 May 2010 19:13:24 +0300
Subject: [PATCHv2] MMC: add support for the Marvell platform SDHCI controller

This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.

Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
 drivers/mmc/host/Kconfig    |   12 ++
 drivers/mmc/host/Makefile   |    1 +
 drivers/mmc/host/sdhci-mv.c |  243 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-mv.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 2e13b94..d132256 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -146,6 +146,18 @@ config MMC_SDHCI_S3C_DMA
 
 	  YMMV.
 
+config MMC_SDHCI_MV
+	tristate "SDHCI support on Marvell's soc"
+	depends on MMC_SDHCI
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Secure Digital Host Controller Interface in
+	  Marvell's SoC controllers.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index f480397..3a5519a 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PLTFM)	+= sdhci-pltfm.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
+obj-$(CONFIG_MMC_SDHCI_MV)	+= sdhci-mv.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 0000000..93adf2a
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,243 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on  sdhci-pltfm.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_mv_host {
+#if defined(CONFIG_HAVE_CLK)
+	struct clk		*clk;
+#endif
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * SDHCI core callbacks                                                      *
+ *                                                                           *
+\*****************************************************************************/
+static u16 mv_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	switch (reg) {
+	case SDHCI_HOST_VERSION:
+	case SDHCI_SLOT_INT_STATUS:
+		/* those registers don't exist */
+		return 0;
+	default:
+		ret = readw(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static u32 mv_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	switch (reg) {
+	case SDHCI_CAPABILITIES:
+		ret = readl(host->ioaddr + reg);
+		/* Mask the support for 3.0V */
+		ret &= ~SDHCI_CAN_VDD_300;
+		break;
+	default:
+		ret = readl(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+	.read_w = mv_readw,
+	.read_l = mv_readl,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Device probing/removal                                                    *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __devinit sdhci_mv_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct sdhci_mv_host *mv_host;
+	struct resource *iomem;
+	int ret;
+
+	BUG_ON(pdev == NULL);
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	if (resource_size(iomem) != 0x100)
+		dev_err(&pdev->dev, "Invalid iomem size. You may "
+			"experience problems.\n");
+
+	if (pdev->dev.parent)
+		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*mv_host));
+	else
+		host = sdhci_alloc_host(&pdev->dev, sizeof(*mv_host));
+
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err;
+	}
+
+	mv_host = sdhci_priv(host);
+	host->hw_name = "marvell-sdhci";
+	host->ops = &sdhci_mv_ops;
+	host->irq = platform_get_irq(pdev, 0);
+	host->quirks =  SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+			SDHCI_QUIRK_NO_BUSY_IRQ |
+			SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+			SDHCI_QUIRK_FORCE_DMA;
+
+	if (!devm_request_mem_region(&pdev->dev, iomem->start,
+				     resource_size(iomem),
+				     mmc_hostname(host->mmc))) {
+		dev_err(&pdev->dev, "cannot request region\n");
+		ret = -EBUSY;
+		goto err_request;
+	}
+
+	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
+				    resource_size(iomem));
+	if (!host->ioaddr) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
+		goto err_request;
+	}
+
+#if defined(CONFIG_HAVE_CLK)
+	mv_host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mv_host->clk))
+		dev_notice(&pdev->dev, "cannot get clkdev\n");
+	else
+		clk_enable(mv_host->clk);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_request;
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+
+err_request:
+	sdhci_free_host(host);
+err:
+	printk(KERN_ERR"Probing of sdhci-mv failed: %d\n", ret);
+	return ret;
+}
+
+static int __devexit sdhci_mv_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+#if defined(CONFIG_HAVE_CLK)
+	struct sdhci_mv_host *mv_host = sdhci_priv(host);
+	struct clk *clk = mv_host->clk;
+#endif
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+
+	sdhci_remove_host(host, dead);
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+#if defined(CONFIG_HAVE_CLK)
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	}
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdhci_mv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_suspend_host(host, state);
+}
+
+static int sdhci_mv_resume(struct platform_device *pdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_resume_host(host);
+}
+#else
+#define sdhci_mv_suspend NULL
+#define sdhci_mv_resume NULL
+#endif
+
+static struct platform_driver sdhci_mv_driver = {
+	.driver = {
+		.name	= "sdhci-mv",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sdhci_mv_probe,
+	.remove		= __devexit_p(sdhci_mv_remove),
+	.suspend	= sdhci_mv_suspend,
+	.resume		= sdhci_mv_resume,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init sdhci_mv_init(void)
+{
+	return platform_driver_register(&sdhci_mv_driver);
+}
+
+static void __exit sdhci_mv_exit(void)
+{
+	platform_driver_unregister(&sdhci_mv_driver);
+}
+
+module_init(sdhci_mv_init);
+module_exit(sdhci_mv_exit);
+
+MODULE_DESCRIPTION("Marvell SDHCI platform driver");
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sdhci-mv");
+
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH] MMC: add support for the Marvell platform SDHCI controller
@ 2010-05-04 16:24 Saeed Bishara
  2010-05-05 13:39 ` saeed bishara
  0 siblings, 1 reply; 18+ messages in thread
From: Saeed Bishara @ 2010-05-04 16:24 UTC (permalink / raw)
  To: linux-mmc; +Cc: saeed.bishara, Saeed Bishara

This patch implements the driver for the platfrom SDHCI controllers that found on some of Marvell's SoC's.

Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
 drivers/mmc/host/sdhci-mv.c |  266 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 266 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-mv.c

diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 0000000..a88cae1
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,266 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on  sdhci-pltfm.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_mv_host {
+#if defined(CONFIG_HAVE_CLK)
+	struct clk		*clk;
+#endif
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * SDHCI core callbacks                                                      *
+ *                                                                           *
+\*****************************************************************************/
+static u16 mv_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	switch (reg) {
+	case SDHCI_HOST_VERSION:
+	case SDHCI_SLOT_INT_STATUS:
+		/* those registers don't exist */
+		return 0;
+	default:
+		ret = readw(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static u32 mv_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	switch (reg) {
+	case SDHCI_BUFFER:
+		/*
+		 * This register can't be accessed with 32 bit access, solve
+		 * this issue by breaking it into two 16 bit accesses.
+		 */
+		ret = readw(host->ioaddr + SDHCI_BUFFER);
+		ret |= readw(host->ioaddr + SDHCI_BUFFER + 2) << 16;
+		break;
+	default:
+		ret = readl(host->ioaddr + reg);
+	}
+	return ret;
+}
+
+static void mv_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	switch (reg) {
+	case SDHCI_BUFFER:
+	{
+		/*
+		 * This register can't be accessed with 32 bit access, solve
+		 * this issue by breaking it into two 16 bit accesses.
+		 */
+		u16 temp = reg & 0xFFFF;
+		writew(temp, host->ioaddr + SDHCI_BUFFER);
+		temp = (0xFFFF0000 & reg) >> 16;
+		writew(temp, host->ioaddr + SDHCI_BUFFER + 2);
+	}
+	break;
+	default:
+		writel(val, host->ioaddr + reg);
+	}
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+	.read_w = mv_readw,
+	.read_l = mv_readl,
+	.write_l = mv_writel,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Device probing/removal                                                    *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __devinit sdhci_mv_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct sdhci_mv_host *mv_host;
+	struct resource *iomem;
+	int ret;
+
+	BUG_ON(pdev == NULL);
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	if (resource_size(iomem) != 0x100)
+		dev_err(&pdev->dev, "Invalid iomem size. You may "
+			"experience problems.\n");
+
+	if (pdev->dev.parent)
+		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*mv_host));
+	else
+		host = sdhci_alloc_host(&pdev->dev, sizeof(*mv_host));
+
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err;
+	}
+
+	mv_host = sdhci_priv(host);
+	host->hw_name = "marvell-sdhci";
+	host->ops = &sdhci_mv_ops;
+	host->irq = platform_get_irq(pdev, 0);
+	host->quirks =  SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+			SDHCI_QUIRK_NO_BUSY_IRQ |
+			SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
+	if (!devm_request_mem_region(&pdev->dev, iomem->start,
+				     resource_size(iomem),
+				     mmc_hostname(host->mmc))) {
+		dev_err(&pdev->dev, "cannot request region\n");
+		ret = -EBUSY;
+		goto err_request;
+	}
+
+	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
+				    resource_size(iomem));
+	if (!host->ioaddr) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
+		goto err_request;
+	}
+
+#if defined(CONFIG_HAVE_CLK)
+	mv_host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mv_host->clk))
+		dev_notice(&pdev->dev, "cannot get clkdev\n");
+	else
+		clk_enable(mv_host->clk);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_request;
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+
+err_request:
+	sdhci_free_host(host);
+err:
+	printk(KERN_ERR"Probing of sdhci-mv failed: %d\n", ret);
+	return ret;
+}
+
+static int __devexit sdhci_mv_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+#if defined(CONFIG_HAVE_CLK)
+	struct sdhci_mv_host *mv_host = sdhci_priv(host);
+	struct clk *clk = mv_host->clk;
+#endif
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+
+	sdhci_remove_host(host, dead);
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+#if defined(CONFIG_HAVE_CLK)
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	}
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdhci_mv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_suspend_host(host, state);
+}
+
+static int sdhci_mv_resume(struct platform_device *pdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+	return sdhci_resume_host(host);
+}
+#else
+#define sdhci_mv_suspend NULL
+#define sdhci_mv_resume NULL
+#endif
+
+static struct platform_driver sdhci_mv_driver = {
+	.driver = {
+		.name	= "sdhci-mv",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sdhci_mv_probe,
+	.remove		= __devexit_p(sdhci_mv_remove),
+	.suspend	= sdhci_mv_suspend,
+	.resume		= sdhci_mv_resume,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init sdhci_mv_init(void)
+{
+	return platform_driver_register(&sdhci_mv_driver);
+}
+
+static void __exit sdhci_mv_exit(void)
+{
+	platform_driver_unregister(&sdhci_mv_driver);
+}
+
+module_init(sdhci_mv_init);
+module_exit(sdhci_mv_exit);
+
+MODULE_DESCRIPTION("Marvell SDHCI platform driver");
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sdhci-mv");
+
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2010-10-27  9:17 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-22 14:09 [PATCH] MMC: add support for the Marvell platform SDHCI controller Saeed Bishara
2010-06-23 11:52 ` Matt Fleming
2010-06-23 12:11   ` saeed bishara
2010-06-23 14:06     ` Matt Fleming
2010-08-25 22:39 ` Matt Fleming
2010-08-25 23:16   ` Andrew Morton
2010-09-10 20:16 ` Chris Ball
  -- strict thread matches above, loose matches on Subject: below --
2010-10-27  8:07 Mike Rapoport
2010-10-27  8:07 ` Mike Rapoport
2010-10-27  8:46 ` Saeed Bishara
2010-10-27  8:46   ` Saeed Bishara
2010-10-27  9:17   ` Mike Rapoport
2010-10-27  9:17     ` Mike Rapoport
2010-10-27  9:10 ` Chris Ball
2010-10-27  9:10   ` Chris Ball
2010-05-04 16:24 Saeed Bishara
2010-05-05 13:39 ` saeed bishara
2010-05-25  7:21   ` saeed bishara

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.