On 28 September 2015 at 08:35, Yangbo Lu <yangbo...@freescale.com> wrote:
> To support little endian eSDHC controller, we redefine both BE and
> LE IO accessors. In the new accessors, use ioread*/iowrite* instead
> of in_be32/out_be32 and will select accessors according to endian
> mode in probe function.
>
> Signed-off-by: Yangbo Lu <yangbo...@freescale.com>
> ---

It's good practice to provide the reviewers with some history of what
has been changed between each revision. Can you please add that future
wise.

>  drivers/mmc/host/sdhci-esdhc.h    |   2 +
>  drivers/mmc/host/sdhci-of-esdhc.c | 436 
> ++++++++++++++++++++++++++++----------
>  2 files changed, 324 insertions(+), 114 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 163ac99..de132e2 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -24,6 +24,8 @@
>                                 SDHCI_QUIRK_PIO_NEEDS_DELAY | \
>                                 SDHCI_QUIRK_NO_HISPD_BIT)
>
> +#define ESDHC_PROCTL           0x28
> +
>  #define ESDHC_SYSTEM_CONTROL   0x2c
>  #define ESDHC_CLOCK_MASK       0x0000fff0
>  #define ESDHC_PREDIV_SHIFT     8
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c 
> b/drivers/mmc/host/sdhci-of-esdhc.c
> index 2a54dbe..5315864 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -18,128 +18,326 @@
>  #include <linux/of.h>
>  #include <linux/delay.h>
>  #include <linux/module.h>
> +#include <linux/slab.h>
>  #include <linux/mmc/host.h>
>  #include "sdhci-pltfm.h"
>  #include "sdhci-esdhc.h"
>
>  #define VENDOR_V_22    0x12
>  #define VENDOR_V_23    0x13
> -static u32 esdhc_readl(struct sdhci_host *host, int reg)
> +
> +struct esdhc_host {
> +       u8 vendor_ver;
> +       u8 spec_ver;
> +       u16 xfer_mode_shadow;
> +       struct sdhci_host *host;
> +};
> +
> +static struct esdhc_host *esdhc;

This looks wrong, you shouldn't have a global variable for this.
Instead, I think you shall allocate one per device/host.

> +
> +/**
> + * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register
> + *                    to make it compatible with SD spec.
> + *
> + * @esdhc: pointer to esdhc_host
> + * @spec_reg: SD spec register address
> + * @value: 32bit eSDHC register value on spec_reg address
> + *
> + * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
> + * registers are 32 bits. There are differences in register size, register
> + * address, register function, bit position and function between eSDHC spec
> + * and SD spec.
> + *
> + * Return a fixed up register value
> + */
> +static u32 esdhc_readl_fixup(struct esdhc_host *esdhc,
> +                                    int spec_reg, u32 value)
>  {
>         u32 ret;
>
> -       ret = in_be32(host->ioaddr + reg);
>         /*
>          * The bit of ADMA flag in eSDHC is not compatible with standard
>          * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
>          * supported by eSDHC.
>          * And for many FSL eSDHC controller, the reset value of field
> -        * SDHCI_CAN_DO_ADMA1 is one, but some of them can't support ADMA,
> +        * SDHCI_CAN_DO_ADMA1 is 1, but some of them can't support ADMA,
>          * only these vendor version is greater than 2.2/0x12 support ADMA.
> -        * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the
> -        * the verdor version number, oxFE is SDHCI_HOST_VERSION.
>          */
> -       if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) {
> -               u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
> -               tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> -               if (tmp > VENDOR_V_22)
> -                       ret |= SDHCI_CAN_DO_ADMA2;
> +       if ((spec_reg == SDHCI_CAPABILITIES) && (value & SDHCI_CAN_DO_ADMA1)) 
> {
> +               if (esdhc->vendor_ver > VENDOR_V_22) {
> +                       ret = value | SDHCI_CAN_DO_ADMA2;
> +                       return ret;
> +               }
>         }
> -
> +       ret = value;
>         return ret;
>  }
>
> -static u16 esdhc_readw(struct sdhci_host *host, int reg)
> +static u16 esdhc_readw_fixup(struct esdhc_host *esdhc,
> +                                    int spec_reg, u32 value)
>  {
>         u16 ret;
> -       int base = reg & ~0x3;
> -       int shift = (reg & 0x2) * 8;
> +       int shift = (spec_reg & 0x2) * 8;
>
> -       if (unlikely(reg == SDHCI_HOST_VERSION))
> -               ret = in_be32(host->ioaddr + base) & 0xffff;
> +       if (spec_reg == SDHCI_HOST_VERSION)
> +               ret = value & 0xffff;
>         else
> -               ret = (in_be32(host->ioaddr + base) >> shift) & 0xffff;
> +               ret = (value >> shift) & 0xffff;
>         return ret;
>  }
>
> -static u8 esdhc_readb(struct sdhci_host *host, int reg)
> +static u8 esdhc_readb_fixup(struct esdhc_host *esdhc,
> +                                    int spec_reg, u32 value)
>  {
> -       int base = reg & ~0x3;
> -       int shift = (reg & 0x3) * 8;
> -       u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff;
> +       u8 ret;
> +       u8 dma_bits;
> +       int shift = (spec_reg & 0x3) * 8;
> +
> +       ret = (value >> shift) & 0xff;
>
>         /*
>          * "DMA select" locates at offset 0x28 in SD specification, but on
>          * P5020 or P3041, it locates at 0x29.
>          */
> -       if (reg == SDHCI_HOST_CONTROL) {
> -               u32 dma_bits;
> -
> -               dma_bits = in_be32(host->ioaddr + reg);
> +       if (spec_reg == SDHCI_HOST_CONTROL) {
>                 /* DMA select is 22,23 bits in Protocol Control Register */
> -               dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK;
> -
> +               dma_bits = (value >> 5) & SDHCI_CTRL_DMA_MASK;
>                 /* fixup the result */
>                 ret &= ~SDHCI_CTRL_DMA_MASK;
>                 ret |= dma_bits;
>         }
> -
>         return ret;
>  }
>
> -static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
> +/**
> + * esdhc_write*_fixup - Fixup the SD spec register value so that it could be
> + *                     written into eSDHC register.
> + *
> + * @esdhc: pointer to esdhc_host
> + * @spec_reg: SD spec register address
> + * @value: 8/16/32bit SD spec register value that would be written
> + * @old_value: 32bit eSDHC register value on spec_reg address
> + *
> + * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
> + * registers are 32 bits. There are differences in register size, register
> + * address, register function, bit position and function between eSDHC spec
> + * and SD spec.
> + *
> + * Return a fixed up register value
> + */
> +static u32 esdhc_writel_fixup(struct esdhc_host *esdhc,
> +                                    int spec_reg, u32 value, u32 old_value)
>  {
> +       u32 ret;
> +
>         /*
> -        * Enable IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
> -        * when SYSCTL[RSTD]) is set for some special operations.
> -        * No any impact other operation.
> +        * Enabling IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
> +        * when SYSCTL[RSTD] is set for some special operations.
> +        * No any impact on other operation.
>          */
> -       if (reg == SDHCI_INT_ENABLE)
> -               val |= SDHCI_INT_BLK_GAP;
> -       sdhci_be32bs_writel(host, val, reg);
> +       if (spec_reg == SDHCI_INT_ENABLE)
> +               ret = value | SDHCI_INT_BLK_GAP;
> +       else
> +               ret = value;
> +
> +       return ret;
>  }
>
> -static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
> +static u32 esdhc_writew_fixup(struct esdhc_host *esdhc,
> +                                    int spec_reg, u16 value, u32 old_value)
>  {
> -       if (reg == SDHCI_BLOCK_SIZE) {
> +       u32 ret;
> +       int shift = (spec_reg & 0x2) * 8;
> +
> +       switch (spec_reg) {
> +       case SDHCI_TRANSFER_MODE:
> +               /*
> +                * Postpone this write, we must do it together with a
> +                * command write that is down below. Return old value.
> +                */
> +               esdhc->xfer_mode_shadow = value;
> +               return old_value;
> +       case SDHCI_COMMAND:
> +               ret = (value << 16) | esdhc->xfer_mode_shadow;
> +               return ret;
> +       }
> +
> +       ret = old_value & (~(0xffff << shift));
> +       ret |= (value << shift);
> +
> +       if (spec_reg == SDHCI_BLOCK_SIZE) {
>                 /*
>                  * Two last DMA bits are reserved, and first one is used for
>                  * non-standard blksz of 4096 bytes that we don't support
>                  * yet. So clear the DMA boundary bits.
>                  */
> -               val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
> +               ret &= (~SDHCI_MAKE_BLKSZ(0x7, 0));
>         }
> -       sdhci_be32bs_writew(host, val, reg);
> +       return ret;
>  }
>
> -static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
> +static u32 esdhc_writeb_fixup(struct esdhc_host *esdhc,
> +                                    int spec_reg, u8 value, u32 old_value)
>  {
> +       u32 ret;
> +       u32 dma_bits;
> +       u8 tmp;
> +       int shift = (spec_reg & 0x3) * 8;
> +
>         /*
>          * "DMA select" location is offset 0x28 in SD specification, but on
>          * P5020 or P3041, it's located at 0x29.
>          */
> -       if (reg == SDHCI_HOST_CONTROL) {
> -               u32 dma_bits;
> -
> +       if (spec_reg == SDHCI_HOST_CONTROL) {
>                 /*
>                  * If host control register is not standard, exit
>                  * this function
>                  */
> -               if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
> -                       return;
> +               if (esdhc->host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
> +                       return old_value;
>
>                 /* DMA select is 22,23 bits in Protocol Control Register */
> -               dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
> -               clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
> -                       dma_bits);
> -               val &= ~SDHCI_CTRL_DMA_MASK;
> -               val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK;
> +               dma_bits = (value & SDHCI_CTRL_DMA_MASK) << 5;
> +               ret = (old_value & (~(SDHCI_CTRL_DMA_MASK << 5))) | dma_bits;
> +               tmp = (value & (~SDHCI_CTRL_DMA_MASK)) |
> +                     (old_value & SDHCI_CTRL_DMA_MASK);
> +               ret = (ret & (~0xff)) | tmp;
> +
> +               /* Prevent SDHCI core from writing reserved bits (e.g. HISPD) 
> */
> +               ret &= ~ESDHC_HOST_CONTROL_RES;
> +               return ret;
>         }
>
> -       /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
> -       if (reg == SDHCI_HOST_CONTROL)
> -               val &= ~ESDHC_HOST_CONTROL_RES;
> -       sdhci_be32bs_writeb(host, val, reg);
> +       ret = (old_value & (~(0xff << shift))) | (value << shift);
> +       return ret;
> +}
> +
> +static u32 esdhc_be_readl(struct sdhci_host *host, int reg)
> +{
> +       u32 ret;
> +       u32 value;
> +
> +       value = ioread32be(host->ioaddr + reg);
> +       ret = esdhc_readl_fixup(esdhc, reg, value);
> +
> +       return ret;
> +}
> +
> +static u32 esdhc_le_readl(struct sdhci_host *host, int reg)
> +{
> +       u32 ret;
> +       u32 value;
> +
> +       value = ioread32(host->ioaddr + reg);
> +       ret = esdhc_readl_fixup(esdhc, reg, value);
> +
> +       return ret;
> +}
> +
> +static u16 esdhc_be_readw(struct sdhci_host *host, int reg)
> +{
> +       u16 ret;
> +       u32 value;
> +       int base = reg & ~0x3;
> +
> +       value = ioread32be(host->ioaddr + base);
> +       ret = esdhc_readw_fixup(esdhc, reg, value);
> +       return ret;
> +}
> +
> +static u16 esdhc_le_readw(struct sdhci_host *host, int reg)
> +{
> +       u16 ret;
> +       u32 value;
> +       int base = reg & ~0x3;
> +
> +       value = ioread32(host->ioaddr + base);
> +       ret = esdhc_readw_fixup(esdhc, reg, value);
> +       return ret;
> +}
> +
> +static u8 esdhc_be_readb(struct sdhci_host *host, int reg)
> +{
> +       u8 ret;
> +       u32 value;
> +       int base = reg & ~0x3;
> +
> +       value = ioread32be(host->ioaddr + base);
> +       ret = esdhc_readb_fixup(esdhc, reg, value);
> +       return ret;
> +}
> +
> +static u8 esdhc_le_readb(struct sdhci_host *host, int reg)
> +{
> +       u8 ret;
> +       u32 value;
> +       int base = reg & ~0x3;
> +
> +       value = ioread32(host->ioaddr + base);
> +       ret = esdhc_readb_fixup(esdhc, reg, value);
> +       return ret;
> +}
> +
> +static void esdhc_be_writel(struct sdhci_host *host, u32 val, int reg)
> +{
> +       u32 value;
> +
> +       value = esdhc_writel_fixup(esdhc, reg, val, 0);
> +       iowrite32be(value, host->ioaddr + reg);
> +}
> +
> +static void esdhc_le_writel(struct sdhci_host *host, u32 val, int reg)
> +{
> +       u32 value;
> +
> +       value = esdhc_writel_fixup(esdhc, reg, val, 0);
> +       iowrite32(value, host->ioaddr + reg);
> +}
> +
> +static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg)
> +{
> +       int base = reg & ~0x3;
> +       u32 value;
> +       u32 ret;
> +
> +       value = ioread32be(host->ioaddr + base);
> +       ret = esdhc_writew_fixup(esdhc, reg, val, value);
> +       if (reg != SDHCI_TRANSFER_MODE)
> +               iowrite32be(ret, host->ioaddr + base);
> +}
> +
> +static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg)
> +{
> +       int base = reg & ~0x3;
> +       u32 value;
> +       u32 ret;
> +
> +       value = ioread32(host->ioaddr + base);
> +       ret = esdhc_writew_fixup(esdhc, reg, val, value);
> +       if (reg != SDHCI_TRANSFER_MODE)
> +               iowrite32(ret, host->ioaddr + base);
> +}
> +
> +static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg)
> +{
> +       int base = reg & ~0x3;
> +       u32 value;
> +       u32 ret;
> +
> +       value = ioread32be(host->ioaddr + base);
> +       ret = esdhc_writeb_fixup(esdhc, reg, val, value);
> +       iowrite32be(ret, host->ioaddr + base);
> +}
> +
> +static void esdhc_le_writeb(struct sdhci_host *host, u8 val, int reg)
> +{
> +       int base = reg & ~0x3;
> +       u32 value;
> +       u32 ret;
> +
> +       value = ioread32(host->ioaddr + base);
> +       ret = esdhc_writeb_fixup(esdhc, reg, val, value);
> +       iowrite32(ret, host->ioaddr + base);
>  }
>
>  /*
> @@ -149,19 +347,15 @@ static void esdhc_writeb(struct sdhci_host *host, u8 
> val, int reg)
>   * For Continue, apply soft reset for data(SYSCTL[RSTD]);
>   * and re-issue the entire read transaction from beginning.
>   */
> -static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
> +static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask)
>  {
> -       u32 tmp;
>         bool applicable;
>         dma_addr_t dmastart;
>         dma_addr_t dmanow;
>
> -       tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
> -       tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> -
>         applicable = (intmask & SDHCI_INT_DATA_END) &&
> -               (intmask & SDHCI_INT_BLK_GAP) &&
> -               (tmp == VENDOR_V_23);
> +                    (intmask & SDHCI_INT_BLK_GAP) &&
> +                    (esdhc->vendor_ver == VENDOR_V_23);
>         if (!applicable)
>                 return;
>
> @@ -179,7 +373,11 @@ static void esdhci_of_adma_workaround(struct sdhci_host 
> *host, u32 intmask)
>
>  static int esdhc_of_enable_dma(struct sdhci_host *host)
>  {
> -       setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
> +       u32 value;
> +
> +       value = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> +       value |= ESDHC_DMA_SNOOP;
> +       sdhci_writel(host, value, ESDHC_DMA_SYSCTL);
>         return 0;
>  }
>
> @@ -209,9 +407,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, 
> unsigned int clock)
>                 return;
>
>         /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
> -       temp = esdhc_readw(host, SDHCI_HOST_VERSION);
> -       temp = (temp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> -       if (temp < VENDOR_V_23)
> +       if (esdhc->vendor_ver < VENDOR_V_23)
>                 pre_div = 2;
>
>         /* Workaround to reduce the clock frequency for p1010 esdhc */
> @@ -247,39 +443,26 @@ static void esdhc_of_set_clock(struct sdhci_host *host, 
> unsigned int clock)
>         mdelay(1);
>  }
>
> -static void esdhc_of_platform_init(struct sdhci_host *host)
> -{
> -       u32 vvn;
> -
> -       vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
> -       vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> -       if (vvn == VENDOR_V_22)
> -               host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
> -
> -       if (vvn > VENDOR_V_22)
> -               host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
> -}
> -
>  static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
>  {
>         u32 ctrl;
>
> +       ctrl = sdhci_readl(host, ESDHC_PROCTL);
> +       ctrl &= (~ESDHC_CTRL_BUSWIDTH_MASK);
>         switch (width) {
>         case MMC_BUS_WIDTH_8:
> -               ctrl = ESDHC_CTRL_8BITBUS;
> +               ctrl |= ESDHC_CTRL_8BITBUS;
>                 break;
>
>         case MMC_BUS_WIDTH_4:
> -               ctrl = ESDHC_CTRL_4BITBUS;
> +               ctrl |= ESDHC_CTRL_4BITBUS;
>                 break;
>
>         default:
> -               ctrl = 0;
>                 break;
>         }
>
> -       clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
> -                       ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
> +       sdhci_writel(host, ctrl, ESDHC_PROCTL);
>  }
>
>  static void esdhc_reset(struct sdhci_host *host, u8 mask)
> @@ -290,32 +473,13 @@ static void esdhc_reset(struct sdhci_host *host, u8 
> mask)
>         sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>  }
>
> -static const struct sdhci_ops sdhci_esdhc_ops = {
> -       .read_l = esdhc_readl,
> -       .read_w = esdhc_readw,
> -       .read_b = esdhc_readb,
> -       .write_l = esdhc_writel,
> -       .write_w = esdhc_writew,
> -       .write_b = esdhc_writeb,
> -       .set_clock = esdhc_of_set_clock,
> -       .enable_dma = esdhc_of_enable_dma,
> -       .get_max_clock = esdhc_of_get_max_clock,
> -       .get_min_clock = esdhc_of_get_min_clock,
> -       .platform_init = esdhc_of_platform_init,
> -       .adma_workaround = esdhci_of_adma_workaround,
> -       .set_bus_width = esdhc_pltfm_set_bus_width,
> -       .reset = esdhc_reset,
> -       .set_uhs_signaling = sdhci_set_uhs_signaling,
> -};
> -
>  #ifdef CONFIG_PM
> -
>  static u32 esdhc_proctl;
>  static int esdhc_of_suspend(struct device *dev)
>  {
>         struct sdhci_host *host = dev_get_drvdata(dev);
>
> -       esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
> +       esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL);
>
>         return sdhci_suspend_host(host);
>  }
> @@ -328,9 +492,8 @@ static int esdhc_of_resume(struct device *dev)
>         if (ret == 0) {
>                 /* Isn't this already done by sdhci_resume_host() ? --rmk */
>                 esdhc_of_enable_dma(host);
> -               sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
> +               sdhci_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
>         }
> -
>         return ret;
>  }
>
> @@ -343,16 +506,56 @@ static const struct dev_pm_ops esdhc_pmops = {
>  #define ESDHC_PMOPS NULL
>  #endif
>
> -static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
> -       /*
> -        * card detection could be handled via GPIO
> -        * eSDHC cannot support End Attribute in NOP ADMA descriptor
> -        */
> -       .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
> -               | SDHCI_QUIRK_NO_CARD_NO_RESET
> -               | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
> -       .ops = &sdhci_esdhc_ops,
> +static struct sdhci_ops sdhci_esdhc_ops = {
> +       .set_clock = esdhc_of_set_clock,
> +       .enable_dma = esdhc_of_enable_dma,
> +       .get_max_clock = esdhc_of_get_max_clock,
> +       .get_min_clock = esdhc_of_get_min_clock,
> +       .adma_workaround = esdhc_of_adma_workaround,
> +       .set_bus_width = esdhc_pltfm_set_bus_width,
> +       .reset = esdhc_reset,
> +       .set_uhs_signaling = sdhci_set_uhs_signaling,
>  };
> +static struct sdhci_pltfm_data sdhci_esdhc_pdata;
> +
> +static void esdhc_setup_pltfm_data(struct platform_device *pdev)
> +{
> +       struct device_node *np;
> +
> +       np = pdev->dev.of_node;
> +       if (of_get_property(np, "little-endian", NULL)) {
> +               sdhci_esdhc_ops.read_l  = esdhc_le_readl;
> +               sdhci_esdhc_ops.read_w  = esdhc_le_readw;
> +               sdhci_esdhc_ops.read_b  = esdhc_le_readb;
> +               sdhci_esdhc_ops.write_l = esdhc_le_writel;
> +               sdhci_esdhc_ops.write_w = esdhc_le_writew;
> +               sdhci_esdhc_ops.write_b = esdhc_le_writeb;
> +       } else {
> +               sdhci_esdhc_ops.read_l  = esdhc_be_readl;
> +               sdhci_esdhc_ops.read_w  = esdhc_be_readw;
> +               sdhci_esdhc_ops.read_b  = esdhc_be_readb;
> +               sdhci_esdhc_ops.write_l = esdhc_be_writel;
> +               sdhci_esdhc_ops.write_w = esdhc_be_writew;
> +               sdhci_esdhc_ops.write_b = esdhc_be_writeb;
> +       }
> +
> +       sdhci_esdhc_pdata.quirks = ESDHC_DEFAULT_QUIRKS |
> +                                  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
> +                                  SDHCI_QUIRK_NO_CARD_NO_RESET |
> +                                  SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
> +       sdhci_esdhc_pdata.ops = &sdhci_esdhc_ops;
> +}
> +
> +static void esdhc_init(struct esdhc_host *esdhc, struct sdhci_host *host)
> +{
> +       u16 host_ver;
> +
> +       host_ver = sdhci_readw(host, SDHCI_HOST_VERSION);
> +       esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
> +                            SDHCI_VENDOR_VER_SHIFT;
> +       esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
> +       esdhc->host = host;
> +}
>
>  static int sdhci_esdhc_probe(struct platform_device *pdev)
>  {
> @@ -360,10 +563,15 @@ static int sdhci_esdhc_probe(struct platform_device 
> *pdev)
>         struct device_node *np;
>         int ret;
>
> +       esdhc_setup_pltfm_data(pdev);
> +
>         host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0);
>         if (IS_ERR(host))
>                 return PTR_ERR(host);
>
> +       esdhc = kmalloc(sizeof(struct esdhc_host), GFP_KERNEL);

I think it's better to use devm_kzalloc(), thus you don't have to take
care of freeing data since that's handled automatically for the devm
APIs.

> +       esdhc_init(esdhc, host);
> +
>         sdhci_get_of_property(pdev);
>
>         np = pdev->dev.of_node;
> --
> 2.1.0.27.g96db324
>

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to