Re: [PATCH 2/2] sdhci-pxa add call back interface to share sdhci-pxa

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2010/12/7 Philip Rakity <prakity@xxxxxxxxxxx>:
>
> was interested in the 9xx code.

You can ask Jun for pxa910 code, and Raymond for pxa950 code via
internal email system, thanks
>
>
> On Dec 7, 2010, at 7:38 AM, zhangfei gao wrote:
>
>> 2010/12/7 Philip Rakity <prakity@xxxxxxxxxxx>:
>>>
>>> Where is the code that implements
>>>
>>>> +     unsigned int    clk_delay_cycles;
>>>> +     unsigned int    clk_delay_sel;
>>
>> The code is located under arch/arm/, it is used differently depends on
>> different platfrom.
>> For example, aspen could realize under arch/arm/mach-pxa/pxa168.c.
>> Could you refer the code for mmp2.
>>
>>>
>>>
>>>
>>>
>>> On Dec 6, 2010, at 9:56 PM, Raymond Wu wrote:
>>>
>>>> Hi,
>>>>
>>>> This patch is verified by: Raymond Wu(xywu@xxxxxxxxxxx) on pxa955 SAARB platform.
>>>>
>>>> Thanks,
>>>> Raymond
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: zhangfei gao [mailto:zhangfei.gao@xxxxxxxxx]
>>>> Sent: 2010年12月3日 14:31
>>>> To: linux-mmc@xxxxxxxxxxxxxxx
>>>> Cc: Chris Ball; Eric Miao; Haojian Zhuang; niej0001@xxxxxxxxx; Philip Rakity; Mark Brown; Raymond Wu; Jun Nie
>>>> Subject: [PATCH 2/2] sdhci-pxa add call back interface to share sdhci-pxa
>>>>
>>>> From fb5927afac7cbb44805093816bea51dde33da1e5 Mon Sep 17 00:00:00 2001
>>>> From: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
>>>> Date: Tue, 30 Nov 2010 05:43:29 -0500
>>>> Subject: [PATCH 2/2] sdhci-pxa: add call back interface to share sdhci-pxa
>>>>
>>>>      Call back functions is added to support mmp2, pxa910, pxa168 and pxa955
>>>>
>>>> Signed-off-by: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
>>>> CC: RaymondWu <xywu@xxxxxxxxxxx>
>>>> CC: Jun Nie <njun@xxxxxxxxxxx>
>>>> CC: Philip Rakity <prakity@xxxxxxxxxxx>
>>>> ---
>>>> arch/arm/plat-pxa/include/plat/sdhci.h |   44 +++++++++++++++++
>>>> drivers/mmc/host/sdhci-pxa.c           |   83 +++++++++++++++++++++-----------
>>>> 2 files changed, 98 insertions(+), 29 deletions(-)
>>>>
>>>> diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h
>>>> b/arch/arm/plat-pxa/include/plat/sdhci.h
>>>> index 1ab332e..4ce3b05 100644
>>>> --- a/arch/arm/plat-pxa/include/plat/sdhci.h
>>>> +++ b/arch/arm/plat-pxa/include/plat/sdhci.h
>>>> @@ -13,9 +13,14 @@
>>>> #ifndef __PLAT_PXA_SDHCI_H
>>>> #define __PLAT_PXA_SDHCI_H
>>>>
>>>> +#include <linux/mmc/sdhci.h>
>>>> +#include <linux/platform_device.h>
>>>> +
>>>> /* pxa specific flag */
>>>> /* Require clock free running */
>>>> #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
>>>> +/* card alwayes wired to host, like on-chip emmc */
>>>> +#define PXA_FLAG_CARD_PERMANENT      (1<<1)
>>>>
>>>> /* Board design supports 8-bit data on SD/SDIO BUS */  #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2) @@ -25,11 +30,50 @@
>>>> * @max_speed: the maximum speed supported
>>>> * @quirks: quirks of specific device
>>>> * @flags: flags for platform requirement
>>>> + * @clk_delay_cycles:
>>>> + *   mmp2: each step is roughly 100ps, 5bits width
>>>> + *   pxa910 & pxa168: each step is 1ns, 4bits width
>>>> + * @clk_delay_enable: enable clk_delay or not, used on pxa910 & pxa168
>>>> + * @clk_delay_sel: select clk_delay, used on pxa910 & pxa168
>>>> + *   0: choose feedback clk
>>>> + *   1: choose feedback clk + delay value
>>>> + *   2: choose internal clk
>>>> + * @ext_cd_gpio: gpio pin used for external CD line
>>>> + * @ext_cd_gpio_invert: invert values for external CD gpio line
>>>> + * @soc_set_timing: set timing for specific soc
>>>> + * @ext_cd_init: Initialize external card detect subsystem
>>>> + * @ext_cd_cleanup: Cleanup external card detect subsystem
>>>> + * @soc_set_ops: overwrite host ops with soc specific ops
>>>> */
>>>> +struct sdhci_pxa;
>>>> struct sdhci_pxa_platdata {
>>>>      unsigned int    max_speed;
>>>>      unsigned int    quirks;
>>>>      unsigned int    flags;
>>>> +     unsigned int    clk_delay_cycles;
>>>> +     unsigned int    clk_delay_sel;
>>>> +     unsigned int    ext_cd_gpio;
>>>> +     bool            ext_cd_gpio_invert;
>>>> +     bool            clk_delay_enable;
>>>> +
>>>> +     void (*soc_set_timing)(struct sdhci_host *host,
>>>> +                     struct sdhci_pxa_platdata *pdata);
>>>> +     int (*ext_cd_init)(void (*notify_func)(struct platform_device *dev,
>>>> +                                                int state), void *data);
>>>> +     int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *dev,
>>>> +                                                   int state), void *data);
>>>> +     void (*soc_set_ops)(struct sdhci_pxa *pxa); };
>>>> +
>>>> +struct sdhci_pxa {
>>>> +     struct sdhci_host               *host;
>>>> +     struct sdhci_pxa_platdata       *pdata;
>>>> +     struct clk                      *clk;
>>>> +     struct resource                 *res;
>>>> +     struct sdhci_ops                *ops;
>>>> +
>>>> +     u8      clk_enable;
>>>> +     u8      power_mode;
>>>> };
>>>>
>>>> #endif /* __PLAT_PXA_SDHCI_H */
>>>> diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c index 5a61208..f79dccf 100644
>>>> --- a/drivers/mmc/host/sdhci-pxa.c
>>>> +++ b/drivers/mmc/host/sdhci-pxa.c
>>>> @@ -24,32 +24,22 @@
>>>> #include <linux/clk.h>
>>>> #include <linux/io.h>
>>>> #include <linux/err.h>
>>>> +#include <linux/slab.h>
>>>> #include <plat/sdhci.h>
>>>> #include "sdhci.h"
>>>>
>>>> #define DRIVER_NAME   "sdhci-pxa"
>>>>
>>>> -#define SD_FIFO_PARAM                0x104
>>>> -#define DIS_PAD_SD_CLK_GATE  0x400
>>>> -
>>>> -struct sdhci_pxa {
>>>> -     struct sdhci_host               *host;
>>>> -     struct sdhci_pxa_platdata       *pdata;
>>>> -     struct clk                      *clk;
>>>> -     struct resource                 *res;
>>>> -
>>>> -     u8 clk_enable;
>>>> -};
>>>> -
>>>> /*****************************************************************************\
>>>> *                                                                           *
>>>> * SDHCI core callbacks                                                      *
>>>> *                                                                           *
>>>> \*****************************************************************************/
>>>> +
>>>> static void set_clock(struct sdhci_host *host, unsigned int clock)  {
>>>>      struct sdhci_pxa *pxa = sdhci_priv(host);
>>>> -     u32 tmp = 0;
>>>> +     struct sdhci_pxa_platdata *pdata = pxa->pdata;
>>>>
>>>>      if (clock == 0) {
>>>>              if (pxa->clk_enable) {
>>>> @@ -57,21 +47,31 @@ static void set_clock(struct sdhci_host *host, unsigned int clock)
>>>>                      pxa->clk_enable = 0;
>>>>              }
>>>>      } else {
>>>> -             if (0 == pxa->clk_enable) {
>>>> -                     if (pxa->pdata->flags & PXA_FLAG_DISABLE_CLOCK_GATING) {
>>>> -                             tmp = readl(host->ioaddr + SD_FIFO_PARAM);
>>>> -                             tmp |= DIS_PAD_SD_CLK_GATE;
>>>> -                             writel(tmp, host->ioaddr + SD_FIFO_PARAM);
>>>> -                     }
>>>> -                     clk_enable(pxa->clk);
>>>> -                     pxa->clk_enable = 1;
>>>> -             }
>>>> +             if (pdata && pdata->soc_set_timing)
>>>> +                     pdata->soc_set_timing(host, pdata);
>>>> +             clk_enable(pxa->clk);
>>>> +             pxa->clk_enable = 1;
>>>>      }
>>>> }
>>>>
>>>> -static struct sdhci_ops sdhci_pxa_ops = {
>>>> -     .set_clock = set_clock,
>>>> -};
>>>> +static void sdhci_pxa_notify_change(struct platform_device *dev, int
>>>> +state) {
>>>> +     struct sdhci_host *host = platform_get_drvdata(dev);
>>>> +     unsigned long flags;
>>>> +
>>>> +     if (host) {
>>>> +             spin_lock_irqsave(&host->lock, flags);
>>>> +             if (state) {
>>>> +                     dev_dbg(&dev->dev, "card inserted.\n");
>>>> +                     host->flags &= ~SDHCI_DEVICE_DEAD;
>>>> +             } else {
>>>> +                     dev_dbg(&dev->dev, "card removed.\n");
>>>> +                     host->flags |= SDHCI_DEVICE_DEAD;
>>>> +             }
>>>> +             tasklet_schedule(&host->card_tasklet);
>>>> +             spin_unlock_irqrestore(&host->lock, flags);
>>>> +     }
>>>> +}
>>>>
>>>> /*****************************************************************************\
>>>> *                                                                           *
>>>> @@ -111,6 +111,12 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
>>>>      pxa->pdata = pdata;
>>>>      pxa->clk_enable = 0;
>>>>
>>>> +     pxa->ops = kzalloc(sizeof(struct sdhci_ops), GFP_KERNEL);
>>>> +     if (!pxa->ops) {
>>>> +             ret = -ENOMEM;
>>>> +             goto out;
>>>> +     }
>>>> +
>>>>      pxa->clk = clk_get(dev, "PXA-SDHCLK");
>>>>      if (IS_ERR(pxa->clk)) {
>>>>              dev_err(dev, "failed to get io clock\n"); @@ -134,32 +140,46 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
>>>>      }
>>>>
>>>>      host->hw_name = "MMC";
>>>> -     host->ops = &sdhci_pxa_ops;
>>>>      host->irq = irq;
>>>>      host->quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
>>>>
>>>> -     if (pdata->quirks)
>>>> +     if (pdata && pdata->flags & PXA_FLAG_CARD_PERMANENT) {
>>>> +             /* on-chip device */
>>>> +             host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
>>>> +             host->mmc->caps |= MMC_CAP_NONREMOVABLE;
>>>> +     }
>>>> +
>>>> +     if (pdata && pdata->quirks)
>>>>              host->quirks |= pdata->quirks;
>>>>
>>>>      /* If slot design supports 8 bit data, indicate this to MMC. */
>>>>      if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
>>>>              host->mmc->caps |= MMC_CAP_8_BIT_DATA;
>>>>
>>>> +     if (pdata && pdata->soc_set_ops)
>>>> +             pdata->soc_set_ops(pxa);
>>>> +
>>>> +     pxa->ops->set_clock = set_clock;
>>>> +     host->ops = pxa->ops;
>>>> +
>>>>      ret = sdhci_add_host(host);
>>>>      if (ret) {
>>>>              dev_err(&pdev->dev, "failed to add host\n");
>>>>              goto out;
>>>>      }
>>>>
>>>> -     if (pxa->pdata->max_speed)
>>>> -             host->mmc->f_max = pxa->pdata->max_speed;
>>>> +     if (pdata && pdata->max_speed)
>>>> +             host->mmc->f_max = pdata->max_speed;
>>>>
>>>> +     if (pdata && pdata->ext_cd_init)
>>>> +             pdata->ext_cd_init(&sdhci_pxa_notify_change, pdata);
>>>>      platform_set_drvdata(pdev, host);
>>>>
>>>>      return 0;
>>>> out:
>>>>      if (host) {
>>>>              clk_put(pxa->clk);
>>>> +             kfree(pxa->ops);
>>>>              if (host->ioaddr)
>>>>                      iounmap(host->ioaddr);
>>>>              if (pxa->res)
>>>> @@ -173,18 +193,23 @@ out:
>>>>
>>>> static int __devexit sdhci_pxa_remove(struct platform_device *pdev)  {
>>>> +     struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
>>>>      struct sdhci_host *host = platform_get_drvdata(pdev);
>>>>      struct sdhci_pxa *pxa = sdhci_priv(host);
>>>>      int dead = 0;
>>>>      u32 scratch;
>>>>
>>>>      if (host) {
>>>> +             if (pdata && pdata->ext_cd_cleanup)
>>>> +                     pdata->ext_cd_cleanup(&sdhci_pxa_notify_change, pdata);
>>>> +
>>>>              scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
>>>>              if (scratch == (u32)-1)
>>>>                      dead = 1;
>>>>
>>>>              sdhci_remove_host(host, dead);
>>>>
>>>> +             kfree(pxa->ops);
>>>>              if (host->ioaddr)
>>>>                      iounmap(host->ioaddr);
>>>>              if (pxa->res)
>>>> --
>>>> 1.7.0.4
>>>
>>>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux