This is a step in the right direction for future Device Tree support. It will allow variant specific attributes to be collected from a Device Tree without overloading the MMCI core. It will also provide additional future variants a cleaner way to add support. Signed-off-by: Lee Jones <lee.jones@xxxxxxxxxx> --- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/mmci-ux500.c | 93 +++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/mmci.c | 90 ++++------------------------------------ drivers/mmc/host/mmci.h | 37 ++++++++++++++++ 4 files changed, 139 insertions(+), 83 deletions(-) create mode 100644 drivers/mmc/host/mmci-ux500.c diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 745f8fc..58e2bdc 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -2,7 +2,7 @@ # Makefile for MMC/SD host controller drivers # -obj-$(CONFIG_MMC_ARMMMCI) += mmci.o +obj-$(CONFIG_MMC_ARMMMCI) += mmci.o mmci-ux500.o obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_IMX) += imxmmc.o obj-$(CONFIG_MMC_MXC) += mxcmmc.o diff --git a/drivers/mmc/host/mmci-ux500.c b/drivers/mmc/host/mmci-ux500.c new file mode 100644 index 0000000..82e60f9 --- /dev/null +++ b/drivers/mmc/host/mmci-ux500.c @@ -0,0 +1,93 @@ +#include <linux/kernel.h> +#include <linux/module.h> + +/* MMCIPOWER bits */ +#define MCI_DATA2DIREN (1 << 2) +#define MCI_CMDDIREN (1 << 3) +#define MCI_DATA0DIREN (1 << 4) +#define MCI_DATA31DIREN (1 << 5) +#define MCI_FBCLKEN (1 << 7) + +static struct variant_data variant_u300 = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg_enable = MCI_ST_U300_HWFCEN, + .datalength_bits = 16, + .sdio = true, +}; + +static struct variant_data variant_ux500 = { + .fifosize = 30 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datalength_bits = 24, + .sdio = true, + .st_clkdiv = true, +}; + +static struct variant_data variant_ux500v2 = { + .fifosize = 30 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datalength_bits = 24, + .sdio = true, + .st_clkdiv = true, + .blksz_datactrl16 = true, +}; + +static struct amba_id mmci_ux500_ids[] = { + /* ST Micro variants */ + { + .id = 0x00180180, + .mask = 0x00ffffff, + .data = &variant_u300, + }, + { + .id = 0x00280180, + .mask = 0x00ffffff, + .data = &variant_u300, + }, + { + .id = 0x00480180, + .mask = 0xf0ffffff, + .data = &variant_ux500, + }, + { + .id = 0x10480180, + .mask = 0xf0ffffff, + .data = &variant_ux500v2, + }, + { 0, 0 }, +}; + +MODULE_DEVICE_TABLE(amba, mmci_ux500_ids); + +static struct amba_driver mmci_ux500_driver = { + .drv = { + .name = DRIVER_NAME, + }, + .probe = mmci_probe, + .remove = __devexit_p(mmci_remove), + .suspend = mmci_suspend, + .resume = mmci_resume, + .id_table = mmci_ux500_ids, +}; + +static int __init mmci_ux500_init(void) +{ + return amba_driver_register(&mmci_ux500_driver); +} + +static void __exit mmci_ux500_exit(void) +{ + amba_driver_unregister(&mmci_ux500_driver); +} + +module_init(mmci_ux500_init); +module_exit(mmci_ux500_exit); +module_param(fmax, uint, 0444); + +MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 304f2f9..ff44586 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -37,34 +37,6 @@ #include "mmci.h" -#define DRIVER_NAME "mmci-pl18x" - -static unsigned int fmax = 515633; - -/** - * struct variant_data - MMCI variant-specific quirks - * @clkreg: default value for MCICLOCK register - * @clkreg_enable: enable value for MMCICLOCK register - * @datalength_bits: number of bits in the MMCIDATALENGTH register - * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY - * is asserted (likewise for RX) - * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY - * is asserted (likewise for RX) - * @sdio: variant supports SDIO - * @st_clkdiv: true if using a ST-specific clock divider algorithm - * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register - */ -struct variant_data { - unsigned int clkreg; - unsigned int clkreg_enable; - unsigned int datalength_bits; - unsigned int fifosize; - unsigned int fifohalfsize; - bool sdio; - bool st_clkdiv; - bool blksz_datactrl16; -}; - static struct variant_data variant_arm = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, @@ -77,35 +49,6 @@ static struct variant_data variant_arm_extended_fifo = { .datalength_bits = 16, }; -static struct variant_data variant_u300 = { - .fifosize = 16 * 4, - .fifohalfsize = 8 * 4, - .clkreg_enable = MCI_ST_U300_HWFCEN, - .datalength_bits = 16, - .sdio = true, -}; - -static struct variant_data variant_ux500 = { - .fifosize = 30 * 4, - .fifohalfsize = 8 * 4, - .clkreg = MCI_CLK_ENABLE, - .clkreg_enable = MCI_ST_UX500_HWFCEN, - .datalength_bits = 24, - .sdio = true, - .st_clkdiv = true, -}; - -static struct variant_data variant_ux500v2 = { - .fifosize = 30 * 4, - .fifohalfsize = 8 * 4, - .clkreg = MCI_CLK_ENABLE, - .clkreg_enable = MCI_ST_UX500_HWFCEN, - .datalength_bits = 24, - .sdio = true, - .st_clkdiv = true, - .blksz_datactrl16 = true, -}; - /* * This must be called with host->lock held */ @@ -1125,7 +1068,7 @@ static const struct mmc_host_ops mmci_ops = { .get_cd = mmci_get_cd, }; -static int __devinit mmci_probe(struct amba_device *dev, +extern int __devinit mmci_probe(struct amba_device *dev, const struct amba_id *id) { struct mmci_platform_data *plat = dev->dev.platform_data; @@ -1376,8 +1319,9 @@ static int __devinit mmci_probe(struct amba_device *dev, out: return ret; } +EXPORT_SYMBOL_GPL(mmci_probe); -static int __devexit mmci_remove(struct amba_device *dev) +extern int __devexit mmci_remove(struct amba_device *dev) { struct mmc_host *mmc = amba_get_drvdata(dev); @@ -1428,9 +1372,10 @@ static int __devexit mmci_remove(struct amba_device *dev) return 0; } +EXPORT_SYMBOL_GPL(mmci_remove); #ifdef CONFIG_PM -static int mmci_suspend(struct amba_device *dev, pm_message_t state) +extern int mmci_suspend(struct amba_device *dev, pm_message_t state) { struct mmc_host *mmc = amba_get_drvdata(dev); int ret = 0; @@ -1445,8 +1390,9 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state) return ret; } +EXPORT_SYMBOL_GPL(mmci_suspend); -static int mmci_resume(struct amba_device *dev) +extern int mmci_resume(struct amba_device *dev) { struct mmc_host *mmc = amba_get_drvdata(dev); int ret = 0; @@ -1461,6 +1407,7 @@ static int mmci_resume(struct amba_device *dev) return ret; } +EXPORT_SYMBOL_GPL(mmci_resume); #else #define mmci_suspend NULL #define mmci_resume NULL @@ -1482,27 +1429,6 @@ static struct amba_id mmci_ids[] = { .mask = 0x000fffff, .data = &variant_arm, }, - /* ST Micro variants */ - { - .id = 0x00180180, - .mask = 0x00ffffff, - .data = &variant_u300, - }, - { - .id = 0x00280180, - .mask = 0x00ffffff, - .data = &variant_u300, - }, - { - .id = 0x00480180, - .mask = 0xf0ffffff, - .data = &variant_ux500, - }, - { - .id = 0x10480180, - .mask = 0xf0ffffff, - .data = &variant_ux500v2, - }, { 0, 0 }, }; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 79e4143..4ede20d 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -7,6 +7,12 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/amba/mmci.h> +#include <linux/scatterlist.h> +#include <linux/amba/bus.h> + +#define DRIVER_NAME "mmci-pl18x" + #define MMCIPOWER 0x000 #define MCI_PWR_OFF 0x00 #define MCI_PWR_UP 0x02 @@ -162,6 +168,8 @@ #define NR_SG 16 +static unsigned int fmax = 515633; + struct clk; struct variant_data; struct dma_chan; @@ -218,3 +226,32 @@ struct mmci_host { #endif }; +/** + * struct variant_data - MMCI variant-specific quirks + * @clkreg: default value for MCICLOCK register + * @clkreg_enable: enable value for MMCICLOCK register + * @datalength_bits: number of bits in the MMCIDATALENGTH register + * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY + * is asserted (likewise for RX) + * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY + * is asserted (likewise for RX) + * @sdio: variant supports SDIO + * @st_clkdiv: true if using a ST-specific clock divider algorithm + * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + */ +struct variant_data { + unsigned int clkreg; + unsigned int clkreg_enable; + unsigned int datalength_bits; + unsigned int fifosize; + unsigned int fifohalfsize; + bool sdio; + bool st_clkdiv; + bool blksz_datactrl16; +}; + +extern int __devinit mmci_probe(struct amba_device *dev, + const struct amba_id *id); +extern int __devexit mmci_remove(struct amba_device *dev); +extern int mmci_suspend(struct amba_device *dev, pm_message_t state); +extern int mmci_resume(struct amba_device *dev); -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html