Hi, Sorry about that I forgot the base gets shifted there. I dont like tihs implementation too much though as I want to keep knowledge of the bus shift out of as muich code as possible. (currently none of the other tmio MFD cores know about it). Could you give this a whirl on top of my current patchset and see if it fixes things for you? I think the odds of a machine existing that needs two different bus shifts for two different tmio MFDs is vanishingly small and this code still allows us to build a kernel that supports machines with differing bus shifts to each other... 2009/9/30 Philipp Zabel <philipp.zabel@xxxxxxxxx>: > Am Dienstag, den 29.09.2009, 13:52 +0100 schrieb Ian Molton: >> Hi guys, >> >> This is the full TMIO MMC patchset, compiled, tested, checkpatch passed. > > With bus shift support dropped from the SD_CONFIG register accessors, I > can't use this as-is on ASIC3. What do you think about the following > (sketch of a) patch to add it back? > > regards > Philipp > > diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h > index a206a8d..89042d6 100644 > --- a/include/linux/mfd/tmio.h > +++ b/include/linux/mfd/tmio.h > @@ -40,14 +40,38 @@ > > #define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ > > -#define sd_config_write8(a, b) tmio_iowrite8((b), (a)) > -#define sd_config_write16(a, b) tmio_iowrite16((b), (a)) > -#define sd_config_write32(a, b) tmio_iowrite32((b), (a)) > - > -int tmio_core_mmc_enable(void __iomem *cnf, unsigned long base); > -int tmio_core_mmc_resume(void __iomem *cnf, unsigned long base); > -void tmio_core_mmc_pwr(void __iomem *cnf, int state); > -void tmio_core_mmc_clk_div(void __iomem *cnf, int state); > +/* > + * data for the tmio_core_mmc functions (CONFIG regs) > + */ > +struct tmio_core_mmc { > + void __iomem *cnf; > + int bus_shift; > + unsigned long base; > +}; > + > +static inline void sd_config_write8(struct tmio_core_mmc *sd_config, int addr, > + u8 val) > +{ > + writeb(val, sd_config->cnf + (addr << sd_config->bus_shift)); > +} > + > +static inline void sd_config_write16(struct tmio_core_mmc *sd_config, int addr, > + u16 val) > +{ > + writew(val, sd_config->cnf + (addr << sd_config->bus_shift)); > +} > + > +static inline void sd_config_write32(struct tmio_core_mmc *sd_config, int addr, > + u32 val) > +{ > + writew(val, sd_config->cnf + (addr << sd_config->bus_shift)); > + writew(val >> 16, sd_config->cnf + ((addr + 2) << sd_config->bus_shift)); > +} > + > +int tmio_core_mmc_enable(struct tmio_core_mmc *sd_config); > +int tmio_core_mmc_resume(struct tmio_core_mmc *sd_config); > +void tmio_core_mmc_pwr(struct tmio_core_mmc *sd_config, int state); > +void tmio_core_mmc_clk_div(struct tmio_core_mmc *sd_config, int state); > > /* > * data for the MMC controller > diff --git a/drivers/mfd/tmio_core.c b/drivers/mfd/tmio_core.c > index 483fbbb..7abb997 100644 > --- a/drivers/mfd/tmio_core.c > +++ b/drivers/mfd/tmio_core.c > @@ -10,45 +10,45 @@ > > #include <linux/mfd/tmio.h> > > -int tmio_core_mmc_enable(void __iomem *cnf, unsigned long base) > +int tmio_core_mmc_enable(struct tmio_core_mmc *sd_config, unsigned long base) > { > /* Enable the MMC/SD Control registers */ > - sd_config_write16(cnf + CNF_CMD, SDCREN); > - sd_config_write32(cnf + CNF_CTL_BASE, base & 0xfffe); > + sd_config_write16(sd_config, CNF_CMD, SDCREN); > + sd_config_write32(sd_config, CNF_CTL_BASE, base & 0xfffe); > > /* Disable SD power during suspend */ > - sd_config_write8(cnf + CNF_PWR_CTL_3, 0x01); > + sd_config_write8(sd_config, CNF_PWR_CTL_3, 0x01); > > /* The below is required but why? FIXME */ > - sd_config_write8(cnf + CNF_STOP_CLK_CTL, 0x1f); > + sd_config_write8(sd_config, CNF_STOP_CLK_CTL, 0x1f); > > /* Power down SD bus*/ > - sd_config_write8(cnf + CNF_PWR_CTL_2, 0x00); > + sd_config_write8(sd_config, CNF_PWR_CTL_2, 0x00); > > return 0; > } > EXPORT_SYMBOL(tmio_core_mmc_enable); > > -int tmio_core_mmc_resume(void __iomem *cnf, unsigned long base) > +int tmio_core_mmc_resume(struct tmio_core_mmc *sd_config, unsigned long base) > { > > /* Enable the MMC/SD Control registers */ > - sd_config_write16(cnf + CNF_CMD, SDCREN); > - sd_config_write32(cnf + CNF_CTL_BASE, base & 0xfffe); > + sd_config_write16(sd_config, CNF_CMD, SDCREN); > + sd_config_write32(sd_config, CNF_CTL_BASE, base & 0xfffe); > > return 0; > } > EXPORT_SYMBOL(tmio_core_mmc_resume); > > -void tmio_core_mmc_pwr(void __iomem *cnf, int state) > +void tmio_core_mmc_pwr(struct tmio_core_mmc *sd_config, int state) > { > - sd_config_write8(cnf + CNF_PWR_CTL_2, state ? 0x02 : 0x00); > + sd_config_write8(sd_config, CNF_PWR_CTL_2, state ? 0x02 : 0x00); > } > EXPORT_SYMBOL(tmio_core_mmc_pwr); > > -void tmio_core_mmc_clk_div(void __iomem *cnf, int state) > +void tmio_core_mmc_clk_div(struct tmio_core_mmc *sd_config, int state) > { > - sd_config_write8(cnf + CNF_SD_CLK_MODE, state ? 1 : 0); > + sd_config_write8(sd_config, CNF_SD_CLK_MODE, state ? 1 : 0); > } > EXPORT_SYMBOL(tmio_core_mmc_clk_div); > > diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c > index fa8da02..520effe 100644 > --- a/drivers/mfd/tc6387xb.c > +++ b/drivers/mfd/tc6387xb.c > @@ -26,10 +26,9 @@ struct tc6387xb { > void __iomem *scr; > struct clk *clk32k; > struct resource rscr; > + struct tmio_core_mmc sd_config; > }; > > -static struct resource tc6387xb_mmc_resources[]; > - > /*--------------------------------------------------------------------------*/ > > #ifdef CONFIG_PM > @@ -54,8 +53,7 @@ static int tc6387xb_resume(struct platform_device *dev) > if (pdata && pdata->resume) > pdata->resume(dev); > > - tmio_core_mmc_resume(tc6387xb->scr + 0x200, > - tc6387xb_mmc_resources[0].start & 0xfffe); > + tmio_core_mmc_resume(&tc6387xb->sd_config); > > return 0; > } > @@ -71,7 +69,7 @@ static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state) > struct platform_device *dev = to_platform_device(mmc->dev.parent); > struct tc6387xb *tc6387xb = platform_get_drvdata(dev); > > - tmio_core_mmc_pwr(tc6387xb->scr + 0x200, state); > + tmio_core_mmc_pwr(&tc6387xb->sd_config, state); > } > > static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state) > @@ -79,7 +77,7 @@ static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state) > struct platform_device *dev = to_platform_device(mmc->dev.parent); > struct tc6387xb *tc6387xb = platform_get_drvdata(dev); > > - tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, state); > + tmio_core_mmc_clk_div(&tc6387xb->sd_config, state); > } > > > @@ -90,8 +88,7 @@ static int tc6387xb_mmc_enable(struct platform_device *mmc) > > clk_enable(tc6387xb->clk32k); > > - tmio_core_mmc_enable(tc6387xb->scr + 0x200, > - tc6387xb_mmc_resources[0].start & 0xfffe); > + tmio_core_mmc_enable(&tc6387xb->sd_config); > > return 0; > } > @@ -196,6 +193,9 @@ static int tc6387xb_probe(struct platform_device *dev) > tc6387xb_cells[TC6387XB_CELL_MMC].data_size = > sizeof(tc6387xb_cells[TC6387XB_CELL_MMC]); > > + tc6387xb->sd_config.cnf = tc6387xb->scr + 0x200; > + tc6387xb->sd_config.base = tc6387xb_mmc_resources[0].start & 0xfffe; > + > ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, > ARRAY_SIZE(tc6387xb_cells), iomem, irq); > > > > > -- Ian Molton Linux, Automotive, and other hacking: http://www.mnementh.co.uk/
diff --git a/drivers/mfd/tmio_core.c b/drivers/mfd/tmio_core.c index 483fbbb..9b0f660 100644 --- a/drivers/mfd/tmio_core.c +++ b/drivers/mfd/tmio_core.c @@ -10,20 +10,22 @@ #include <linux/mfd/tmio.h> +static int shift; + int tmio_core_mmc_enable(void __iomem *cnf, unsigned long base) { /* Enable the MMC/SD Control registers */ - sd_config_write16(cnf + CNF_CMD, SDCREN); - sd_config_write32(cnf + CNF_CTL_BASE, base & 0xfffe); + sd_config_write16(cnf, shift, CNF_CMD, SDCREN); + sd_config_write32(cnf, shift, CNF_CTL_BASE, ((base << shift) & 0xfffe)); /* Disable SD power during suspend */ - sd_config_write8(cnf + CNF_PWR_CTL_3, 0x01); + sd_config_write8(cnf, shift, CNF_PWR_CTL_3, 0x01); /* The below is required but why? FIXME */ - sd_config_write8(cnf + CNF_STOP_CLK_CTL, 0x1f); + sd_config_write8(cnf, shift, CNF_STOP_CLK_CTL, 0x1f); /* Power down SD bus*/ - sd_config_write8(cnf + CNF_PWR_CTL_2, 0x00); + sd_config_write8(cnf, shift, CNF_PWR_CTL_2, 0x00); return 0; } @@ -33,8 +35,8 @@ int tmio_core_mmc_resume(void __iomem *cnf, unsigned long base) { /* Enable the MMC/SD Control registers */ - sd_config_write16(cnf + CNF_CMD, SDCREN); - sd_config_write32(cnf + CNF_CTL_BASE, base & 0xfffe); + sd_config_write16(cnf, shift, CNF_CMD, SDCREN); + sd_config_write32(cnf, shift, CNF_CTL_BASE, (base << shift) & 0xfffe); return 0; } @@ -42,13 +44,19 @@ EXPORT_SYMBOL(tmio_core_mmc_resume); void tmio_core_mmc_pwr(void __iomem *cnf, int state) { - sd_config_write8(cnf + CNF_PWR_CTL_2, state ? 0x02 : 0x00); + sd_config_write8(cnf, shift, CNF_PWR_CTL_2, state ? 0x02 : 0x00); } EXPORT_SYMBOL(tmio_core_mmc_pwr); void tmio_core_mmc_clk_div(void __iomem *cnf, int state) { - sd_config_write8(cnf + CNF_SD_CLK_MODE, state ? 1 : 0); + sd_config_write8(cnf, shift, CNF_SD_CLK_MODE, state ? 1 : 0); } EXPORT_SYMBOL(tmio_core_mmc_clk_div); +void tmio_core_set_bus_shift(int bus_shift) +{ + shift = bus_shift; +} +EXPORT_SYMBOL(tmio_core_set_bus_shift); + diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index a206a8d..796b3b3 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -40,9 +40,12 @@ #define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ -#define sd_config_write8(a, b) tmio_iowrite8((b), (a)) -#define sd_config_write16(a, b) tmio_iowrite16((b), (a)) -#define sd_config_write32(a, b) tmio_iowrite32((b), (a)) +#define sd_config_write8(base, shift, reg, val) \ + tmio_iowrite8((val), (base) + ((reg) << (shift))) +#define sd_config_write16(base, shift, reg, val) \ + tmio_iowrite16((val), (base) + ((reg) << (shift))) +#define sd_config_write32(base, shift, reg, val) \ + tmio_iowrite32((val), (base) + ((reg) << (shift))) int tmio_core_mmc_enable(void __iomem *cnf, unsigned long base); int tmio_core_mmc_resume(void __iomem *cnf, unsigned long base);