From: Rajendra Nayak <rnayak@ti.com>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-omap@vger.kernel.org, khilman@deeprootsystems.com,
Benoit Cousson <b-cousson@ti.com>
Subject: RE: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
Date: Tue, 11 Jan 2011 19:52:27 +0530 [thread overview]
Message-ID: <9d4bc48cf55c9070297ef446d6d7d260@mail.gmail.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1101101749140.5731@utopia.booyaka.com>
Hi Paul,
> -----Original Message-----
> From: Paul Walmsley [mailto:paul@pwsan.com]
> Sent: Tuesday, January 11, 2011 6:36 AM
> To: Rajendra Nayak
> Cc: linux-omap@vger.kernel.org; khilman@deeprootsystems.com;
b-cousson@ti.com
> Subject: Re: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to
handle deps
>
> Hi Rajendra
>
> On Wed, 5 Jan 2011, Rajendra Nayak wrote:
>
> > Define the following architecture specific funtions for omap2/3
> > .clkdm_add_wkdep
> > .clkdm_del_wkdep
> > .clkdm_read_wkdep
> > .clkdm_clear_all_wkdeps
> > .clkdm_add_sleepdep
> > .clkdm_del_sleepdep
> > .clkdm_read_sleepdep
> > .clkdm_clear_all_sleepdeps
> >
> > Convert the platform-independent framework to call these functions.
> > With this also move the clkdm lookups for all wkdep_srcs and
> > sleepdep_srcs at clkdm_init.
> >
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > ---
> > arch/arm/mach-omap2/Makefile | 2 +
> > arch/arm/mach-omap2/clockdomain.c | 80
++++++---------
> > arch/arm/mach-omap2/clockdomain.h | 2 +
> > arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 113
++++++++++++++++++++++
> > arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
> > 5 files changed, 150 insertions(+), 49 deletions(-)
> > create mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> >
> > diff --git a/arch/arm/mach-omap2/Makefile
b/arch/arm/mach-omap2/Makefile
> > index 4ab82f6..d28db0a 100644
> > --- a/arch/arm/mach-omap2/Makefile
> > +++ b/arch/arm/mach-omap2/Makefile
> > @@ -102,8 +102,10 @@ obj-$(CONFIG_ARCH_OMAP4) +=
$(powerdomain-common) \
> >
> > # PRCM clockdomain control
> > obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
> > + clockdomain2xxx_3xxx.o \
> > clockdomains2xxx_3xxx_data.o
> > obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
> > + clockdomain2xxx_3xxx.o \
> > clockdomains2xxx_3xxx_data.o
> > obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
> > clockdomains44xx_data.o
> > diff --git a/arch/arm/mach-omap2/clockdomain.c
b/arch/arm/mach-omap2/clockdomain.c
> > index 3e40184..c32480c 100644
> > --- a/arch/arm/mach-omap2/clockdomain.c
> > +++ b/arch/arm/mach-omap2/clockdomain.c
> > @@ -308,6 +308,7 @@ void clkdm_init(struct clockdomain **clkdms,
> > struct clockdomain **c = NULL;
> > struct clockdomain *clkdm;
> > struct clkdm_autodep *autodep = NULL;
> > + struct clkdm_dep *cd;
> >
> > if (!custom_funcs)
> > WARN(1, "No custom clkdm functions registered\n");
> > @@ -333,7 +334,18 @@ void clkdm_init(struct clockdomain **clkdms,
> > else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
> > omap2_clkdm_deny_idle(clkdm);
> >
> > + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > + cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > + }
> > clkdm_clear_all_wkdeps(clkdm);
> > +
> > + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name;
cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > + cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > + }
> > clkdm_clear_all_sleepdeps(clkdm);
> > }
> > }
> > @@ -445,8 +457,8 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > pr_debug("clockdomain: hardware will wake up %s when %s
wakes "
> > "up\n", clkdm1->name, clkdm2->name);
> >
> > - omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
PM_WKDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_add_wkdep)
> > + arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
>
> Putting this test inside the loop doesn't make sense to me; arch_clkdm
and
> arch_clkdm->clkdm_* only need to be tested once outside the loop.
Please
> do somtehing like this instead:
Sure, will do the changes.
>
> cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
> if (IS_ERR(cd))
> ret = PTR_ERR(cd);
>
> if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
> ret = -EINVAL;
>
> if (ret) {
> pr_debug("clockdomain: hardware cannot set/clear wake up
of "
> "%s when %s wakes up\n", clkdm1->name,
clkdm2->name);
> return ret;
> }
>
> if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
> pr_debug("clockdomain: hardware will wake up %s when %s
wakes "
> "up\n", clkdm1->name, clkdm2->name);
>
> arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
> }
>
> As in the above code, we should probably return an error if the function
> pointers don't exist. That should allow us to get rid of the
>
> if (!cpu_is_omap34xx())
> return -EINVAL;
>
> tests in the sleepdep functions, since that can now be handled by just
> leaving those function pointers NULL; see the below comments.
>
> These comments also apply to most of the other functions here.
>
> > @@ -480,8 +492,8 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > pr_debug("clockdomain: hardware will no longer wake up %s
"
> > "after %s wakes up\n", clkdm1->name,
clkdm2->name);
> >
> > - omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
PM_WKDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_del_wkdep)
> > + arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
> > }
> >
> > return 0;
> > @@ -516,8 +528,10 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > }
> >
> > /* XXX It's faster to return the atomic wkdep_usecount */
> > - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
PM_WKDEP,
> > - (1 << clkdm2->dep_bit));
> > + if (arch_clkdm && arch_clkdm->clkdm_read_wkdep)
> > + return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
> > +
> > + return -EINVAL;
> > }
> >
> > /**
> > @@ -532,25 +546,11 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > */
> > int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> > {
> > - struct clkdm_dep *cd;
> > - u32 mask = 0;
> > -
> > if (!clkdm)
> > return -EINVAL;
> >
> > - for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> > - if (!omap_chip_is(cd->omap_chip))
> > - continue;
> > -
> > - if (!cd->clkdm && cd->clkdm_name)
> > - cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > -
> > - /* PRM accesses are slow, so minimize them */
> > - mask |= 1 << cd->clkdm->dep_bit;
> > - atomic_set(&cd->wkdep_usecount, 0);
> > - }
> > -
> > - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
PM_WKDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_clear_all_wkdeps)
> > + arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
> >
> > return 0;
> > }
> > @@ -589,9 +589,8 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > pr_debug("clockdomain: will prevent %s from sleeping if %s
"
> > "is active\n", clkdm1->name, clkdm2->name);
> >
> > - omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_add_sleepdep)
> > + arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
> > }
> >
> > return 0;
> > @@ -632,9 +631,8 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > "sleeping if %s is active\n", clkdm1->name,
> > clkdm2->name);
> >
> > - omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_del_sleepdep)
> > + arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
> > }
> >
> > return 0;
> > @@ -675,9 +673,10 @@ int clkdm_read_sleepdep(struct clockdomain
*clkdm1, struct clockdomain *clkdm2)
> > }
> >
> > /* XXX It's faster to return the atomic sleepdep_usecount */
> > - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP,
> > - (1 << clkdm2->dep_bit));
> > + if (arch_clkdm && arch_clkdm->clkdm_read_sleepdep)
> > + return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
> > +
> > + return -EINVAL;
> > }
> >
> > /**
> > @@ -692,29 +691,14 @@ int clkdm_read_sleepdep(struct clockdomain
*clkdm1, struct clockdomain *clkdm2)
> > */
> > int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> > {
> > - struct clkdm_dep *cd;
> > - u32 mask = 0;
> > -
> > if (!cpu_is_omap34xx())
> > return -EINVAL;
> >
> > if (!clkdm)
> > return -EINVAL;
> >
> > - for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> > - if (!omap_chip_is(cd->omap_chip))
> > - continue;
> > -
> > - if (!cd->clkdm && cd->clkdm_name)
> > - cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > -
> > - /* PRM accesses are slow, so minimize them */
> > - mask |= 1 << cd->clkdm->dep_bit;
> > - atomic_set(&cd->sleepdep_usecount, 0);
> > - }
> > -
> > - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_clear_all_sleepdeps)
> > + arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
> >
> > return 0;
> > }
> > diff --git a/arch/arm/mach-omap2/clockdomain.h
b/arch/arm/mach-omap2/clockdomain.h
> > index 346efa2..a9cda27 100644
> > --- a/arch/arm/mach-omap2/clockdomain.h
> > +++ b/arch/arm/mach-omap2/clockdomain.h
> > @@ -181,4 +181,6 @@ int omap2_clkdm_clk_disable(struct clockdomain
*clkdm, struct clk *clk);
> > extern void __init omap2_clockdomains_init(void);
> > extern void __init omap44xx_clockdomains_init(void);
> >
> > +extern struct clkdm_ops omap2_clkdm_operations;
> > +
> > #endif
> > diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> > new file mode 100644
> > index 0000000..a7303bd
> > --- /dev/null
> > +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> > @@ -0,0 +1,113 @@
> > +/*
> > + * OMAP2 and OMAP3 clockdomain control
> > + *
> > + * Copyright (C) 2008-2010 Texas Instruments, Inc.
> > + * Copyright (C) 2008-2010 Nokia Corporation
> > + *
> > + * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> > + * Rajendra Nayak <rnayak@ti.com>
> > + *
> > + * This program is free software; you can redistribute it and/or
modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <plat/prcm.h>
> > +#include "prm.h"
> > +#include "prm2xxx_3xxx.h"
> > +#include "cm.h"
> > +#include "cm2xxx_3xxx.h"
> > +#include "cm-regbits-24xx.h"
> > +#include "cm-regbits-34xx.h"
> > +#include "clockdomain.h"
> > +
> > +static void omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> > +}
> > +
> > +static void omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> > +}
> > +
> > +static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> > + PM_WKDEP, (1 << clkdm2->dep_bit));
> > +}
> > +
> > +static void omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> > +{
> > + struct clkdm_dep *cd;
> > + u32 mask = 0;
> > +
> > + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > +
> > + /* PRM accesses are slow, so minimize them */
> > + mask |= 1 << cd->clkdm->dep_bit;
> > + atomic_set(&cd->wkdep_usecount, 0);
> > + }
> > +
> > + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> > + PM_WKDEP);
> > +}
> > +
> > +static void omap2_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP);
> > +}
>
> OMAP2xxx didn't support software-controlled sleepdeps, so this should
not
> be present (note the 'OMAP3430' in the OMAP3430_CM_SLEEPDEP macro).
Yup, realized after I sent the patches out. Will fix them in V2.
Thanks
Rajendra
>
> > +
> > +static void omap2_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP);
> > +}
>
> as above
>
> > +
> > +static int omap2_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP, (1 <<
clkdm2->dep_bit));
> > +}
>
> as above
>
> > +
> > +static void omap2_clkdm_clear_all_sleepdeps(struct clockdomain
*clkdm)
> > +{
> > + struct clkdm_dep *cd;
> > + u32 mask = 0;
> > +
> > + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > +
> > + /* PRM accesses are slow, so minimize them */
> > + mask |= 1 << cd->clkdm->dep_bit;
> > + atomic_set(&cd->sleepdep_usecount, 0);
> > + }
> > + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP);
> > +}
>
> as above
>
> > +
> > +struct clkdm_ops omap2_clkdm_operations = {
> > + .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
> > + .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
> > + .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
> > + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> > + .clkdm_add_sleepdep = omap2_clkdm_add_sleepdep,
> > + .clkdm_del_sleepdep = omap2_clkdm_del_sleepdep,
> > + .clkdm_read_sleepdep = omap2_clkdm_read_sleepdep,
> > + .clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
>
> These four function pointers should not be present. OMAP2xxx did not
> support software-controlled sleepdeps. You'll probably need to add
> omap3_clkdm_operations in this patch.
>
> > +};
> > diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
b/arch/arm/mach-
> omap2/clockdomains2xxx_3xxx_data.c
> > index 8cab07a..ba0bbbd 100644
> > --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> > +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> > @@ -856,5 +856,5 @@ static struct clockdomain *clockdomains_omap2[]
__initdata = {
> >
> > void __init omap2_clockdomains_init(void)
> > {
> > - clkdm_init(clockdomains_omap2, clkdm_autodeps, NULL);
> > + clkdm_init(clockdomains_omap2, clkdm_autodeps,
&omap2_clkdm_operations);
> > }
> > --
> > 1.7.0.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-omap"
in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
>
> - Paul
next prev parent reply other threads:[~2011-01-11 14:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-05 14:22 [PATCH 0/5] Clockdomain split series Rajendra Nayak
2011-01-05 14:22 ` [PATCH 1/5] OMAP: clockdomain: Infrastructure to put arch specific code Rajendra Nayak
2011-01-05 14:22 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Rajendra Nayak
2011-01-05 14:22 ` [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm Rajendra Nayak
2011-01-05 14:22 ` [PATCH 4/5] OMAP: clockdomain: Arch specific funcs for hwsup control " Rajendra Nayak
2011-01-05 14:22 ` [PATCH 5/5] OMAP: clockdomain: Arch specific funcs for clkdm_clk_enable/disable Rajendra Nayak
2011-01-11 1:05 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Paul Walmsley
2011-01-11 14:22 ` Rajendra Nayak [this message]
2011-01-11 1:32 ` Paul Walmsley
2011-01-11 14:20 ` Rajendra Nayak
2011-01-14 6:20 ` Paul Walmsley
2011-01-19 11:01 ` Rajendra Nayak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9d4bc48cf55c9070297ef446d6d7d260@mail.gmail.com \
--to=rnayak@ti.com \
--cc=b-cousson@ti.com \
--cc=khilman@deeprootsystems.com \
--cc=linux-omap@vger.kernel.org \
--cc=paul@pwsan.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox