diff mbox

[v5] powerpc/esdhc: disable CMD23 for some Freescale SoCs

Message ID 1348639360-5757-1-git-send-email-r66093@freescale.com (mailing list archive)
State New, archived
Headers show

Commit Message

Huang Changming-R66093 Sept. 26, 2012, 6:02 a.m. UTC
From: Jerry Huang <Chang-Ming.Huang@freescale.com>

CMD23 causes lots of errors in kernel on some freescale SoCs
(P1020, P1021, P1022, P1024, P1025 and P4080) when MMC card used,
which is because these controllers does not support CMD23,
even on the SoCs which declares CMD23 is supported.
Therefore, we'll not use CMD23.

Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
CC: Anton Vorontsov <cbouatmailru@gmail.com>
CC: Chris Ball <cjb@laptop.org>
---
changes for v5:
	- change the error to warning information
changes for v4:
	- change to detect the IP version
	- don't use callback function
changes for v3:
	- move the limitation detect function to eSDHC file
	- add the callback funtion to do this limitation detect
changes for v2:
	- discard the property mode and add the processor detection

 drivers/mmc/host/sdhci-of-esdhc.c |   33 +++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-pltfm.c    |    4 +++-
 drivers/mmc/host/sdhci-pltfm.h    |    1 +
 drivers/mmc/host/sdhci.c          |    3 +++
 include/linux/mmc/sdhci.h         |    1 +
 5 files changed, 41 insertions(+), 1 deletion(-)

Comments

Girish K S Sept. 26, 2012, 1:03 p.m. UTC | #1
Looks good
Reviewed By:- Girish K S <girish.shivananjappa@linaro.org>

