From: Russell King - ARM Linux <linux@arm.linux.org.uk>
To: Tony Lindgren <tony@atomide.com>
Cc: Madhusudhan Chikkature <madhu.cr@ti.com>,
linux-omap@vger.kernel.org, Pierre Ossman <drzeus-list@drzeus.cx>,
"Jarkko Lavinen (NMP/Helsinki)" <jarkko.lavinen@nokia.com>,
Carlos Aguiar <carlos.aguiar@indt.org.br>
Subject: Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
Date: Sat, 13 Sep 2008 10:59:46 +0100 [thread overview]
Message-ID: <20080913095946.GA24437@flint.arm.linux.org.uk> (raw)
In-Reply-To: <20080912004848.GO21163@atomide.com>
On Thu, Sep 11, 2008 at 05:48:49PM -0700, Tony Lindgren wrote:
> +static inline void omap1_mmc_mux(struct omap_mmc_platform_data *info)
> +{
> + if (info->slots[0].enabled) {
> + omap_cfg_reg(MMC_CMD);
> + omap_cfg_reg(MMC_CLK);
> + omap_cfg_reg(MMC_DAT0);
> + if (cpu_is_omap1710()) {
> + omap_cfg_reg(M15_1710_MMC_CLKI);
> + omap_cfg_reg(P19_1710_MMC_CMDDIR);
> + omap_cfg_reg(P20_1710_MMC_DATDIR0);
> + }
> + if (info->slots[0].wire4) {
> + omap_cfg_reg(MMC_DAT1);
> + /* NOTE: DAT2 can be on W10 (here) or M15 */
> + if (!info->slots[0].nomux)
> + omap_cfg_reg(MMC_DAT2);
> + omap_cfg_reg(MMC_DAT3);
> + }
> + }
> +
> + /* Block 2 is on newer chips, and has many pinout options */
> + if (cpu_is_omap16xx() && info->slots[1].enabled) {
> + if (!info->slots[1].nomux) {
> + omap_cfg_reg(Y8_1610_MMC2_CMD);
> + omap_cfg_reg(Y10_1610_MMC2_CLK);
> + omap_cfg_reg(R18_1610_MMC2_CLKIN);
> + omap_cfg_reg(W8_1610_MMC2_DAT0);
> + if (info->slots[1].wire4) {
> + omap_cfg_reg(V8_1610_MMC2_DAT1);
> + omap_cfg_reg(W15_1610_MMC2_DAT2);
> + omap_cfg_reg(R10_1610_MMC2_DAT3);
> + }
> +
> + /* These are needed for the level shifter */
> + omap_cfg_reg(V9_1610_MMC2_CMDDIR);
> + omap_cfg_reg(V5_1610_MMC2_DATDIR0);
> + omap_cfg_reg(W19_1610_MMC2_DATDIR1);
> + }
> +
> + /* Feedback clock must be set on OMAP-1710 MMC2 */
> + if (cpu_is_omap1710())
> + omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
> + MOD_CONF_CTRL_1);
> + }
> +}
> +
> +void omap1_init_mmc(struct omap_mmc_platform_data *info)
> +{
> + if (!info)
> + return;
> +
> + omap1_mmc_mux(info);
> + platform_set_drvdata(&omap1_mmc1_device, info);
> +
> + if (cpu_is_omap16xx())
> + platform_set_drvdata(OMAP1_MMC2_DEVICE, info);
> +
> + omap_init_mmc(info, &omap1_mmc1_device, OMAP1_MMC2_DEVICE);
> +}
> +
> +#endif
> +
> +/*-------------------------------------------------------------------------*/
> +
> #if defined(CONFIG_OMAP_STI)
>
> #define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
> @@ -203,6 +205,113 @@ static inline void omap_init_mcspi(void) {}
>
> /*-------------------------------------------------------------------------*/
>
> +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
> + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
> +
> +#define OMAP2_MMC1_BASE 0x4809c000
> +#define OMAP2_MMC1_END (OMAP2_MMC1_BASE + 0x1fc)
> +#define OMAP2_MMC1_INT INT_24XX_MMC_IRQ
> +
> +#define OMAP2_MMC2_BASE 0x480b4000
> +#define OMAP2_MMC2_END (OMAP2_MMC2_BASE + 0x1fc)
> +#define OMAP2_MMC2_INT INT_24XX_MMC2_IRQ
> +
> +static u64 omap2_mmc1_dmamask = 0xffffffff;
> +
> +static struct resource omap2_mmc1_resources[] = {
> + {
> + .start = OMAP2_MMC1_BASE,
> + .end = OMAP2_MMC1_END,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = OMAP2_MMC1_INT,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct platform_device omap2_mmc1_device = {
> + .name = "mmci-omap",
> + .id = 1,
> + .dev = {
> + .dma_mask = &omap2_mmc1_dmamask,
> + },
> + .num_resources = ARRAY_SIZE(omap2_mmc1_resources),
> + .resource = omap2_mmc1_resources,
> +};
> +
> +static u64 omap2_mmc2_dmamask = 0xffffffff;
> +
> +static struct resource omap2_mmc2_resources[] = {
> + {
> + .start = OMAP2_MMC2_BASE,
> + .end = OMAP2_MMC2_END,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = OMAP2_MMC2_INT,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct platform_device omap2_mmc2_device = {
> + .name = "mmci-omap",
> + .id = 2,
> + .dev = {
> + .dma_mask = &omap2_mmc2_dmamask,
> + },
> + .num_resources = ARRAY_SIZE(omap2_mmc2_resources),
> + .resource = omap2_mmc2_resources,
> +};
> +
> +static inline void omap2_mmc_mux(struct omap_mmc_platform_data *info)
> +{
> + if (!cpu_is_omap2420())
> + return;
> +
> + if (info->slots[0].enabled) {
> + omap_cfg_reg(H18_24XX_MMC_CMD);
> + omap_cfg_reg(H15_24XX_MMC_CLKI);
> + omap_cfg_reg(G19_24XX_MMC_CLKO);
> + omap_cfg_reg(F20_24XX_MMC_DAT0);
> + omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
> + omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
> + if (info->slots[0].wire4) {
> + omap_cfg_reg(H14_24XX_MMC_DAT1);
> + omap_cfg_reg(E19_24XX_MMC_DAT2);
> + omap_cfg_reg(D19_24XX_MMC_DAT3);
> + omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
> + omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
> + omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
> + }
> +
> + /*
> + * Use internal loop-back in MMC/SDIO Module Input Clock
> + * selection
> + */
> + if (info->slots[0].internal_clock) {
> + u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
> + v |= (1 << 24);
> + omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
> + }
> + }
> +}
> +
> +void omap2_init_mmc(struct omap_mmc_platform_data *info)
> +{
> + if (!info)
> + return;
> +
> + omap2_mmc_mux(info);
> + omap2_mmc1_device.dev.platform_data = info;
> + omap2_mmc2_device.dev.platform_data = info;
> + omap_init_mmc(info, &omap2_mmc1_device, &omap2_mmc2_device);
> +}
> +
> +#endif
> +
> +/*-------------------------------------------------------------------------*/
> +
> static int __init omap2_init_devices(void)
> {
> /* please keep these calls, and their implementations above,
Hmm.
How about, in arch/arm/plat-omap/devices.c:
static int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
unsigned int irq, struct omap_mmc_platform_data *data)
{
struct platform_device *dev;
struct resource res[2];
int ret;
dev = platform_device_alloc("mmci-omap", id);
if (!dev)
return -ENOMEM;
res[0].start = base;
res[0].end = base + size - 1;
res[0].flags = IORESOURCE_MEM;
res[1].start = res[1].end = irq;
res[1].flags = IORESOURCE_IRQ;
ret = platform_device_add_resources(dev, res, ARRAY_SIZE(res));
if (ret == 0)
ret = platform_device_add_data(dev, data, sizeof(*data));
if (ret)
goto fail;
ret = platform_device_add(dev);
if (ret)
goto fail;
return 0;
fail:
platform_device_put(dev);
return ret;
}
Now, for OMAP1 all you need, apart from the MUX function, is:
void omap1_init_mmc(struct omap_mmc_platform_data *info)
{
omap1_mmc_mux(info);
if (info->slots[0].enabled)
omap_mmc_add(0, OMAP1_MMC1_BASE, 0x7f, OMAP1_MMC1_INT, info);
if (cpu_is_omap16xx() && info->slots[1].enabled)
omap_mmc_add(1, OMAP1_MMC2_BASE, 0x7f, OMAP1_MMC2_INT, info);
}
And OMAP2 looks like this:
void omap2_init_mmc(struct omap_mmc_platform_data *info)
{
omap2_mmc_mux(info);
if (info->slots[0].enabled)
omap_mmc_add(0, OMAP2_MMC1_BASE, 0x1fc, OMAP2_MMC1_INT, info);
if (info->slots[1].enabled)
omap_mmc_add(1, OMAP2_MMC2_BASE, 0x1fc, OMAP2_MMC2_INT, info);
}
Maybe these functions should also be taking note of info->nr_slots?
Though I don't particularly like the way 'info' is shared between both
controllers. It's more usual to pass a data structure to drivers
describing just the data for _this_ instance of the device.
Now, when you come across a device with three controllers, you're not
modifying arch/arm/plat-omap/devices.c to add that third controller -
you're just creating the omapN_init_mmc() function with another
omap_mmc_add() line.
As an added bonus, notice the lack of nasty #ifdef's scattered in there
as well.
Oh, and I see little reason for checking for NULL data in these functions -
they clearly don't take NULL data, and if someone passes NULL data, they
deserve to oops - and hopefully they'll fix their code.
next prev parent reply other threads:[~2008-09-13 10:00 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-13 6:13 [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Madhusudhan Chikkature
2008-09-10 23:56 ` Tony Lindgren
2008-09-11 8:48 ` Russell King - ARM Linux
2008-09-11 9:13 ` Russell King - ARM Linux
2008-09-11 17:33 ` Tony Lindgren
2008-09-11 18:13 ` Russell King - ARM Linux
2008-09-11 21:18 ` Steve Sakoman
2008-09-12 8:04 ` Felipe Balbi
2008-09-12 0:48 ` [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data) Tony Lindgren
2008-09-13 9:59 ` Russell King - ARM Linux [this message]
2008-09-13 17:11 ` Tony Lindgren
2008-09-16 23:13 ` Tony Lindgren
2008-09-17 1:52 ` Tony Lindgren
2008-09-17 7:57 ` Russell King - ARM Linux
2008-09-24 9:02 ` Tony Lindgren
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
2008-09-11 11:35 ` Felipe Balbi
2008-09-20 10:02 ` Pierre Ossman
2008-09-11 19:53 ` Tony Lindgren
2008-09-12 12:32 ` Madhusudhan Chikkature
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080913095946.GA24437@flint.arm.linux.org.uk \
--to=linux@arm.linux.org.uk \
--cc=carlos.aguiar@indt.org.br \
--cc=drzeus-list@drzeus.cx \
--cc=jarkko.lavinen@nokia.com \
--cc=linux-omap@vger.kernel.org \
--cc=madhu.cr@ti.com \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox