Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42051e8a authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Chris Ball
Browse files

mmc: tmio: convert the SDHI MMC driver from MFD to a platform driver



On sh-mobile platforms the SDHI driver was using the tmio_mmc SD/SDIO
MFD cell driver. Now that the tmio_mmc driver has been split into a
core and a separate MFD glue, we can support SDHI natively without the
need to emulate an MFD controller. This also allows to support systems
with an on-SoC SDHI controller and a separate MFD with a TMIO core.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: default avatarPaul Mundt <lethal@linux-sh.org>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 4fbc5ece
Loading
Loading
Loading
Loading
+0 −14
Original line number Original line Diff line number Diff line
@@ -60,15 +60,6 @@ config MFD_ASIC3
	  This driver supports the ASIC3 multifunction chip found on many
	  This driver supports the ASIC3 multifunction chip found on many
	  PDAs (mainly iPAQ and HTC based ones)
	  PDAs (mainly iPAQ and HTC based ones)


config MFD_SH_MOBILE_SDHI
	bool "Support for SuperH Mobile SDHI"
	depends on SUPERH || ARCH_SHMOBILE
	select MFD_CORE
	select TMIO_MMC_DMA
	 ---help---
	  This driver supports the SDHI hardware block found in many
	  SuperH Mobile SoCs.

config MFD_DAVINCI_VOICECODEC
config MFD_DAVINCI_VOICECODEC
	tristate
	tristate
	select MFD_CORE
	select MFD_CORE
@@ -265,11 +256,6 @@ config MFD_TMIO
	bool
	bool
	default n
	default n


config TMIO_MMC_DMA
	bool
	select DMA_ENGINE
	select DMADEVICES

config MFD_T7L66XB
config MFD_T7L66XB
	bool "Support Toshiba T7L66XB"
	bool "Support Toshiba T7L66XB"
	depends on ARM && HAVE_CLK
	depends on ARM && HAVE_CLK
+0 −1
Original line number Original line Diff line number Diff line
@@ -6,7 +6,6 @@
obj-$(CONFIG_MFD_88PM860X)	+= 88pm860x.o
obj-$(CONFIG_MFD_88PM860X)	+= 88pm860x.o
obj-$(CONFIG_MFD_SM501)		+= sm501.o
obj-$(CONFIG_MFD_SM501)		+= sm501.o
obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
obj-$(CONFIG_MFD_SH_MOBILE_SDHI)		+= sh_mobile_sdhi.o


obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
+8 −1
Original line number Original line Diff line number Diff line
@@ -444,12 +444,19 @@ config MMC_TMIO_CORE


config MMC_TMIO
config MMC_TMIO
	tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
	tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
	depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI
	depends on MFD_TMIO || MFD_ASIC3
	select MMC_TMIO_CORE
	select MMC_TMIO_CORE
	help
	help
	  This provides support for the SD/MMC cell found in TC6393XB,
	  This provides support for the SD/MMC cell found in TC6393XB,
	  T7L66XB and also HTC ASIC3
	  T7L66XB and also HTC ASIC3


config MMC_SDHI
	tristate "SH-Mobile SDHI SD/SDIO controller support"
	select MMC_TMIO_CORE
	help
	  This provides support for the SDHI SD/SDIO controller found in
	  SuperH and ARM SH-Mobile SoCs

config MMC_CB710
config MMC_CB710
	tristate "ENE CB710 MMC/SD Interface support"
	tristate "ENE CB710 MMC/SD Interface support"
	depends on PCI
	depends on PCI
+5 −2
Original line number Original line Diff line number Diff line
@@ -31,7 +31,10 @@ obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
obj-$(CONFIG_MMC_TMIO)		+= tmio_mmc.o
obj-$(CONFIG_MMC_TMIO)		+= tmio_mmc.o
obj-$(CONFIG_MMC_TMIO_CORE)	+= tmio_mmc_core.o
obj-$(CONFIG_MMC_TMIO_CORE)	+= tmio_mmc_core.o
tmio_mmc_core-y			:= tmio_mmc_pio.o
tmio_mmc_core-y			:= tmio_mmc_pio.o
tmio_mmc_core-$(CONFIG_TMIO_MMC_DMA)	+= tmio_mmc_dma.o
ifneq ($(CONFIG_MMC_SDHI),n)
tmio_mmc_core-y			+= tmio_mmc_dma.o
endif
obj-$(CONFIG_MMC_SDHI)		+= sh_mobile_sdhi.o
obj-$(CONFIG_MMC_CB710)		+= cb710-mmc.o
obj-$(CONFIG_MMC_CB710)		+= cb710-mmc.o
obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
+33 −62
Original line number Original line Diff line number Diff line
@@ -23,51 +23,30 @@
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/mmc/host.h>
#include <linux/mmc/host.h>
#include <linux/mfd/core.h>
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mfd/tmio.h>
#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/sh_dma.h>
#include <linux/sh_dma.h>


#include "tmio_mmc.h"

struct sh_mobile_sdhi {
struct sh_mobile_sdhi {
	struct clk *clk;
	struct clk *clk;
	struct tmio_mmc_data mmc_data;
	struct tmio_mmc_data mmc_data;
	struct mfd_cell cell_mmc;
	struct sh_dmae_slave param_tx;
	struct sh_dmae_slave param_tx;
	struct sh_dmae_slave param_rx;
	struct sh_dmae_slave param_rx;
	struct tmio_mmc_dma dma_priv;
	struct tmio_mmc_dma dma_priv;
};
};


static struct resource sh_mobile_sdhi_resources[] = {
static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
	{
		.start = 0x000,
		.end   = 0x1ff,
		.flags = IORESOURCE_MEM,
	},
	{
		.start = 0,
		.end   = 0,
		.flags = IORESOURCE_IRQ,
	},
};

static struct mfd_cell sh_mobile_sdhi_cell = {
	.name          = "tmio-mmc",
	.num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
	.resources     = sh_mobile_sdhi_resources,
};

static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
{
{
	struct platform_device *pdev = to_platform_device(tmio->dev.parent);
	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;


	if (p && p->set_pwr)
	if (p && p->set_pwr)
		p->set_pwr(pdev, state);
		p->set_pwr(pdev, state);
}
}


static int sh_mobile_sdhi_get_cd(struct platform_device *tmio)
static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
{
{
	struct platform_device *pdev = to_platform_device(tmio->dev.parent);
	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;


	if (p && p->get_cd)
	if (p && p->get_cd)
@@ -81,20 +60,9 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
	struct sh_mobile_sdhi *priv;
	struct sh_mobile_sdhi *priv;
	struct tmio_mmc_data *mmc_data;
	struct tmio_mmc_data *mmc_data;
	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
	struct resource *mem;
	struct tmio_mmc_host *host;
	char clk_name[8];
	char clk_name[8];
	int ret, irq;
	int ret;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem)
		dev_err(&pdev->dev, "missing MEM resource\n");

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		dev_err(&pdev->dev, "missing IRQ resource\n");

	if (!mem || (irq < 0))
		return -EINVAL;


	priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
	priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
	if (priv == NULL) {
	if (priv == NULL) {
@@ -109,8 +77,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
	if (IS_ERR(priv->clk)) {
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
		ret = PTR_ERR(priv->clk);
		ret = PTR_ERR(priv->clk);
		kfree(priv);
		goto eclkget;
		return ret;
	}
	}


	clk_enable(priv->clk);
	clk_enable(priv->clk);
@@ -123,6 +90,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
		mmc_data->flags = p->tmio_flags;
		mmc_data->flags = p->tmio_flags;
		mmc_data->ocr_mask = p->tmio_ocr_mask;
		mmc_data->ocr_mask = p->tmio_ocr_mask;
		mmc_data->capabilities |= p->tmio_caps;
		mmc_data->capabilities |= p->tmio_caps;

		if (p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
			priv->param_tx.slave_id = p->dma_slave_tx;
			priv->param_rx.slave_id = p->dma_slave_rx;
			priv->dma_priv.chan_priv_tx = &priv->param_tx;
			priv->dma_priv.chan_priv_rx = &priv->param_rx;
			priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
			mmc_data->dma = &priv->dma_priv;
		}
	}
	}


	/*
	/*
@@ -136,36 +112,30 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
	 */
	 */
	mmc_data->flags |= TMIO_MMC_SDIO_IRQ;
	mmc_data->flags |= TMIO_MMC_SDIO_IRQ;


	if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
	ret = tmio_mmc_host_probe(&host, pdev, mmc_data);
		priv->param_tx.slave_id = p->dma_slave_tx;
	if (ret < 0)
		priv->param_rx.slave_id = p->dma_slave_rx;
		goto eprobe;
		priv->dma_priv.chan_priv_tx = &priv->param_tx;
		priv->dma_priv.chan_priv_rx = &priv->param_rx;
		priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
		mmc_data->dma = &priv->dma_priv;
	}


	memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
	pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
	priv->cell_mmc.mfd_data = mmc_data;
		(unsigned long)host->ctl, host->irq);


	platform_set_drvdata(pdev, priv);
	return ret;


	ret = mfd_add_devices(&pdev->dev, pdev->id,
eprobe:
			      &priv->cell_mmc, 1, mem, irq);
	if (ret) {
	clk_disable(priv->clk);
	clk_disable(priv->clk);
	clk_put(priv->clk);
	clk_put(priv->clk);
eclkget:
	kfree(priv);
	kfree(priv);
	}

	return ret;
	return ret;
}
}


static int sh_mobile_sdhi_remove(struct platform_device *pdev)
static int sh_mobile_sdhi_remove(struct platform_device *pdev)
{
{
	struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct tmio_mmc_host *host = mmc_priv(mmc);
	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);


	mfd_remove_devices(&pdev->dev);
	tmio_mmc_host_remove(host);
	clk_disable(priv->clk);
	clk_disable(priv->clk);
	clk_put(priv->clk);
	clk_put(priv->clk);
	kfree(priv);
	kfree(priv);
@@ -198,3 +168,4 @@ module_exit(sh_mobile_sdhi_exit);
MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
MODULE_AUTHOR("Magnus Damm");
MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:sh_mobile_sdhi");
Loading