On 26 September 2012 15:02,  <r66093@freescale.com> wrote:
> From: Jerry Huang <Chang-Ming.Huang@freescale.com>
>
> CMD23 causes lots of errors in kernel on some freescale SoCs
> (P1020, P1021, P1022, P1024, P1025 and P4080) when MMC card used,
> which is because these controllers does not support CMD23,
> even on the SoCs which declares CMD23 is supported.
> Therefore, we'll not use CMD23.
>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> CC: Anton Vorontsov <cbouatmailru@gmail.com>
> CC: Chris Ball <cjb@laptop.org>
> ---
> changes for v5:
>         - change the error to warning information
> changes for v4:
>         - change to detect the IP version
>         - don't use callback function
> changes for v3:
>         - move the limitation detect function to eSDHC file
>         - add the callback funtion to do this limitation detect
> changes for v2:
>         - discard the property mode and add the processor detection
>
>  drivers/mmc/host/sdhci-of-esdhc.c |   33 +++++++++++++++++++++++++++++++++
>  drivers/mmc/host/sdhci-pltfm.c    |    4 +++-
>  drivers/mmc/host/sdhci-pltfm.h    |    1 +
>  drivers/mmc/host/sdhci.c          |    3 +++
>  include/linux/mmc/sdhci.h         |    1 +
>  5 files changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index ae5fcbf..ffc1226 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -169,6 +169,38 @@ static void esdhc_of_resume(struct sdhci_host *host)
>  }
>  #endif
>
> +static void esdhc_of_detect_limitation(struct platform_device *pdev,
> +       struct sdhci_pltfm_data *pdata)
> +{
> +       void __iomem *ioaddr;
> +       struct resource *iomem;
> +       u32 vvn;
> +
> +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!iomem) {
> +               dev_warn(&pdev->dev, "failed to get resource\n");
> +               goto end;
> +       }
> +       if (resource_size(iomem) < 0x100)
> +               dev_warn(&pdev->dev, "Invalid iomem size!\n");
> +
> +       ioaddr = ioremap(iomem->start, resource_size(iomem));
> +       if (!ioaddr) {
> +               dev_warn(&pdev->dev, "failed to remap registers\n");
> +               goto end;
> +       }
> +
> +       /* P102x and P4080 has IP version VVN2.2, CMD23 is not supported */
> +       vvn = in_be32(ioaddr + SDHCI_SLOT_INT_STATUS);
> +       vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> +       if (vvn == VENDOR_V_22)
> +               pdata->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
> +
> +       iounmap(ioaddr);
> +end:
> +       return;
> +}
> +
>  static struct sdhci_ops sdhci_esdhc_ops = {
>         .read_l = esdhc_readl,
>         .read_w = esdhc_readw,
> @@ -199,6 +231,7 @@ static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
>
>  static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
>  {
> +       esdhc_of_detect_limitation(pdev, &sdhci_esdhc_pdata);
>         return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
>  }
>
> diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
> index 65551a9..4dd5770 100644
> --- a/drivers/mmc/host/sdhci-pltfm.c
> +++ b/drivers/mmc/host/sdhci-pltfm.c
> @@ -132,8 +132,10 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
>                 host->ops = pdata->ops;
>         else
>                 host->ops = &sdhci_pltfm_ops;
> -       if (pdata)
> +       if (pdata) {
>                 host->quirks = pdata->quirks;
> +               host->quirks2 = pdata->quirks2;
> +       }
>         host->irq = platform_get_irq(pdev, 0);
>
>         if (!request_mem_region(iomem->start, resource_size(iomem),
> diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
> index 37e0e18..283d54a 100644
> --- a/drivers/mmc/host/sdhci-pltfm.h
> +++ b/drivers/mmc/host/sdhci-pltfm.h
> @@ -18,6 +18,7 @@
>  struct sdhci_pltfm_data {
>         struct sdhci_ops *ops;
>         unsigned int quirks;
> +       unsigned int quirks2;
>  };
>
>  struct sdhci_pltfm_host {
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 0e15c79..b0b7cad 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -2837,6 +2837,9 @@ int sdhci_add_host(struct sdhci_host *host)
>         if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
>                 mmc->caps |= MMC_CAP_4_BIT_DATA;
>
> +       if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
> +               mmc->caps &= ~MMC_CAP_CMD23;
> +
>         if (caps[0] & SDHCI_CAN_DO_HISPD)
>                 mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
>
> diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> index fa8529a..1edcb4d 100644
> --- a/include/linux/mmc/sdhci.h
> +++ b/include/linux/mmc/sdhci.h
> @@ -91,6 +91,7 @@ struct sdhci_host {
>         unsigned int quirks2;   /* More deviations from spec. */
>
>  #define SDHCI_QUIRK2_HOST_OFF_CARD_ON                  (1<<0)
> +#define SDHCI_QUIRK2_HOST_NO_CMD23                     (1<<1)
>
>         int irq;                /* Device IRQ */
>         void __iomem *ioaddr;   /* Mapped address */
> --
> 1.7.9.5
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Huang Changming-R66093 Oct. 9, 2012, 6:24 a.m. UTC | #2
Hi, Anto and Chris
This version was created with the feedback from Kumar and all of you.
Have you any comment about this patch?
Could it be merged into kernel?

Best Regards
Jerry Huang

> -----Original Message-----
> From: Girish K S [mailto:girish.shivananjappa@linaro.org]
> Sent: Wednesday, September 26, 2012 9:04 PM
> To: Huang Changming-R66093
> Cc: linux-mmc@vger.kernel.org; Huang Changming-R66093; Xie Shaohui-B21989;
> Anton Vorontsov; Chris Ball
> Subject: Re: [PATCH v5] powerpc/esdhc: disable CMD23 for some Freescale
> SoCs
> 
> Looks good
> Reviewed By:- Girish K S <girish.shivananjappa@linaro.org>
> 
> On 26 September 2012 15:02,  <r66093@freescale.com> wrote:
> > From: Jerry Huang <Chang-Ming.Huang@freescale.com>
> >
> > CMD23 causes lots of errors in kernel on some freescale SoCs (P1020,
> > P1021, P1022, P1024, P1025 and P4080) when MMC card used, which is
> > because these controllers does not support CMD23, even on the SoCs
> > which declares CMD23 is supported.
> > Therefore, we'll not use CMD23.
> >
> > Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> > Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> > CC: Anton Vorontsov <cbouatmailru@gmail.com>
> > CC: Chris Ball <cjb@laptop.org>
> > ---
> > changes for v5:
> >         - change the error to warning information changes for v4:
> >         - change to detect the IP version
> >         - don't use callback function
> > changes for v3:
> >         - move the limitation detect function to eSDHC file
> >         - add the callback funtion to do this limitation detect
> > changes for v2:
> >         - discard the property mode and add the processor detection
> >
> >  drivers/mmc/host/sdhci-of-esdhc.c |   33
> +++++++++++++++++++++++++++++++++
> >  drivers/mmc/host/sdhci-pltfm.c    |    4 +++-
> >  drivers/mmc/host/sdhci-pltfm.h    |    1 +
> >  drivers/mmc/host/sdhci.c          |    3 +++
> >  include/linux/mmc/sdhci.h         |    1 +
> >  5 files changed, 41 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index ae5fcbf..ffc1226 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -169,6 +169,38 @@ static void esdhc_of_resume(struct sdhci_host
> > *host)  }  #endif
> >
> > +static void esdhc_of_detect_limitation(struct platform_device *pdev,
> > +       struct sdhci_pltfm_data *pdata) {
> > +       void __iomem *ioaddr;
> > +       struct resource *iomem;
> > +       u32 vvn;
> > +
> > +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       if (!iomem) {
> > +               dev_warn(&pdev->dev, "failed to get resource\n");
> > +               goto end;
> > +       }
> > +       if (resource_size(iomem) < 0x100)
> > +               dev_warn(&pdev->dev, "Invalid iomem size!\n");
> > +
> > +       ioaddr = ioremap(iomem->start, resource_size(iomem));
> > +       if (!ioaddr) {
> > +               dev_warn(&pdev->dev, "failed to remap registers\n");
> > +               goto end;
> > +       }
> > +
> > +       /* P102x and P4080 has IP version VVN2.2, CMD23 is not
> supported */
> > +       vvn = in_be32(ioaddr + SDHCI_SLOT_INT_STATUS);
> > +       vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> > +       if (vvn == VENDOR_V_22)
> > +               pdata->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
> > +
> > +       iounmap(ioaddr);
> > +end:
> > +       return;
> > +}
> > +
> >  static struct sdhci_ops sdhci_esdhc_ops = {
> >         .read_l = esdhc_readl,
> >         .read_w = esdhc_readw,
> > @@ -199,6 +231,7 @@ static struct sdhci_pltfm_data sdhci_esdhc_pdata =
> > {
> >
> >  static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
> > {
> > +       esdhc_of_detect_limitation(pdev, &sdhci_esdhc_pdata);
> >         return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);  }
> >
> > diff --git a/drivers/mmc/host/sdhci-pltfm.c
> > b/drivers/mmc/host/sdhci-pltfm.c index 65551a9..4dd5770 100644
> > --- a/drivers/mmc/host/sdhci-pltfm.c
> > +++ b/drivers/mmc/host/sdhci-pltfm.c
> > @@ -132,8 +132,10 @@ struct sdhci_host *sdhci_pltfm_init(struct
> platform_device *pdev,
> >                 host->ops = pdata->ops;
> >         else
> >                 host->ops = &sdhci_pltfm_ops;
> > -       if (pdata)
> > +       if (pdata) {
> >                 host->quirks = pdata->quirks;
> > +               host->quirks2 = pdata->quirks2;
> > +       }
> >         host->irq = platform_get_irq(pdev, 0);
> >
> >         if (!request_mem_region(iomem->start, resource_size(iomem),
> > diff --git a/drivers/mmc/host/sdhci-pltfm.h
> > b/drivers/mmc/host/sdhci-pltfm.h index 37e0e18..283d54a 100644
> > --- a/drivers/mmc/host/sdhci-pltfm.h
> > +++ b/drivers/mmc/host/sdhci-pltfm.h
> > @@ -18,6 +18,7 @@
> >  struct sdhci_pltfm_data {
> >         struct sdhci_ops *ops;
> >         unsigned int quirks;
> > +       unsigned int quirks2;
> >  };
> >
> >  struct sdhci_pltfm_host {
> > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index
> > 0e15c79..b0b7cad 100644
> > --- a/drivers/mmc/host/sdhci.c
> > +++ b/drivers/mmc/host/sdhci.c
> > @@ -2837,6 +2837,9 @@ int sdhci_add_host(struct sdhci_host *host)
> >         if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
> >                 mmc->caps |= MMC_CAP_4_BIT_DATA;
> >
> > +       if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
> > +               mmc->caps &= ~MMC_CAP_CMD23;
> > +
> >         if (caps[0] & SDHCI_CAN_DO_HISPD)
> >                 mmc->caps |= MMC_CAP_SD_HIGHSPEED |
> > MMC_CAP_MMC_HIGHSPEED;
> >
> > diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> > index fa8529a..1edcb4d 100644
> > --- a/include/linux/mmc/sdhci.h
> > +++ b/include/linux/mmc/sdhci.h
> > @@ -91,6 +91,7 @@ struct sdhci_host {
> >         unsigned int quirks2;   /* More deviations from spec. */
> >
> >  #define SDHCI_QUIRK2_HOST_OFF_CARD_ON                  (1<<0)
> > +#define SDHCI_QUIRK2_HOST_NO_CMD23                     (1<<1)
> >
> >         int irq;                /* Device IRQ */
> >         void __iomem *ioaddr;   /* Mapped address */
> > --
> > 1.7.9.5
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc"
> > in the body of a message to majordomo@vger.kernel.org More majordomo
> > info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Huang Changming-R66093 Oct. 15, 2012, 3:07 a.m. UTC | #3
Anton,
Have you any comment about this patch?

Best Regards
Jerry Huang


> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Huang Changming-R66093
> Sent: Tuesday, October 09, 2012 2:24 PM
> To: Anton Vorontsov; Chris Ball
> Cc: linux-mmc@vger.kernel.org; Xie Shaohui-B21989; Girish K S
> Subject: RE: [PATCH v5] powerpc/esdhc: disable CMD23 for some Freescale
> SoCs
> 
> Hi, Anto and Chris
> This version was created with the feedback from Kumar and all of you.
> Have you any comment about this patch?
> Could it be merged into kernel?
> 
> Best Regards
> Jerry Huang
> 
> > -----Original Message-----
> > From: Girish K S [mailto:girish.shivananjappa@linaro.org]
> > Sent: Wednesday, September 26, 2012 9:04 PM
> > To: Huang Changming-R66093
> > Cc: linux-mmc@vger.kernel.org; Huang Changming-R66093; Xie
> > Shaohui-B21989; Anton Vorontsov; Chris Ball
> > Subject: Re: [PATCH v5] powerpc/esdhc: disable CMD23 for some
> > Freescale SoCs
> >
> > Looks good
> > Reviewed By:- Girish K S <girish.shivananjappa@linaro.org>
> >
> > On 26 September 2012 15:02,  <r66093@freescale.com> wrote:
> > > From: Jerry Huang <Chang-Ming.Huang@freescale.com>
> > >
> > > CMD23 causes lots of errors in kernel on some freescale SoCs (P1020,
> > > P1021, P1022, P1024, P1025 and P4080) when MMC card used, which is
> > > because these controllers does not support CMD23, even on the SoCs
> > > which declares CMD23 is supported.
> > > Therefore, we'll not use CMD23.
> > >
> > > Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> > > Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> > > CC: Anton Vorontsov <cbouatmailru@gmail.com>
> > > CC: Chris Ball <cjb@laptop.org>
> > > ---
> > > changes for v5:
> > >         - change the error to warning information changes for v4:
> > >         - change to detect the IP version
> > >         - don't use callback function changes for v3:
> > >         - move the limitation detect function to eSDHC file
> > >         - add the callback funtion to do this limitation detect
> > > changes for v2:
> > >         - discard the property mode and add the processor detection
> > >
> > >  drivers/mmc/host/sdhci-of-esdhc.c |   33
> > +++++++++++++++++++++++++++++++++
> > >  drivers/mmc/host/sdhci-pltfm.c    |    4 +++-
> > >  drivers/mmc/host/sdhci-pltfm.h    |    1 +
> > >  drivers/mmc/host/sdhci.c          |    3 +++
> > >  include/linux/mmc/sdhci.h         |    1 +
> > >  5 files changed, 41 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > > b/drivers/mmc/host/sdhci-of-esdhc.c
> > > index ae5fcbf..ffc1226 100644
> > > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > > @@ -169,6 +169,38 @@ static void esdhc_of_resume(struct sdhci_host
> > > *host)  }  #endif
> > >
> > > +static void esdhc_of_detect_limitation(struct platform_device *pdev,
> > > +       struct sdhci_pltfm_data *pdata) {
> > > +       void __iomem *ioaddr;
> > > +       struct resource *iomem;
> > > +       u32 vvn;
> > > +
> > > +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +       if (!iomem) {
> > > +               dev_warn(&pdev->dev, "failed to get resource\n");
> > > +               goto end;
> > > +       }
> > > +       if (resource_size(iomem) < 0x100)
> > > +               dev_warn(&pdev->dev, "Invalid iomem size!\n");
> > > +
> > > +       ioaddr = ioremap(iomem->start, resource_size(iomem));
> > > +       if (!ioaddr) {
> > > +               dev_warn(&pdev->dev, "failed to remap registers\n");
> > > +               goto end;
> > > +       }
> > > +
> > > +       /* P102x and P4080 has IP version VVN2.2, CMD23 is not
> > supported */
> > > +       vvn = in_be32(ioaddr + SDHCI_SLOT_INT_STATUS);
> > > +       vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> > > +       if (vvn == VENDOR_V_22)
> > > +               pdata->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
> > > +
> > > +       iounmap(ioaddr);
> > > +end:
> > > +       return;
> > > +}
> > > +
> > >  static struct sdhci_ops sdhci_esdhc_ops = {
> > >         .read_l = esdhc_readl,
> > >         .read_w = esdhc_readw,
> > > @@ -199,6 +231,7 @@ static struct sdhci_pltfm_data sdhci_esdhc_pdata
> > > = {
> > >
> > >  static int __devinit sdhci_esdhc_probe(struct platform_device
> > > *pdev) {
> > > +       esdhc_of_detect_limitation(pdev, &sdhci_esdhc_pdata);
> > >         return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);  }
> > >
> > > diff --git a/drivers/mmc/host/sdhci-pltfm.c
> > > b/drivers/mmc/host/sdhci-pltfm.c index 65551a9..4dd5770 100644
> > > --- a/drivers/mmc/host/sdhci-pltfm.c
> > > +++ b/drivers/mmc/host/sdhci-pltfm.c
> > > @@ -132,8 +132,10 @@ struct sdhci_host *sdhci_pltfm_init(struct
> > platform_device *pdev,
> > >                 host->ops = pdata->ops;
> > >         else
> > >                 host->ops = &sdhci_pltfm_ops;
> > > -       if (pdata)
> > > +       if (pdata) {
> > >                 host->quirks = pdata->quirks;
> > > +               host->quirks2 = pdata->quirks2;
> > > +       }
> > >         host->irq = platform_get_irq(pdev, 0);
> > >
> > >         if (!request_mem_region(iomem->start, resource_size(iomem),
> > > diff --git a/drivers/mmc/host/sdhci-pltfm.h
> > > b/drivers/mmc/host/sdhci-pltfm.h index 37e0e18..283d54a 100644
> > > --- a/drivers/mmc/host/sdhci-pltfm.h
> > > +++ b/drivers/mmc/host/sdhci-pltfm.h
> > > @@ -18,6 +18,7 @@
> > >  struct sdhci_pltfm_data {
> > >         struct sdhci_ops *ops;
> > >         unsigned int quirks;
> > > +       unsigned int quirks2;
> > >  };
> > >
> > >  struct sdhci_pltfm_host {
> > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > > index 0e15c79..b0b7cad 100644
> > > --- a/drivers/mmc/host/sdhci.c
> > > +++ b/drivers/mmc/host/sdhci.c
> > > @@ -2837,6 +2837,9 @@ int sdhci_add_host(struct sdhci_host *host)
> > >         if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
> > >                 mmc->caps |= MMC_CAP_4_BIT_DATA;
> > >
> > > +       if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
> > > +               mmc->caps &= ~MMC_CAP_CMD23;
> > > +
> > >         if (caps[0] & SDHCI_CAN_DO_HISPD)
> > >                 mmc->caps |= MMC_CAP_SD_HIGHSPEED |
> > > MMC_CAP_MMC_HIGHSPEED;
> > >
> > > diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> > > index fa8529a..1edcb4d 100644
> > > --- a/include/linux/mmc/sdhci.h
> > > +++ b/include/linux/mmc/sdhci.h
> > > @@ -91,6 +91,7 @@ struct sdhci_host {
> > >         unsigned int quirks2;   /* More deviations from spec. */
> > >
> > >  #define SDHCI_QUIRK2_HOST_OFF_CARD_ON                  (1<<0)
> > > +#define SDHCI_QUIRK2_HOST_NO_CMD23                     (1<<1)
> > >
> > >         int irq;                /* Device IRQ */
> > >         void __iomem *ioaddr;   /* Mapped address */
> > > --
> > > 1.7.9.5
> > >
> > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-mmc"
> > > in the body of a message to majordomo@vger.kernel.org More majordomo
> > > info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Huang Changming-R66093 Oct. 23, 2012, 8:41 a.m. UTC | #4
Anton, 
could you give some comment about this patch?
Reviewed by Girish last month.

Best Regards
Jerry Huang


> -----Original Message-----
> From: Huang Changming-R66093
> Sent: Monday, October 15, 2012 11:07 AM
> To: Huang Changming-R66093; Anton Vorontsov; Chris Ball
> Cc: linux-mmc@vger.kernel.org; Xie Shaohui-B21989; Girish K S
> Subject: RE: [PATCH v5] powerpc/esdhc: disable CMD23 for some Freescale
> SoCs
> 
> Anton,
> Have you any comment about this patch?
> 
> Best Regards
> Jerry Huang
> 
> 
> > -----Original Message-----
> > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> > owner@vger.kernel.org] On Behalf Of Huang Changming-R66093
> > Sent: Tuesday, October 09, 2012 2:24 PM
> > To: Anton Vorontsov; Chris Ball
> > Cc: linux-mmc@vger.kernel.org; Xie Shaohui-B21989; Girish K S
> > Subject: RE: [PATCH v5] powerpc/esdhc: disable CMD23 for some
> > Freescale SoCs
> >
> > Hi, Anto and Chris
> > This version was created with the feedback from Kumar and all of you.
> > Have you any comment about this patch?
> > Could it be merged into kernel?
> >
> > Best Regards
> > Jerry Huang
> >
> > > -----Original Message-----
> > > From: Girish K S [mailto:girish.shivananjappa@linaro.org]
> > > Sent: Wednesday, September 26, 2012 9:04 PM
> > > To: Huang Changming-R66093
> > > Cc: linux-mmc@vger.kernel.org; Huang Changming-R66093; Xie
> > > Shaohui-B21989; Anton Vorontsov; Chris Ball
> > > Subject: Re: [PATCH v5] powerpc/esdhc: disable CMD23 for some
> > > Freescale SoCs
> > >
> > > Looks good
> > > Reviewed By:- Girish K S <girish.shivananjappa@linaro.org>
> > >
> > > On 26 September 2012 15:02,  <r66093@freescale.com> wrote:
> > > > From: Jerry Huang <Chang-Ming.Huang@freescale.com>
> > > >
> > > > CMD23 causes lots of errors in kernel on some freescale SoCs
> > > > (P1020, P1021, P1022, P1024, P1025 and P4080) when MMC card used,
> > > > which is because these controllers does not support CMD23, even on
> > > > the SoCs which declares CMD23 is supported.
> > > > Therefore, we'll not use CMD23.
> > > >
> > > > Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> > > > Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> > > > CC: Anton Vorontsov <cbouatmailru@gmail.com>
> > > > CC: Chris Ball <cjb@laptop.org>
> > > > ---
> > > > changes for v5:
> > > >         - change the error to warning information changes for v4:
> > > >         - change to detect the IP version
> > > >         - don't use callback function changes for v3:
> > > >         - move the limitation detect function to eSDHC file
> > > >         - add the callback funtion to do this limitation detect
> > > > changes for v2:
> > > >         - discard the property mode and add the processor
> > > > detection
> > > >
> > > >  drivers/mmc/host/sdhci-of-esdhc.c |   33
> > > +++++++++++++++++++++++++++++++++
> > > >  drivers/mmc/host/sdhci-pltfm.c    |    4 +++-
> > > >  drivers/mmc/host/sdhci-pltfm.h    |    1 +
> > > >  drivers/mmc/host/sdhci.c          |    3 +++
> > > >  include/linux/mmc/sdhci.h         |    1 +
> > > >  5 files changed, 41 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > > > b/drivers/mmc/host/sdhci-of-esdhc.c
> > > > index ae5fcbf..ffc1226 100644
> > > > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > > > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > > > @@ -169,6 +169,38 @@ static void esdhc_of_resume(struct sdhci_host
> > > > *host)  }  #endif
> > > >
> > > > +static void esdhc_of_detect_limitation(struct platform_device
> *pdev,
> > > > +       struct sdhci_pltfm_data *pdata) {
> > > > +       void __iomem *ioaddr;
> > > > +       struct resource *iomem;
> > > > +       u32 vvn;
> > > > +
> > > > +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > > +       if (!iomem) {
> > > > +               dev_warn(&pdev->dev, "failed to get resource\n");
> > > > +               goto end;
> > > > +       }
> > > > +       if (resource_size(iomem) < 0x100)
> > > > +               dev_warn(&pdev->dev, "Invalid iomem size!\n");
> > > > +
> > > > +       ioaddr = ioremap(iomem->start, resource_size(iomem));
> > > > +       if (!ioaddr) {
> > > > +               dev_warn(&pdev->dev, "failed to remap registers\n");
> > > > +               goto end;
> > > > +       }
> > > > +
> > > > +       /* P102x and P4080 has IP version VVN2.2, CMD23 is not
> > > supported */
> > > > +       vvn = in_be32(ioaddr + SDHCI_SLOT_INT_STATUS);
> > > > +       vvn = (vvn & SDHCI_VENDOR_VER_MASK) >>
> SDHCI_VENDOR_VER_SHIFT;
> > > > +       if (vvn == VENDOR_V_22)
> > > > +               pdata->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
> > > > +
> > > > +       iounmap(ioaddr);
> > > > +end:
> > > > +       return;
> > > > +}
> > > > +
> > > >  static struct sdhci_ops sdhci_esdhc_ops = {
> > > >         .read_l = esdhc_readl,
> > > >         .read_w = esdhc_readw,
> > > > @@ -199,6 +231,7 @@ static struct sdhci_pltfm_data
> > > > sdhci_esdhc_pdata = {
> > > >
> > > >  static int __devinit sdhci_esdhc_probe(struct platform_device
> > > > *pdev) {
> > > > +       esdhc_of_detect_limitation(pdev, &sdhci_esdhc_pdata);
> > > >         return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);  }
> > > >
> > > > diff --git a/drivers/mmc/host/sdhci-pltfm.c
> > > > b/drivers/mmc/host/sdhci-pltfm.c index 65551a9..4dd5770 100644
> > > > --- a/drivers/mmc/host/sdhci-pltfm.c
> > > > +++ b/drivers/mmc/host/sdhci-pltfm.c
> > > > @@ -132,8 +132,10 @@ struct sdhci_host *sdhci_pltfm_init(struct
> > > platform_device *pdev,
> > > >                 host->ops = pdata->ops;
> > > >         else
> > > >                 host->ops = &sdhci_pltfm_ops;
> > > > -       if (pdata)
> > > > +       if (pdata) {
> > > >                 host->quirks = pdata->quirks;
> > > > +               host->quirks2 = pdata->quirks2;
> > > > +       }
> > > >         host->irq = platform_get_irq(pdev, 0);
> > > >
> > > >         if (!request_mem_region(iomem->start,
> > > > resource_size(iomem), diff --git a/drivers/mmc/host/sdhci-pltfm.h
> > > > b/drivers/mmc/host/sdhci-pltfm.h index 37e0e18..283d54a 100644
> > > > --- a/drivers/mmc/host/sdhci-pltfm.h
> > > > +++ b/drivers/mmc/host/sdhci-pltfm.h
> > > > @@ -18,6 +18,7 @@
> > > >  struct sdhci_pltfm_data {
> > > >         struct sdhci_ops *ops;
> > > >         unsigned int quirks;
> > > > +       unsigned int quirks2;
> > > >  };
> > > >
> > > >  struct sdhci_pltfm_host {
> > > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > > > index 0e15c79..b0b7cad 100644
> > > > --- a/drivers/mmc/host/sdhci.c
> > > > +++ b/drivers/mmc/host/sdhci.c
> > > > @@ -2837,6 +2837,9 @@ int sdhci_add_host(struct sdhci_host *host)
> > > >         if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
> > > >                 mmc->caps |= MMC_CAP_4_BIT_DATA;
> > > >
> > > > +       if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
> > > > +               mmc->caps &= ~MMC_CAP_CMD23;
> > > > +
> > > >         if (caps[0] & SDHCI_CAN_DO_HISPD)
> > > >                 mmc->caps |= MMC_CAP_SD_HIGHSPEED |
> > > > MMC_CAP_MMC_HIGHSPEED;
> > > >
> > > > diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> > > > index fa8529a..1edcb4d 100644
> > > > --- a/include/linux/mmc/sdhci.h
> > > > +++ b/include/linux/mmc/sdhci.h
> > > > @@ -91,6 +91,7 @@ struct sdhci_host {
> > > >         unsigned int quirks2;   /* More deviations from spec. */
> > > >
> > > >  #define SDHCI_QUIRK2_HOST_OFF_CARD_ON                  (1<<0)
> > > > +#define SDHCI_QUIRK2_HOST_NO_CMD23                     (1<<1)
> > > >
> > > >         int irq;                /* Device IRQ */
> > > >         void __iomem *ioaddr;   /* Mapped address */
> > > > --
> > > > 1.7.9.5
> > > >
> > > >
> > > > --
> > > > To unsubscribe from this list: send the line "unsubscribe linux-
> mmc"
> > > > in the body of a message to majordomo@vger.kernel.org More
> > > > majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc"
> > in the body of a message to majordomo@vger.kernel.org More majordomo
> > info at http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Anton Vorontsov Oct. 24, 2012, 8:39 a.m. UTC | #5
Sorry for the late reply, Huang.

On Tue, Oct 09, 2012 at 06:24:13AM +0000, Huang Changming-R66093 wrote:
[...]
> > > +static void esdhc_of_detect_limitation(struct platform_device *pdev,
> > > +       struct sdhci_pltfm_data *pdata) {

Wrong indentation. Should be one more tab, at least (or align to opening
brace).

> > > +       void __iomem *ioaddr;
> > > +       struct resource *iomem;
> > > +       u32 vvn;
> > > +
> > > +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +       if (!iomem) {
> > > +               dev_warn(&pdev->dev, "failed to get resource\n");
> > > +               goto end;
> > > +       }
> > > +       if (resource_size(iomem) < 0x100)
> > > +               dev_warn(&pdev->dev, "Invalid iomem size!\n");
> > > +
> > > +       ioaddr = ioremap(iomem->start, resource_size(iomem));
> > > +       if (!ioaddr) {
> > > +               dev_warn(&pdev->dev, "failed to remap registers\n");
> > > +               goto end;
> > > +       }
> > > +
> > > +       /* P102x and P4080 has IP version VVN2.2, CMD23 is not
> > supported */
> > > +       vvn = in_be32(ioaddr + SDHCI_SLOT_INT_STATUS);
> > > +       vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> > > +       if (vvn == VENDOR_V_22)
> > > +               pdata->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
> > > +
> > > +       iounmap(ioaddr);
> > > +end:
> > > +       return;

No need for the 'end' label.

> > > +}
> > > +
> > >  static struct sdhci_ops sdhci_esdhc_ops = {
> > >         .read_l = esdhc_readl,
> > >         .read_w = esdhc_readw,
> > > @@ -199,6 +231,7 @@ static struct sdhci_pltfm_data sdhci_esdhc_pdata =
> > > {
> > >
> > >  static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
> > > {
> > > +       esdhc_of_detect_limitation(pdev, &sdhci_esdhc_pdata);

I would rather prefer it to be in sdhci_ops (i.e. introduce
sdhci_ops->platform_init), so that way you wouldn't need to ioremap()
stuff by yourself. And make drivers/mmc/host/sdhci-pltfm.c call
platform_init after ioremap().

Then your detect_limitation() function would only need to check revision
and set additional quirks.

Thanks,
Anton.
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Huang Changming-R66093 Oct. 25, 2012, 6:29 a.m. UTC | #6
SGksIGFudG9uLCANCkkgaGF2ZSByZXNlbnQgdGhpcyBwYXRjaCBhY2NvcmRpbmcgdG8geW91ciBz
dWdnZXN0aW9uLg0KUGxlYXNlIHJldmlldy4NClRoYW5rcy4NCg0KQmVzdCBSZWdhcmRzDQpKZXJy
eSBIdWFuZw0KDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogQW50b24g
Vm9yb250c292IFttYWlsdG86Y2JvdWF0bWFpbHJ1QGdtYWlsLmNvbV0NCj4gU2VudDogV2VkbmVz
ZGF5LCBPY3RvYmVyIDI0LCAyMDEyIDQ6MzkgUE0NCj4gVG86IEh1YW5nIENoYW5nbWluZy1SNjYw
OTMNCj4gQ2M6IENocmlzIEJhbGw7IGxpbnV4LW1tY0B2Z2VyLmtlcm5lbC5vcmc7IFhpZSBTaGFv
aHVpLUIyMTk4OTsgR2lyaXNoIEsgUw0KPiBTdWJqZWN0OiBSZTogW1BBVENIIHY1XSBwb3dlcnBj
L2VzZGhjOiBkaXNhYmxlIENNRDIzIGZvciBzb21lIEZyZWVzY2FsZQ0KPiBTb0NzDQo+IA0KPiBT
b3JyeSBmb3IgdGhlIGxhdGUgcmVwbHksIEh1YW5nLg0KPiANCj4gT24gVHVlLCBPY3QgMDksIDIw
MTIgYXQgMDY6MjQ6MTNBTSArMDAwMCwgSHVhbmcgQ2hhbmdtaW5nLVI2NjA5MyB3cm90ZToNCj4g
Wy4uLl0NCj4gPiA+ID4gK3N0YXRpYyB2b2lkIGVzZGhjX29mX2RldGVjdF9saW1pdGF0aW9uKHN0
cnVjdCBwbGF0Zm9ybV9kZXZpY2UNCj4gKnBkZXYsDQo+ID4gPiA+ICsgICAgICAgc3RydWN0IHNk
aGNpX3BsdGZtX2RhdGEgKnBkYXRhKSB7DQo+IA0KPiBXcm9uZyBpbmRlbnRhdGlvbi4gU2hvdWxk
IGJlIG9uZSBtb3JlIHRhYiwgYXQgbGVhc3QgKG9yIGFsaWduIHRvIG9wZW5pbmcNCj4gYnJhY2Up
Lg0KPiANCj4gPiA+ID4gKyAgICAgICB2b2lkIF9faW9tZW0gKmlvYWRkcjsNCj4gPiA+ID4gKyAg
ICAgICBzdHJ1Y3QgcmVzb3VyY2UgKmlvbWVtOw0KPiA+ID4gPiArICAgICAgIHUzMiB2dm47DQo+
ID4gPiA+ICsNCj4gPiA+ID4gKyAgICAgICBpb21lbSA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShw
ZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ID4gPiA+ICsgICAgICAgaWYgKCFpb21lbSkgew0K
PiA+ID4gPiArICAgICAgICAgICAgICAgZGV2X3dhcm4oJnBkZXYtPmRldiwgImZhaWxlZCB0byBn
ZXQgcmVzb3VyY2VcbiIpOw0KPiA+ID4gPiArICAgICAgICAgICAgICAgZ290byBlbmQ7DQo+ID4g
PiA+ICsgICAgICAgfQ0KPiA+ID4gPiArICAgICAgIGlmIChyZXNvdXJjZV9zaXplKGlvbWVtKSA8
IDB4MTAwKQ0KPiA+ID4gPiArICAgICAgICAgICAgICAgZGV2X3dhcm4oJnBkZXYtPmRldiwgIklu
dmFsaWQgaW9tZW0gc2l6ZSFcbiIpOw0KPiA+ID4gPiArDQo+ID4gPiA+ICsgICAgICAgaW9hZGRy
ID0gaW9yZW1hcChpb21lbS0+c3RhcnQsIHJlc291cmNlX3NpemUoaW9tZW0pKTsNCj4gPiA+ID4g
KyAgICAgICBpZiAoIWlvYWRkcikgew0KPiA+ID4gPiArICAgICAgICAgICAgICAgZGV2X3dhcm4o
JnBkZXYtPmRldiwgImZhaWxlZCB0byByZW1hcCByZWdpc3RlcnNcbiIpOw0KPiA+ID4gPiArICAg
ICAgICAgICAgICAgZ290byBlbmQ7DQo+ID4gPiA+ICsgICAgICAgfQ0KPiA+ID4gPiArDQo+ID4g
PiA+ICsgICAgICAgLyogUDEwMnggYW5kIFA0MDgwIGhhcyBJUCB2ZXJzaW9uIFZWTjIuMiwgQ01E
MjMgaXMgbm90DQo+ID4gPiBzdXBwb3J0ZWQgKi8NCj4gPiA+ID4gKyAgICAgICB2dm4gPSBpbl9i
ZTMyKGlvYWRkciArIFNESENJX1NMT1RfSU5UX1NUQVRVUyk7DQo+ID4gPiA+ICsgICAgICAgdnZu
ID0gKHZ2biAmIFNESENJX1ZFTkRPUl9WRVJfTUFTSykgPj4NCj4gU0RIQ0lfVkVORE9SX1ZFUl9T
SElGVDsNCj4gPiA+ID4gKyAgICAgICBpZiAodnZuID09IFZFTkRPUl9WXzIyKQ0KPiA+ID4gPiAr
ICAgICAgICAgICAgICAgcGRhdGEtPnF1aXJrczIgfD0gU0RIQ0lfUVVJUksyX0hPU1RfTk9fQ01E
MjM7DQo+ID4gPiA+ICsNCj4gPiA+ID4gKyAgICAgICBpb3VubWFwKGlvYWRkcik7DQo+ID4gPiA+
ICtlbmQ6DQo+ID4gPiA+ICsgICAgICAgcmV0dXJuOw0KPiANCj4gTm8gbmVlZCBmb3IgdGhlICdl
bmQnIGxhYmVsLg0KPiANCj4gPiA+ID4gK30NCj4gPiA+ID4gKw0KPiA+ID4gPiAgc3RhdGljIHN0
cnVjdCBzZGhjaV9vcHMgc2RoY2lfZXNkaGNfb3BzID0gew0KPiA+ID4gPiAgICAgICAgIC5yZWFk
X2wgPSBlc2RoY19yZWFkbCwNCj4gPiA+ID4gICAgICAgICAucmVhZF93ID0gZXNkaGNfcmVhZHcs
DQo+ID4gPiA+IEBAIC0xOTksNiArMjMxLDcgQEAgc3RhdGljIHN0cnVjdCBzZGhjaV9wbHRmbV9k
YXRhDQo+ID4gPiA+IHNkaGNpX2VzZGhjX3BkYXRhID0gew0KPiA+ID4gPg0KPiA+ID4gPiAgc3Rh
dGljIGludCBfX2RldmluaXQgc2RoY2lfZXNkaGNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2Rldmlj
ZQ0KPiA+ID4gPiAqcGRldikgew0KPiA+ID4gPiArICAgICAgIGVzZGhjX29mX2RldGVjdF9saW1p
dGF0aW9uKHBkZXYsICZzZGhjaV9lc2RoY19wZGF0YSk7DQo+IA0KPiBJIHdvdWxkIHJhdGhlciBw
cmVmZXIgaXQgdG8gYmUgaW4gc2RoY2lfb3BzIChpLmUuIGludHJvZHVjZSBzZGhjaV9vcHMtDQo+
ID5wbGF0Zm9ybV9pbml0KSwgc28gdGhhdCB3YXkgeW91IHdvdWxkbid0IG5lZWQgdG8gaW9yZW1h
cCgpIHN0dWZmIGJ5DQo+IHlvdXJzZWxmLiBBbmQgbWFrZSBkcml2ZXJzL21tYy9ob3N0L3NkaGNp
LXBsdGZtLmMgY2FsbCBwbGF0Zm9ybV9pbml0DQo+IGFmdGVyIGlvcmVtYXAoKS4NCj4gDQo+IFRo
ZW4geW91ciBkZXRlY3RfbGltaXRhdGlvbigpIGZ1bmN0aW9uIHdvdWxkIG9ubHkgbmVlZCB0byBj
aGVjayByZXZpc2lvbg0KPiBhbmQgc2V0IGFkZGl0aW9uYWwgcXVpcmtzLg0KPiANCj4gVGhhbmtz
LA0KPiBBbnRvbi4NCg0K

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

Patch

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ae5fcbf..ffc1226 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -169,6 +169,38 @@  static void esdhc_of_resume(struct sdhci_host *host)
 }
 #endif
 
+static void esdhc_of_detect_limitation(struct platform_device *pdev,
+	struct sdhci_pltfm_data *pdata)
+{
+	void __iomem *ioaddr;
+	struct resource *iomem;
+	u32 vvn;
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		dev_warn(&pdev->dev, "failed to get resource\n");
+		goto end;
+	}
+	if (resource_size(iomem) < 0x100)
+		dev_warn(&pdev->dev, "Invalid iomem size!\n");
+
+	ioaddr = ioremap(iomem->start, resource_size(iomem));
+	if (!ioaddr) {
+		dev_warn(&pdev->dev, "failed to remap registers\n");
+		goto end;
+	}
+
+	/* P102x and P4080 has IP version VVN2.2, CMD23 is not supported */
+	vvn = in_be32(ioaddr + SDHCI_SLOT_INT_STATUS);
+	vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+	if (vvn == VENDOR_V_22)
+		pdata->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
+
+	iounmap(ioaddr);
+end:
+	return;
+}
+
 static struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = esdhc_readl,
 	.read_w = esdhc_readw,
@@ -199,6 +231,7 @@  static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
 
 static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
 {
+	esdhc_of_detect_limitation(pdev, &sdhci_esdhc_pdata);
 	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
 }
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 65551a9..4dd5770 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -132,8 +132,10 @@  struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
 		host->ops = pdata->ops;
 	else
 		host->ops = &sdhci_pltfm_ops;
-	if (pdata)
+	if (pdata) {
 		host->quirks = pdata->quirks;
+		host->quirks2 = pdata->quirks2;
+	}
 	host->irq = platform_get_irq(pdev, 0);
 
 	if (!request_mem_region(iomem->start, resource_size(iomem),
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 37e0e18..283d54a 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -18,6 +18,7 @@ 
 struct sdhci_pltfm_data {
 	struct sdhci_ops *ops;
 	unsigned int quirks;
+	unsigned int quirks2;
 };
 
 struct sdhci_pltfm_host {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0e15c79..b0b7cad 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2837,6 +2837,9 @@  int sdhci_add_host(struct sdhci_host *host)
 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
+	if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
+		mmc->caps &= ~MMC_CAP_CMD23;
+
 	if (caps[0] & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index fa8529a..1edcb4d 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -91,6 +91,7 @@  struct sdhci_host {
 	unsigned int quirks2;	/* More deviations from spec. */
 
 #define SDHCI_QUIRK2_HOST_OFF_CARD_ON			(1<<0)
+#define SDHCI_QUIRK2_HOST_NO_CMD23			(1<<1)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */