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