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 <[email protected]>:
> 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);