Commit 8e007b6b authored by David Brownell's avatar David Brownell Committed by Kevin Hilman

davinci_mmc platform_data

Inital support for new MMC init logic, where boards can say how
to initialize what, and also provide functions to sense card
detect and writeprotect switches.  This also removes some
static driver configuration forcing it to always use 4-bit
parallel data channels; boards can now override that.

This patch stubs in support for the two EVM boards with MMC/SD
support, equivalent to current behavior ... later patches will
update these.  SFFSDR presumably needs something too.

Note that this doesn't currently handle card detect IRQs.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 69a42b24
......@@ -111,6 +111,8 @@ static __init void dm355_evm_init(void)
davinci_board_config_size = ARRAY_SIZE(davinci_evm_config);
davinci_serial_init();
davinci_setup_mmc(0, NULL);
davinci_setup_mmc(1, NULL);
}
static __init void dm355_evm_irq_init(void)
......
......@@ -503,6 +503,9 @@ static __init void davinci_evm_init(void)
platform_add_devices(davinci_evm_devices,
ARRAY_SIZE(davinci_evm_devices));
evm_init_i2c();
davinci_setup_mmc(0, NULL);
davinci_board_config = davinci_evm_config;
davinci_board_config_size = ARRAY_SIZE(davinci_evm_config);
davinci_serial_init();
......
......@@ -22,6 +22,7 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <mach/board.h>
#include <mach/hardware.h>
#include <mach/edma.h>
#include <mach/emac.h>
......@@ -138,35 +139,47 @@ static struct platform_device davinci_mmcsd1_device = {
};
static void davinci_init_mmcsd(void)
void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
{
if (cpu_is_davinci_dm646x())
struct platform_device *pdev = NULL;
const char *clockname;
if (WARN_ON(cpu_is_davinci_dm646x()))
return;
/* FIXME: only register devices the board tells are wired up.
* And update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
/* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
* for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
*
* FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
* not handled right here ...
*/
if (cpu_is_davinci_dm355()) {
davinci_clk_associate(&davinci_mmcsd1_device.dev, "mmc",
"MMCSDCLK1");
platform_device_register(&davinci_mmcsd1_device);
switch (module) {
case 1:
if (!cpu_is_davinci_dm355())
break;
mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
pdev = &davinci_mmcsd1_device;
clockname = "MMCSDCLK1";
break;
case 0:
pdev = &davinci_mmcsd0_device;
clockname = cpu_is_davinci_dm355() ? "MMCSDCLK0" : "MMCSDCLK";
break;
}
davinci_clk_associate(&davinci_mmcsd0_device.dev, "mmc",
cpu_is_davinci_dm355()
? "MMCSDCLK0"
: "MMCSDCLK");
platform_device_register(&davinci_mmcsd0_device);
if (WARN_ON(!pdev))
return;
pdev->dev.platform_data = config;
davinci_clk_associate(&pdev->dev, "mmc", clockname);
platform_device_register(pdev);
}
#else
static void davinci_init_mmcsd(void) {}
void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
{
}
#endif
......@@ -295,7 +308,6 @@ static int __init davinci_init_devices(void)
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
davinci_init_mmcsd();
davinci_init_wdt();
return 0;
......
......@@ -25,6 +25,15 @@ struct davinci_uart_config {
unsigned int enabled_uarts;
};
struct davinci_mmc_config {
/* get_cd()/get_wp() may sleep */
int (*get_cd)(int module);
int (*get_ro)(int module);
/* wires == 0 is equivalent to wires == 4 (4-bit parallel) */
u8 wires;
};
void davinci_setup_mmc(int module, struct davinci_mmc_config *config);
struct davinci_board_config_entry {
u16 tag;
u16 len;
......
......@@ -42,6 +42,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <mach/board.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
......@@ -68,8 +69,6 @@ static struct mmcsd_config_def mmcsd_cfg = {
32,
/* To use the DMA or not-- 1- Use DMA, 0-Interrupt mode */
1,
/* flag Indicates 1bit/4bit mode */
1
};
#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
......@@ -1189,17 +1188,33 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
static struct mmc_host_ops mmc_davinci_ops = {
.request = mmc_davinci_request,
.set_ios = mmc_davinci_set_ios,
.get_ro = mmc_davinci_get_ro
};
static int mmc_davinci_get_cd(struct mmc_host *mmc)
{
struct platform_device *pdev = to_platform_device(mmc->parent);
struct davinci_mmc_config *config = pdev->dev.platform_data;
if (!config || !config->get_cd)
return -ENOSYS;
return config->get_cd(pdev->id);
}
static int mmc_davinci_get_ro(struct mmc_host *mmc)
{
return 0;
struct platform_device *pdev = to_platform_device(mmc->parent);
struct davinci_mmc_config *config = pdev->dev.platform_data;
if (!config || !config->get_ro)
return -ENOSYS;
return config->get_ro(pdev->id);
}
static struct mmc_host_ops mmc_davinci_ops = {
.request = mmc_davinci_request,
.set_ios = mmc_davinci_set_ios,
.get_cd = mmc_davinci_get_cd,
.get_ro = mmc_davinci_get_ro,
};
static void mmc_check_card(unsigned long data)
{
struct mmc_davinci_host *host = (struct mmc_davinci_host *)data;
......@@ -1290,12 +1305,15 @@ static void init_mmcsd_host(struct mmc_davinci_host *host)
static int davinci_mmcsd_probe(struct platform_device *pdev)
{
struct davinci_mmc_config *pdata = pdev->dev.platform_data;
struct mmc_davinci_host *host = NULL;
struct mmc_host *mmc = NULL;
struct resource *r, *mem = NULL;
int ret = 0, irq = 0;
size_t mem_size;
/* REVISIT: when we're fully converted, fail if pdata is NULL */
ret = -ENODEV;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
......@@ -1345,7 +1363,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev)
init_mmcsd_host(host);
if (mmcsd_cfg.use_4bit_mode)
if (!pdata || pdata->wires == 4 || pdata->wires == 0)
mmc->caps |= MMC_CAP_4_BIT_DATA;
mmc->ops = &mmc_davinci_ops;
......@@ -1402,7 +1420,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev)
dev_info(mmc_dev(host->mmc), "Using %s, %d-bit mode\n",
mmcsd_cfg.use_dma ? "DMA" : "PIO",
mmcsd_cfg.use_4bit_mode ? 4 : 1);
(mmc->caps & MMC_CAP_4_BIT_DATA) ? 4 : 1);
return 0;
......
......@@ -230,7 +230,6 @@ struct mmc_davinci_host {
struct mmcsd_config_def {
unsigned short rw_threshold;
unsigned short use_dma;
unsigned short use_4bit_mode;
};
enum mmcsdevent {
......@@ -257,8 +256,6 @@ static int mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
static void mmc_davinci_xfer_done(struct mmc_davinci_host *host,
struct mmc_data *data);
static int mmc_davinci_get_ro(struct mmc_host *mmc);
static void davinci_abort_dma(struct mmc_davinci_host *host);
#endif /* DAVINCI_MMC_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment