Welcome to Soft32 Linux Forums!
FAQFAQ    SearchSearch      ProfileProfile    Private MessagesPrivate Messages   Log inLog in

[PATCH] davinci: MMC: add cpufreq support

 
   Soft32 Home -> Linux -> Kernel RSS
Next:  Accepted nss-pam-ldapd 0.7.1 (source i386)  
Author Message
Chaithrika U S

External


Since: Oct 20, 2009
Posts: 1



(Msg. 1) Posted: Tue Oct 20, 2009 7:20 am
Post subject: [PATCH] davinci: MMC: add cpufreq support
Archived from groups: linux>kernel (more info?)

Add cpufreq support to MMC driver. The clock divider value has to be
modified according to the controller input frequency.

Signed-off-by: Chaithrika U S <chaithrika RemoveThis @ti.com>
---
This patch applies on top of the following two patches submitted to LKML
http://patchwork.kernel.org/patch/54013/
http://patchwork.kernel.org/patch/50914/

drivers/mmc/host/davinci_mmc.c | 100 +++++++++++++++++++++++++++++++++------
1 files changed, 84 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index fe8f613..b54c779 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -25,6 +25,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/cpufreq.h>
#include <linux/mmc/host.h>
#include <linux/io.h>
#include <linux/irq.h>
@@ -200,6 +201,9 @@ struct mmc_davinci_host {
u8 version;
/* for ns in one cycle calculation */
unsigned ns_in_one_cycle;
+#ifdef CONFIG_CPU_FREQ
+ struct notifier_block freq_transition;
+#endif
};


@@ -739,27 +743,12 @@ static unsigned int calculate_freq_for_card(struct mmc_davinci_host *host,
return mmc_push_pull_divisor;
}

-static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
{
unsigned int open_drain_freq = 0, mmc_pclk = 0;
unsigned int mmc_push_pull_freq = 0;
struct mmc_davinci_host *host = mmc_priv(mmc);

- mmc_pclk = host->mmc_input_clk;
- dev_dbg(mmc_dev(host->mmc),
- "clock %dHz busmode %d powermode %d Vdd %04x\n",
- ios->clock, ios->bus_mode, ios->power_mode,
- ios->vdd);
- if (ios->bus_width == MMC_BUS_WIDTH_4) {
- dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
- writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
- host->base + DAVINCI_MMCCTL);
- } else {
- dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
- writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
- host->base + DAVINCI_MMCCTL);
- }
-
if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
u32 temp;

@@ -798,6 +787,29 @@ static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)

udelay(10);
}
+}
+
+static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ unsigned int mmc_pclk = 0;
+ struct mmc_davinci_host *host = mmc_priv(mmc);
+
+ mmc_pclk = host->mmc_input_clk;
+ dev_dbg(mmc_dev(host->mmc),
+ "clock %dHz busmode %d powermode %d Vdd %04x\n",
+ ios->clock, ios->bus_mode, ios->power_mode,
+ ios->vdd);
+ if (ios->bus_width == MMC_BUS_WIDTH_4) {
+ dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
+ writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
+ host->base + DAVINCI_MMCCTL);
+ } else {
+ dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
+ writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
+ host->base + DAVINCI_MMCCTL);
+ }
+
+ calculate_clk_divider(mmc, ios);

host->bus_mode = ios->bus_mode;
if (ios->power_mode == MMC_POWER_UP) {
@@ -1040,6 +1052,52 @@ static struct mmc_host_ops mmc_davinci_ops = {

/*----------------------------------------------------------------------*/

+#ifdef CONFIG_CPU_FREQ
+static int mmc_davinci_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct mmc_davinci_host *host;
+ unsigned int mmc_pclk;
+ struct mmc_host *mmc;
+ unsigned long flags;
+
+ host = container_of(nb, struct mmc_davinci_host, freq_transition);
+ mmc = host->mmc;
+ mmc_pclk = clk_get_rate(host->clk);
+
+ if (val == CPUFREQ_POSTCHANGE) {
+ spin_lock_irqsave(&mmc->lock, flags);
+ host->mmc_input_clk = mmc_pclk;
+ calculate_clk_divider(mmc, &mmc->ios);
+ spin_unlock_irqrestore(&mmc->lock, flags);
+ }
+
+ return 0;
+}
+
+static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host)
+{
+ host->freq_transition.notifier_call = mmc_davinci_cpufreq_transition;
+
+ return cpufreq_register_notifier(&host->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host)
+{
+ cpufreq_unregister_notifier(&host->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+#else
+static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host)
+{
+ return 0;
+}
+
+static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host)
+{
+}
+#endif
static void __init init_mmcsd_host(struct mmc_davinci_host *host)
{
/* DAT line portion is diabled and in reset state */
@@ -1169,6 +1227,12 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, host);

+ ret = mmc_davinci_cpufreq_register(host);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register cpufreq\n");
+ goto cpu_freq_fail;
+ }
+
ret = mmc_add_host(mmc);
if (ret < 0)
goto out;
@@ -1186,6 +1250,8 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
return 0;

out:
+ mmc_davinci_cpufreq_deregister(host);
+cpu_freq_fail:
if (host) {
davinci_release_dma_channels(host);

@@ -1215,6 +1281,8 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev)

platform_set_drvdata(pdev, NULL);
if (host) {
+ mmc_davinci_cpufreq_deregister(host);
+
mmc_remove_host(host->mmc);
free_irq(host->irq, host);

--
1.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo RemoveThis @vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to top
Login to vote
Linus Walleij

External


Since: May 14, 2009
Posts: 18



(Msg. 2) Posted: Tue Oct 20, 2009 5:20 pm
Post subject: Re: [PATCH] davinci: MMC: add cpufreq support [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

2009/10/20 Chaithrika U S <chaithrika DeleteThis @ti.com>:

> Add cpufreq support to MMC driver. The clock divider value has to be
> modified according to the controller input frequency.
> (...)
> @@ -1040,6 +1052,52 @@ static struct mmc_host_ops mmc_davinci_ops = {
>
>  /*----------------------------------------------------------------------*/
>
> +#ifdef CONFIG_CPU_FREQ
> +static int mmc_davinci_cpufreq_transition(struct notifier_block *nb,
> +                                    unsigned long val, void *data)
> +{
> +       struct mmc_davinci_host *host;
> +       unsigned int mmc_pclk;
> +       struct mmc_host *mmc;
> +       unsigned long flags;
> +
> +       host = container_of(nb, struct mmc_davinci_host, freq_transition);
> +       mmc = host->mmc;
> +       mmc_pclk = clk_get_rate(host->clk);
> +
> +       if (val == CPUFREQ_POSTCHANGE) {
> +               spin_lock_irqsave(&mmc->lock, flags);
> +               host->mmc_input_clk = mmc_pclk;
> +               calculate_clk_divider(mmc, &mmc->ios);
> +               spin_unlock_irqrestore(&mmc->lock, flags);
> +       }
> +
> +       return 0;
> +}

Now the way I understand it CPUfreq is about rising/lowering the
frequency of the *CPU* when the load of the system goes up/down.

I highly suspect that there is no general rule that davinci's host->clk
will actually change just because the CPU changes frequency?

I don't know enough about davinci to tell but I suspect there are
system-wide operating points hidden behind this and CPUfreq
is being (ab)used for changing and notifying the system frequency
overall. Some of these transitions include changing the MMC clock
so if you simply broadcast them all?

I really believe this is just masking the problem that the clk
framework need support of real clk notifiers that can notify clk
users pre/post a clk change. This is really what you want for a
driver like this.

Now I don't know the davinci consensus around these things,
do you always use CPUfreq like this, for changing frequencies
of clocks that are not CPU clocks at all?

I have similar code boiling for the MMCI/PL180 PrimeCell but
I just cannot submit that because the PrimeCell is generic and
there is no way I can implicitly correlate the CPU clk with the
MMCI host clk like this, so I have to wait for real clock notifiers
(or implement them myself...)

Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo DeleteThis @vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to top
Login to vote
Chaithrika U S

External


Since: Oct 21, 2009
Posts: 2



(Msg. 3) Posted: Wed Oct 21, 2009 5:20 am
Post subject: RE: [PATCH] davinci: MMC: add cpufreq support [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

On Wed, Oct 21, 2009 at 03:44:51, Linus Walleij wrote:
> 2009/10/20 Chaithrika U S <chaithrika.DeleteThis@ti.com>:
>
> > Add cpufreq support to MMC driver. The clock divider value has to be
> > modified according to the controller input frequency.
> > (...)
> > @@ -1040,6 +1052,52 @@ static struct mmc_host_ops mmc_davinci_ops = {
> >
> >  /*----------------------------------------------------------------------*/
> >
> > +#ifdef CONFIG_CPU_FREQ
> > +static int mmc_davinci_cpufreq_transition(struct notifier_block *nb,
> > +                                    unsigned long val, void *data)
> > +{
> > +       struct mmc_davinci_host *host;
> > +       unsigned int mmc_pclk;
> > +       struct mmc_host *mmc;
> > +       unsigned long flags;
> > +
> > +       host = container_of(nb, struct mmc_davinci_host, freq_transition);
> > +       mmc = host->mmc;
> > +       mmc_pclk = clk_get_rate(host->clk);
> > +
> > +       if (val == CPUFREQ_POSTCHANGE) {
> > +               spin_lock_irqsave(&mmc->lock, flags);
> > +               host->mmc_input_clk = mmc_pclk;
> > +               calculate_clk_divider(mmc, &mmc->ios);
> > +               spin_unlock_irqrestore(&mmc->lock, flags);
> > +       }
> > +
> > +       return 0;
> > +}
>
> Now the way I understand it CPUfreq is about rising/lowering the
> frequency of the *CPU* when the load of the system goes up/down.
>
> I highly suspect that there is no general rule that davinci's host->clk
> will actually change just because the CPU changes frequency?
>

In this case, the PLL controller which supplies clock to the CPU also
provides clock to the MMC/SD peripheral. Hence, the host->clk changes
with the CPU frequency changes.

> I don't know enough about davinci to tell but I suspect there are
> system-wide operating points hidden behind this and CPUfreq
> is being (ab)used for changing and notifying the system frequency
> overall. Some of these transitions include changing the MMC clock
> so if you simply broadcast them all?
>
> I really believe this is just masking the problem that the clk
> framework need support of real clk notifiers that can notify clk
> users pre/post a clk change. This is really what you want for a
> driver like this.
>
> Now I don't know the davinci consensus around these things,
> do you always use CPUfreq like this, for changing frequencies
> of clocks that are not CPU clocks at all?
>

In the case where the module clock is dependent on CPU clock, cpufreq
is used to adjust the peripheral clock based on the CPU clock. Similar
implementation is present in Samsung S3C MCI driver too.

> I have similar code boiling for the MMCI/PL180 PrimeCell but
> I just cannot submit that because the PrimeCell is generic and
> there is no way I can implicitly correlate the CPU clk with the
> MMCI host clk like this, so I have to wait for real clock notifiers
> (or implement them myself...)
>
> Linus Walleij
>
>

Regards,
Chaithrika


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo.DeleteThis@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to top
Login to vote
Chaithrika U S

External


Since: Oct 21, 2009
Posts: 2



(Msg. 4) Posted: Tue Nov 03, 2009 11:20 pm
Post subject: RE: [PATCH] davinci: MMC: add cpufreq support [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Do you have any review comments or suggestions for this patch?

Regards,
Chaithrika

On Tue, Oct 20, 2009 at 17:40:10, Chaithrika U S wrote:
> Add cpufreq support to MMC driver. The clock divider value has to be
> modified according to the controller input frequency.
>
> Signed-off-by: Chaithrika U S <chaithrika.RemoveThis@ti.com>
> ---
> This patch applies on top of the following two patches submitted to LKML
> http://patchwork.kernel.org/patch/54013/
> http://patchwork.kernel.org/patch/50914/
>
> drivers/mmc/host/davinci_mmc.c | 100 +++++++++++++++++++++++++++++++++------
> 1 files changed, 84 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
> index fe8f613..b54c779 100644
> --- a/drivers/mmc/host/davinci_mmc.c
> +++ b/drivers/mmc/host/davinci_mmc.c
> @@ -25,6 +25,7 @@
> #include <linux/platform_device.h>
> #include <linux/clk.h>
> #include <linux/err.h>
> +#include <linux/cpufreq.h>
> #include <linux/mmc/host.h>
> #include <linux/io.h>
> #include <linux/irq.h>
> @@ -200,6 +201,9 @@ struct mmc_davinci_host {
> u8 version;
> /* for ns in one cycle calculation */
> unsigned ns_in_one_cycle;
> +#ifdef CONFIG_CPU_FREQ
> + struct notifier_block freq_transition;
> +#endif
> };
>
>
> @@ -739,27 +743,12 @@ static unsigned int calculate_freq_for_card(struct mmc_davinci_host *host,
> return mmc_push_pull_divisor;
> }
>
> -static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> +static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
> {
> unsigned int open_drain_freq = 0, mmc_pclk = 0;
> unsigned int mmc_push_pull_freq = 0;
> struct mmc_davinci_host *host = mmc_priv(mmc);
>
> - mmc_pclk = host->mmc_input_clk;
> - dev_dbg(mmc_dev(host->mmc),
> - "clock %dHz busmode %d powermode %d Vdd %04x\n",
> - ios->clock, ios->bus_mode, ios->power_mode,
> - ios->vdd);
> - if (ios->bus_width == MMC_BUS_WIDTH_4) {
> - dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
> - writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
> - host->base + DAVINCI_MMCCTL);
> - } else {
> - dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
> - writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
> - host->base + DAVINCI_MMCCTL);
> - }
> -
> if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
> u32 temp;
>
> @@ -798,6 +787,29 @@ static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>
> udelay(10);
> }
> +}
> +
> +static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> + unsigned int mmc_pclk = 0;
> + struct mmc_davinci_host *host = mmc_priv(mmc);
> +
> + mmc_pclk = host->mmc_input_clk;
> + dev_dbg(mmc_dev(host->mmc),
> + "clock %dHz busmode %d powermode %d Vdd %04x\n",
> + ios->clock, ios->bus_mode, ios->power_mode,
> + ios->vdd);
> + if (ios->bus_width == MMC_BUS_WIDTH_4) {
> + dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
> + writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
> + host->base + DAVINCI_MMCCTL);
> + } else {
> + dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
> + writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
> + host->base + DAVINCI_MMCCTL);
> + }
> +
> + calculate_clk_divider(mmc, ios);
>
> host->bus_mode = ios->bus_mode;
> if (ios->power_mode == MMC_POWER_UP) {
> @@ -1040,6 +1052,52 @@ static struct mmc_host_ops mmc_davinci_ops = {
>
> /*----------------------------------------------------------------------*/
>
> +#ifdef CONFIG_CPU_FREQ
> +static int mmc_davinci_cpufreq_transition(struct notifier_block *nb,
> + unsigned long val, void *data)
> +{
> + struct mmc_davinci_host *host;
> + unsigned int mmc_pclk;
> + struct mmc_host *mmc;
> + unsigned long flags;
> +
> + host = container_of(nb, struct mmc_davinci_host, freq_transition);
> + mmc = host->mmc;
> + mmc_pclk = clk_get_rate(host->clk);
> +
> + if (val == CPUFREQ_POSTCHANGE) {
> + spin_lock_irqsave(&mmc->lock, flags);
> + host->mmc_input_clk = mmc_pclk;
> + calculate_clk_divider(mmc, &mmc->ios);
> + spin_unlock_irqrestore(&mmc->lock, flags);
> + }
> +
> + return 0;
> +}
> +
> +static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host)
> +{
> + host->freq_transition.notifier_call = mmc_davinci_cpufreq_transition;
> +
> + return cpufreq_register_notifier(&host->freq_transition,
> + CPUFREQ_TRANSITION_NOTIFIER);
> +}
> +
> +static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host)
> +{
> + cpufreq_unregister_notifier(&host->freq_transition,
> + CPUFREQ_TRANSITION_NOTIFIER);
> +}
> +#else
> +static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host)
> +{
> + return 0;
> +}
> +
> +static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host)
> +{
> +}
> +#endif
> static void __init init_mmcsd_host(struct mmc_davinci_host *host)
> {
> /* DAT line portion is diabled and in reset state */
> @@ -1169,6 +1227,12 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, host);
>
> + ret = mmc_davinci_cpufreq_register(host);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to register cpufreq\n");
> + goto cpu_freq_fail;
> + }
> +
> ret = mmc_add_host(mmc);
> if (ret < 0)
> goto out;
> @@ -1186,6 +1250,8 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
> return 0;
>
> out:
> + mmc_davinci_cpufreq_deregister(host);
> +cpu_freq_fail:
> if (host) {
> davinci_release_dma_channels(host);
>
> @@ -1215,6 +1281,8 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, NULL);
> if (host) {
> + mmc_davinci_cpufreq_deregister(host);
> +
> mmc_remove_host(host->mmc);
> free_irq(host->irq, host);
>
> --
> 1.5.6
>


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo.RemoveThis@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to top
Login to vote
Display posts from previous:   
Related Topics:
[PATCH] Rewrite lock in cpufreq to eliminate cpufreq/hotpl.. - Yet another attempt to resolve cpufreq and hotplug locking issues. Patchset has 3 patches: * Rewrite the lock..

[patch] ACPI: fix cpufreq regression - Subject: [patch] ACPI: fix cpufreq regression From: Ingo Molnar <mingo@elte.hu> recently cpufreq support on my l...

[patch] cleanup cpufreq kconfig options - Adds proper lines to help output of kconfig so people can find the module names. Also fixed some broken leading spaces....

[patch] cpufreq: do not declare undefined functions - fill_powernow_table_pstate() and fill_powernow_table_fidvid() are only defined and used for X86_POWERNOW_K8_ACPI. Cc:....

[PATCH] i386 cpufreq: cs5530A allows active idle - The cs5530A will be able to go into active idle (PWRSVE) so its PCI class revision should be accurately stored. Cc:..

[PATCH 2.6.20-rc3] cpufreq: check sysfs_create_link return.. - Trivial patch to check sysfs_create_link return values. Fail gracefully if needed. Signed-off-by: Ahmed Darwish..
       Soft32 Home -> Linux -> Kernel All times are: Pacific Time (US & Canada) (change)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Categories:
 Windows
  Linux
 Mac
 PDA


[ Contact us | Terms of Service/Privacy Policy ]