@@ -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
new file mode 100644
@@ -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");
@@ -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 },
};
@@ -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);
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@linaro.org> --- 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