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]

 



was interested in the 9xx code. 


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
>> 
>> 

?韬{.n?????%??檩??w?{.n???{炳i?)?骅w*jg????????G??⒏⒎?:+v????????????"??????


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

  Powered by Linux