Re: [PATCH PM-QA] cputopology: add scheduler domain flag test

2015-02-27 Thread Mike Turquette
Quoting Vincent Guittot (2015-02-27 00:39:53)
 On 27 February 2015 at 01:32, Mike Turquette mturque...@linaro.org wrote:
  Quoting Larry Bassel (2015-02-24 13:50:51)
  On 24 Feb 15 21:53, Vincent Guittot wrote:
   On 8 February 2015 at 01:08, Larry Bassel larry.bas...@linaro.org 
   wrote:
+check_sched_domain_flags() {
+
+cpu_num=$1
+domain_num=$2
+
+
sched_domain_flags=/proc/sys/kernel/sched_domain/$cpu_num/domain$domain_num/flags
+val=$(cat $sched_domain_flags)
+
+check sched_domain_flags (domain $domain_num) test \$val\ != 
\-1\
+printf domain$domain_num flag 0x%x\n $val
+
+is_flag_set $val  0x80  domain$domain_num share cpu capacity 
flag
+is_flag_set $val  0x100  domain$domain_num share power domain 
flag
+is_flag_set $val  0x200  domain$domain_num share cpu package 
resources flag
  
   could you use a list of masks to be tested against $val instead of
   hard coding them ? the number of flags to be tested should increase
   with eas patchset
  
 
  Yes, this is a good idea. What is the best (i.e. cleanest/most
  maintainable/most portable) way of doing this in a shell script?
 
  SD flags are not exported to userspace so we can't scrape them at
  run-time from /usr/include/linux/sched.h. That would be the most
  future-proof way of doing it, but would require packaging kernel
  headers, etc.
 
  Arrays of masks and corresponding strings? I think I remember
  Lisa telling me that arrays aren't portable as they are not in
  all shells.
 
  The current implementation isn't very future-proof. If the definition of
  a flag is missing from the script then it is silently ignored. A better
  way is to iterate over every bit in the 32-bit flag mask and print out
  whether that bit is set or unset, and also a human-friendly definition
  if that is known. But not having the human-readable definition should
  not exclude the numeric value from being displayed since we might create
  new flags as Vincent suggested.
 
 In fact, the flag value is already displayed by the script before
 analysing the bit we are interested in and i'm not sure that we want
 to display all the flags as some are set out of our control or
 irrelevant for the test. Nevetheless, we can test the sched_domain
 flags and compare it with a defined bitmask so we can display a
 warning if a new unknow flag appears

Yes that sounds good. It allows us to catch new flags but removes the
noise from stable flags that we are not interested in. Do you have the
bit mask of stable and uninteresting flags?

Regards,
Mike

 
 Regards
 
 
  More realistically it looks like all of the current flags fit in the
  bottom 16 bits of the flag mask, so maybe we can just print the first 16
  bits instead of 32. Maybe something like:
 
  for i in $(seq 16); do is_flag_set $val $i; done
 
  Where is_flag_set prints whether bit $i is set or unset in $val.
  is_flag_set can also maintain the table/array of human-readable flags
  for well-defined definitions that we consider to be stable/unchanging.
 
  Regards,
  Mike
 
 
  Thanks.
 
  Larry
 
  ___
  linaro-dev mailing list
  linaro-dev@lists.linaro.org
  http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH PM-QA] cputopology: add scheduler domain flag test

2015-02-26 Thread Mike Turquette
Quoting Larry Bassel (2015-02-24 13:50:51)
 On 24 Feb 15 21:53, Vincent Guittot wrote:
  On 8 February 2015 at 01:08, Larry Bassel larry.bas...@linaro.org wrote:
   +check_sched_domain_flags() {
   +
   +cpu_num=$1
   +domain_num=$2
   +
   +
   sched_domain_flags=/proc/sys/kernel/sched_domain/$cpu_num/domain$domain_num/flags
   +val=$(cat $sched_domain_flags)
   +
   +check sched_domain_flags (domain $domain_num) test \$val\ != 
   \-1\
   +printf domain$domain_num flag 0x%x\n $val
   +
   +is_flag_set $val  0x80  domain$domain_num share cpu capacity flag
   +is_flag_set $val  0x100  domain$domain_num share power domain flag
   +is_flag_set $val  0x200  domain$domain_num share cpu package 
   resources flag
  
  could you use a list of masks to be tested against $val instead of
  hard coding them ? the number of flags to be tested should increase
  with eas patchset
  
 
 Yes, this is a good idea. What is the best (i.e. cleanest/most
 maintainable/most portable) way of doing this in a shell script?

SD flags are not exported to userspace so we can't scrape them at
run-time from /usr/include/linux/sched.h. That would be the most
future-proof way of doing it, but would require packaging kernel
headers, etc.

 Arrays of masks and corresponding strings? I think I remember
 Lisa telling me that arrays aren't portable as they are not in
 all shells.

The current implementation isn't very future-proof. If the definition of
a flag is missing from the script then it is silently ignored. A better
way is to iterate over every bit in the 32-bit flag mask and print out
whether that bit is set or unset, and also a human-friendly definition
if that is known. But not having the human-readable definition should
not exclude the numeric value from being displayed since we might create
new flags as Vincent suggested.

More realistically it looks like all of the current flags fit in the
bottom 16 bits of the flag mask, so maybe we can just print the first 16
bits instead of 32. Maybe something like:

for i in $(seq 16); do is_flag_set $val $i; done

Where is_flag_set prints whether bit $i is set or unset in $val.
is_flag_set can also maintain the table/array of human-readable flags
for well-defined definitions that we consider to be stable/unchanging.

Regards,
Mike

 
 Thanks.
 
 Larry
 
 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


embedding html into the wiki

2013-09-03 Thread Mike Turquette
Hi all,

I wanted to create a google doc spreadsheet for tracking some team
activity and then embed in iframe for that spreadsheet into the team
wiki page.

I tried adding something like the following:

=== Project Status ===
{{{#!html
iframe width='500' height='300' frameborder='0'
src='https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=true'/iframe
}}}

Nothing shows up. I decided to try an easier test:

=== Project Status ===
{{{#!html
bHello, world!/b
}}}

I can see the Hello, world! string, but the bold tags were ignored.

So is HTML embedding disabled in MoinMoin? Any idea on the best way to proceed?

Thanks,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: embedding html into the wiki

2013-09-03 Thread Mike Turquette
On Tue, Sep 3, 2013 at 2:29 PM, Fathi Boudra fathi.bou...@linaro.org wrote:
 Hi Mike,

 On 4 September 2013 00:09, Mike Turquette mturque...@linaro.org wrote:
 Hi all,

 I wanted to create a google doc spreadsheet for tracking some team
 activity and then embed in iframe for that spreadsheet into the team
 wiki page.

 I tried adding something like the following:

 === Project Status ===
 {{{#!html
 iframe width='500' height='300' frameborder='0'
 src='https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=true'/iframe
 }}}

 Nothing shows up. I decided to try an easier test:

 === Project Status ===
 {{{#!html
 bHello, world!/b
 }}}

 I can see the Hello, world! string, but the bold tags were ignored.

 So is HTML embedding disabled in MoinMoin? Any idea on the best way to 
 proceed?

 IFrame(https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=truewidth=800height=600,
 800, 600)

Thanks for the quick response Fathi! I'm still unable to get this to
work after trying several variations. Do you have an example in the
Linaro wiki of iframe usage? Am I supposed to wrap the
IFrame(..) part up in some other HTML wrapper?

Thanks,
Mike


 Thanks,
 Mike

 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev


 Cheers,
 --
 Fathi Boudra
 Builds and Baselines Manager | Release Manager
 Linaro.org | Open source software for ARM SoCs

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: embedding html into the wiki

2013-09-03 Thread Mike Turquette
On Tue, Sep 3, 2013 at 5:03 PM, John Stultz john.stu...@linaro.org wrote:
 On 09/03/2013 04:33 PM, Mike Turquette wrote:
 On Tue, Sep 3, 2013 at 2:29 PM, Fathi Boudra fathi.bou...@linaro.org wrote:
 Hi Mike,

 On 4 September 2013 00:09, Mike Turquette mturque...@linaro.org wrote:
 Hi all,

 I wanted to create a google doc spreadsheet for tracking some team
 activity and then embed in iframe for that spreadsheet into the team
 wiki page.

 I tried adding something like the following:

 === Project Status ===
 {{{#!html
 iframe width='500' height='300' frameborder='0'
 src='https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=true'/iframe
 }}}

 Nothing shows up. I decided to try an easier test:

 === Project Status ===
 {{{#!html
 bHello, world!/b
 }}}

 I can see the Hello, world! string, but the bold tags were ignored.

 So is HTML embedding disabled in MoinMoin? Any idea on the best way to 
 proceed?
 IFrame(https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=truewidth=800height=600,
 800, 600)
 Thanks for the quick response Fathi! I'm still unable to get this to
 work after trying several variations. Do you have an example in the
 Linaro wiki of iframe usage? Am I supposed to wrap the
 IFrame(..) part up in some other HTML wrapper?

 I'm using it here:
 https://wiki.linaro.org/WorkingGroups/Kernel/AndroidUpstreaming

Great, turns out it wasn't pilot error, per se. I was using Google
Drive's publish feature which gave me some strange URL that didn't
play nice with moinmoin IFrame function. Just using the normal
document share link did the trick.

Regards,
Mike


 thanks
 -john


 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: embedding html into the wiki

2013-09-03 Thread Mike Turquette
On Tue, Sep 3, 2013 at 5:56 PM, Mike Turquette mturque...@linaro.org wrote:
 On Tue, Sep 3, 2013 at 5:03 PM, John Stultz john.stu...@linaro.org wrote:
 On 09/03/2013 04:33 PM, Mike Turquette wrote:
 On Tue, Sep 3, 2013 at 2:29 PM, Fathi Boudra fathi.bou...@linaro.org 
 wrote:
 Hi Mike,

 On 4 September 2013 00:09, Mike Turquette mturque...@linaro.org wrote:
 Hi all,

 I wanted to create a google doc spreadsheet for tracking some team
 activity and then embed in iframe for that spreadsheet into the team
 wiki page.

 I tried adding something like the following:

 === Project Status ===
 {{{#!html
 iframe width='500' height='300' frameborder='0'
 src='https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=true'/iframe
 }}}

 Nothing shows up. I decided to try an easier test:

 === Project Status ===
 {{{#!html
 bHello, world!/b
 }}}

 I can see the Hello, world! string, but the bold tags were ignored.

 So is HTML embedding disabled in MoinMoin? Any idea on the best way to 
 proceed?
 IFrame(https://docs.google.com/spreadsheet/pub?key=0Ajx9x7R7ZLSidGVWcVI5YzhWVER5ZDdVbENKcDh1RUEoutput=htmlwidget=truewidth=800height=600,
 800, 600)
 Thanks for the quick response Fathi! I'm still unable to get this to
 work after trying several variations. Do you have an example in the
 Linaro wiki of iframe usage? Am I supposed to wrap the
 IFrame(..) part up in some other HTML wrapper?

 I'm using it here:
 https://wiki.linaro.org/WorkingGroups/Kernel/AndroidUpstreaming

 Great, turns out it wasn't pilot error, per se. I was using Google
 Drive's publish feature which gave me some strange URL that didn't
 play nice with moinmoin IFrame function. Just using the normal
 document share link did the trick.

For the curious, results can be seen here:
https://wiki.linaro.org/WorkingGroups/PowerManagement/SubTeams/PmCore


 Regards,
 Mike


 thanks
 -john


 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: Panda, Android Bluetooth

2013-08-20 Thread Mike Turquette
Quoting Vishal Bhoj (2013-08-19 20:35:48)
  Even on ICS it was partially working. File transfer resulted in crashes on
 4.0.4. You can try this release which is based on 4.0.3 :
 http://releases.linaro.org/12.03/android/leb-panda/

Great, thanks for pointer.

snip
 I am trying to get this build working again:
 https://android-build.linaro.org/builds/~linaro-android-archive/panda-ics-
 gcc47-omapzoom-stable-blob/
 
 This build is based on 3.0 kernel which had most of the connectivity working
 and included MM support as well. I'll get back to you once the build is
 succesful again.

Thanks. I can probably spare a little bit of time if you need help
debugging those issues.

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: Panda, Android Bluetooth

2013-08-19 Thread Mike Turquette
On Sat, Aug 17, 2013 at 11:55 PM, Andy Green andy.gr...@linaro.org wrote:
 On 18 August 2013 14:41, Fathi Boudra fathi.bou...@linaro.org wrote:
 Hey Mike,

 On 17 August 2013 20:07, Mike Turquette mturque...@linaro.org wrote:
 On Thu, Aug 15, 2013 at 6:02 PM, Andy Green andy.gr...@linaro.org wrote:
 On 16 August 2013 08:22, Mike Turquette mturque...@linaro.org wrote:
 Hi all,

 I'm interested in looking at some Bluetooth stuff on my OMAP 4460
 Panda ES. Looking at the bug reports I don't see any Jelly Bean
 releases that have BT working properly on Panda. Is this correct?

 Can you please point me to a release where BT and display/hdmi are
 working for Panda? It's OK if it is ICS.

 I'm OK starting with binaries but I would much prefer to be able to
 build from source and reproduce any known-good bins. I have already
 built JB from the latest tip as well as the 13.07 manifest (display is
 working fine but BT doesn't work, bugs already filed). I tried the
 12.07 Panda LEB (which I think was the last ICS release?) but the
 binaries supplied did not have display working even after running the
 install-binaries-4.0.4.sh script.

 Nicolas Dechesne may be able to help more directly, but mainline BT
 was never workable reliably on Panda.

 That's disappointing since an article on omappedia references the
 Linaro release and says, Note: Wifi, bluetooth, YouTube, jpeg, video
 playback (both .mp4 and .3gp), and audio playback (both .mp3 and .aac)
 all have been verified as working in this release. You can see it
 here:

 http://www.omappedia.com/wiki/Android_Panda_Build_Source#Building_from_Linaro

 What about asking Linaro guys that actually produce this build?

 Looking at our test results, the bluetooth test failed in 12.07 release.
 A bug has been opened at that time:
 https://bugs.launchpad.net/linaro-android/+bug/987765

 Adding Vishal in CC, who's probably know the bluetooth status in
 Linaro Android builds better than me.

 Mike's saying even video didn't work when he tried that.

 Reading that bug it sounds like a firmware issue in the image.  I say
 in the bug it's working on kernel side at that time.

 However like the video problem, it sort of hinges on the meaning of working.

 HDMI and DVI on Panda have worked to some extent for a long while.
 But they've never worked properly dual-head and in fact because they
 share a PLL for the pixel clock, they'll never work outside of special
 conditions like same monitor and resolution.  Last I saw of it there's
 a behaviour in HDMI hotlug detect handling in the driver that means
 some monitors won't be seen as plugged, because they delay sending hpd
 by up to 1s (I have one of these monitors).  The code in the Panda
 release was forward-ported from 3.0 DSS stack on omapzoom (since
 that's the only thing TI had on offer with working Android SGX) and
 that deviates hugely from mainline DSS, so any improvements in this
 area didn't get transplanted.

 Bluetooth is similar on mainline basis, it was able to work for a
 while but when hammered it fell over.

Sounds like I'm out of luck for finding a build where things Just
Work. Thanks for the inputs everyone.

Regards,
Mike


 -Andy

 The p-android stuff on omapzoom was meant to have numerous patches
 that actually made it work.  At one point we talked to some guys from
 TI and got some patches, however they were patches against
 p-android-3.0 that not only did not apply on mainline but were 100%
 patching code that anyway did not exist in mainline, so we got
 literally nowhere with it.

 The p-android stuff are busy history trees, so it is very hard to
 extract a coherent series that fixes bluetooth.  Even to do direct
 diffs at file level isn't easy since the files have all moved around
 and the 3.0 one we know worked is radically different than current
 mainline anyway.  Some of the issues were down to PM related stuff and
 the p-android arrangements for that bear no relationship to mainline.

 Anyway Nicolas may know more, but the best bet may be to find a TI
 Alumni who worked on it and get the skinny.

 Nicolas, any inputs?

 Thanks,
 Mike


 -Andy

 Thanks,
 Mike

 Cheers,
 --
 Fathi Boudra
 Builds and Baselines Manager | Release Manager
 Linaro.org | Open source software for ARM SoCs

 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: Panda, Android Bluetooth

2013-08-17 Thread Mike Turquette
On Thu, Aug 15, 2013 at 6:02 PM, Andy Green andy.gr...@linaro.org wrote:
 On 16 August 2013 08:22, Mike Turquette mturque...@linaro.org wrote:
 Hi all,

 I'm interested in looking at some Bluetooth stuff on my OMAP 4460
 Panda ES. Looking at the bug reports I don't see any Jelly Bean
 releases that have BT working properly on Panda. Is this correct?

 Can you please point me to a release where BT and display/hdmi are
 working for Panda? It's OK if it is ICS.

 I'm OK starting with binaries but I would much prefer to be able to
 build from source and reproduce any known-good bins. I have already
 built JB from the latest tip as well as the 13.07 manifest (display is
 working fine but BT doesn't work, bugs already filed). I tried the
 12.07 Panda LEB (which I think was the last ICS release?) but the
 binaries supplied did not have display working even after running the
 install-binaries-4.0.4.sh script.

 Nicolas Dechesne may be able to help more directly, but mainline BT
 was never workable reliably on Panda.

That's disappointing since an article on omappedia references the
Linaro release and says, Note: Wifi, bluetooth, YouTube, jpeg, video
playback (both .mp4 and .3gp), and audio playback (both .mp3 and .aac)
all have been verified as working in this release. You can see it
here:

http://www.omappedia.com/wiki/Android_Panda_Build_Source#Building_from_Linaro


 The p-android stuff on omapzoom was meant to have numerous patches
 that actually made it work.  At one point we talked to some guys from
 TI and got some patches, however they were patches against
 p-android-3.0 that not only did not apply on mainline but were 100%
 patching code that anyway did not exist in mainline, so we got
 literally nowhere with it.

 The p-android stuff are busy history trees, so it is very hard to
 extract a coherent series that fixes bluetooth.  Even to do direct
 diffs at file level isn't easy since the files have all moved around
 and the 3.0 one we know worked is radically different than current
 mainline anyway.  Some of the issues were down to PM related stuff and
 the p-android arrangements for that bear no relationship to mainline.

 Anyway Nicolas may know more, but the best bet may be to find a TI
 Alumni who worked on it and get the skinny.

Nicolas, any inputs?

Thanks,
Mike


 -Andy

 Thanks,
 Mike

 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Panda, Android Bluetooth

2013-08-15 Thread Mike Turquette
Hi all,

I'm interested in looking at some Bluetooth stuff on my OMAP 4460
Panda ES. Looking at the bug reports I don't see any Jelly Bean
releases that have BT working properly on Panda. Is this correct?

Can you please point me to a release where BT and display/hdmi are
working for Panda? It's OK if it is ICS.

I'm OK starting with binaries but I would much prefer to be able to
build from source and reproduce any known-good bins. I have already
built JB from the latest tip as well as the 13.07 manifest (display is
working fine but BT doesn't work, bugs already filed). I tried the
12.07 Panda LEB (which I think was the last ICS release?) but the
binaries supplied did not have display working even after running the
install-binaries-4.0.4.sh script.

Thanks,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


automated testing at ARM Summit

2013-08-05 Thread Mike Turquette
Hi all,

There is currently a thread on LAKML that once again touches on the
issue of automated build/boot testing:
http://permalink.gmane.org/gmane.linux.ports.arm.kernel/257669

There seemed to be some good discussions between the LAVA team and
Kevin at LCE13 and I wanted to make others are aware of this thread
(and possibly of automated testing being a topic at the ARM Summit).

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


automated build coverage

2013-05-09 Thread Mike Turquette
Hi all,

I just wanted to forward this thread from LAKML to linaro-dev:
http://article.gmane.org/gmane.linux.ports.tegra/10683

Seems there is lots desire for an improvement to automated build
coverage and automated reporting along with it.

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH powerdebug] clock: show only active clocks

2013-05-06 Thread Mike Turquette
Quoting Sanjay Singh Rawat (2013-05-04 13:27:58)
 - use the clk_summary file of CCF for showing clocks
 - add option to show active or all clocks
 
 Signed-off-by: Sanjay Singh Rawat sanjay.ra...@linaro.org

clk_dump gives a JSON-formatted description of the clock tree, so it is
a bit more machine readable than clk_summary.  Also if you wanted to
actually represent a tree structure then clk_dump would be a better
starting point than using clk_summary, which does not include
parent-child relationship information.

Regards,
Mike

 ---
  clocks.c  |   62 
 +
  display.c |3 +++
  display.h |1 +
  3 files changed, 54 insertions(+), 12 deletions(-)
 
 diff --git a/clocks.c b/clocks.c
 index 95acf57..a0510b4 100644
 --- a/clocks.c
 +++ b/clocks.c
 @@ -287,9 +287,8 @@ static int clock_print_header(void)
 int ret;
  
 if(clock_fw == CCF) {
 -   if (asprintf(buf, %-35s %-10s %-12s %-10s %-11s %-15s %-14s 
 %-14s,
 -Name, Flags, Rate, Usecount, Children, 
 Prepare_Count,
 -Enable_Count, Notifier_Count)  0)
 +   if (asprintf(buf, %-30s %-10s %-12s %-10s (clock toggle 
 key-'c'),
 +Name, Enable_Count, Prepare_Count, Rate)  0)
 return -1;
 }
 else {
 @@ -297,23 +296,57 @@ static int clock_print_header(void)
  Name, Flags, Rate, Usecount, Children)  0)
 return -1;
 }
 -
 ret = display_column_name(buf);
 -
 free(buf);
  
 return ret;
  }
  
 +/*
 + * Display clocks by refering the clk_summary file of CCF
 + */
 +static int display_clk_summary()
 +{
 +FILE *fp;
 +char line[256];
 +int afterheader;
 +char clock[30];
 +int enable_cnt,prepare_cnt,rate;
 +
 +afterheader = 0;
 +fp = fopen(/sys/kernel/debug/clk/clk_summary,r);
 +if (fp == NULL) {
 +printf(error: failed to open clock tree file\n);
 +return -1;
 +}
 +
 +while (NULL != fgets(line,256,fp)) {
 +if (afterheader  1) {
 +sscanf(line,%s %d %d 
 %d,clock,enable_cnt,prepare_cnt,rate);
 +if (active_clks) {
 +   if (enable_cnt)
 +   display_print_line(CLOCK,afterheader,
 +   line,0,clock_tree);
 +   }
 +   else
 +   
 display_print_line(CLOCK,afterheader,line,1,clock_tree);
 +}
 +afterheader++;
 +}
 +   return 0;
 +}
 +
  static int clock_print_info(struct tree *tree)
  {
 int ret, line = 0;
  
 display_reset_cursor(CLOCK);
 -
 clock_print_header();
  
 -   ret = tree_for_each(tree, clock_print_info_cb, line);
 +   if (clock_fw == CCF)
 +   ret = display_clk_summary();
 +   else
 +   ret = tree_for_each(tree, clock_print_info_cb, line);
  
 display_refresh_pad(CLOCK);
  
 @@ -426,8 +459,10 @@ int clock_init(void)
  
 sprintf(clk_dir_path[CCF], %s/clk, clk_dir_path[CCF]);
 sprintf(clk_dir_path[OCF], %s/clock, clk_dir_path[OCF]);
 +
 if (!access(clk_dir_path[CCF], F_OK)) {
 clock_fw = CCF;
 +   active_clks = true;
 strcpy(clk_dir_path[MAX],clk_dir_path[CCF]);
 }
 else if(!access(clk_dir_path[OCF], F_OK)) {
 @@ -437,12 +472,15 @@ int clock_init(void)
 else
 return -1;
  
 -   clock_tree = tree_load(clk_dir_path[MAX], NULL, false);
 -   if (!clock_tree)
 -   return -1;
 +   /* Not preparing tree for CCF, will use the clk_summary file */
 +   if(clock_fw != CCF) {
 +   clock_tree = tree_load(clk_dir_path[MAX], NULL, false);
 +   if (!clock_tree)
 +   return -1;
  
 -   if (fill_clock_tree())
 -   return -1;
 +   if (fill_clock_tree())
 +   return -1;
 +   }
  
 return display_register(CLOCK, clock_ops);
  }
 diff --git a/display.c b/display.c
 index e9f4bf6..98544e6 100644
 --- a/display.c
 +++ b/display.c
 @@ -416,6 +416,9 @@ static int display_keystroke(int fd, void *data)
 case 'r':
 case 'R':
 return display_refresh(current_win, true);
 +   case 'c':
 +   active_clks = active_clks ? false : true;
 +   return display_refresh(current_win, true);
 default:
 return 0;
 }
 diff --git a/display.h b/display.h
 index 6362a48..24c9d59 100644
 --- a/display.h
 +++ b/display.h
 @@ -33,4 +33,5 @@ extern int display_init(int wdefault);
  extern int display_register(int win, struct display_ops *ops);
  extern int display_column_name(const char 

Re: [PATCH 1/1] clk: Add notifier support in clk_prepare/clk_unprepare

2013-03-28 Thread Mike Turquette
Quoting Colin Cross (2013-03-21 17:06:25)
 On Thu, Mar 21, 2013 at 3:36 PM, Mike Turquette mturque...@linaro.org wrote:
  To my knowledge, devfreq performs one task: implements an algorithm
  (typically one that loops/polls) and applies this heuristic towards a
  dvfs transition.
 
  It is a policy layer, a high level layer.  It should not be used as a
  lower-level mechanism.  Please correct me if my understanding is wrong.
 
  I think the very idea of the clk framework calling into devfreq is
  backwards.  Ideally a devfreq driver would call clk_set_rate as part of
  it's target callback.  This is analogous to a cpufreq .target callback
  which calls clk_set_rate and regulator_set_voltage.  Can you imagine the
  clock framework cross-calling into cpufreq when clk_set_rate is called?
  I think that would be strange.
 
  I think that all of this discussion highlights the fact that there is a
  missing piece of infrastructure.  It isn't devfreq or clock rate-change
  notifiers.  It is that there is not a dvfs mechanism which neatly builds
  on top of these lower-level frameworks (clocks  regulators).  Clearly
  some higher-level abstraction layer is needed.
 
 I went through all of this on Tegra2.  For a while I had a
 dvfs_set_rate api for drivers that needed to modify the voltage when
 they updated a clock, but I ended up dropping it.  Drivers rarely care
 about the voltage, all they want to do is set their clock rate.  The
 voltage necessary to support that clock is an implementation detail of
 the silicon that is irrelevant to the driver

Hi Colin,

I agree about voltage scaling being an implementation detail,  but I
think that drivers similarly do not care about enabling clocks, clock
domains, power domains, voltage domains, etc.  The just want to say
give me what I need to turn on and run, and I'm done with that stuff
now, lazily turn off if you want to.  Runtime pm gives drivers that
abstraction layer today.

There is a need for a similar abstraction layer for dvfs or, more
generically, an abstraction layer for performance.  It is true that a
driver doesn't care about scaling it's voltage, but it also might not
care that its functional clock is changing rate, or that memory needs to
run faster, or that an async bridge or interface clock needs to change
it's rate.

These are also implementation details that are common in dvfs
transitions, but the driver surely doesn't care about.  (note that
obviously some driver care specifically about clocks, such as multimedia
codecs)

 (I know TI liked to specify voltage/frequency combos for the blocks,
 but their chips still had to support running at a lower clock speed
 for the voltage than specified in the OPP because that case always
 occurs during a dvfs change).
 

I don't see the relevance to this discussion.

 For Tegra2, before clk_prepare/clk_unprepare existed, I hacked dvfs
 into the clk framework by using a mixture of mutex locked clocks and
 spinlock locked clocks.  The main issue is accidentally recursive
 locking the main clock locks when the call path is
 clk-dvfs-regulator set-i2c-clk.  I think if you could guarantee
 that clocks required for dvfs were always in the prepared state
 (maybe a flag on the clock, kind of like WQ_MEM_RECLAIM marks
 special workqueues, or just have the machine call clk_prepare), and
 that clk_prepare on an already-prepared clock avoided taking the mutex
 (atomic op fastpath plus mutex slow path?), then the existing
 notifiers would be perfect for dvfs.

The clk reentrancy patchset[1] solves the particular locking problem
you're referring to.

The bigger issue that worries me about using clock rate-change notifiers
to implement a dvfs transition is that the mechanism may not be powerful
enough, or may be very messy.

For instance consider OMAP's voltage domain dependencies.  A straight
forward example is running the MPU fast, which requires DDR to run fast.
So a call to clk_set_rate(cpu_clk) will shoot off PRE_RATE_CHANGE
notifiers that call clk_set_rate(ddr_clk).  Both of those calls to
clk_set_rate will also result in notifiers that each call
regulator_scale_voltage on their respective regulators.

Since there is no user tracking going on in the clock framework, all it
takes is any other actor in the system to call clk_set_rate(ddr_clk) and
overwrite what the mpu_clk did.  For instance a bluetooth file transfer
needs CORE to run fast for some 3Mbps transfer, and then ramps clock
rates back down (including the ddr_clk rate) after it completes, even
while the MPU is still running fast.  So now user requests have to be
tracked and compared to prevent that sort of thing from happening.
Should all of that user-tracking stuff end up in the clock framework?
I'm not so sure.

Anyways I'm still looking at the voltage scaling via notifiers thing and
trying to understand the limits of that design choice before everyone
converts over to it and there is no turning back.

Regards,
Mike

[1] http://article.gmane.org

Re: [PATCH 1/5] clk: allow reentrant calls into the clk framework

2013-03-27 Thread Mike Turquette
Quoting Bill Huang (2013-03-26 20:33:31)
 On Thu, 2013-02-28 at 12:49 +0800, Mike Turquette wrote:
  Reentrancy into the clock framework from the clk.h api is highly
  desirable.  This feature is necessary for clocks that are prepared and
  unprepared via i2c_transfer (which includes many PMICs and discrete
  audio chips) and it is also necessary for performing dynamic voltage 
  frequency scaling via clock rate-change notifiers.
  
  This patch implements reentrancy by adding a global atomic_t which
  tracks the context of the current caller.  Context in this case is the
  return value from get_current().  The clk.h api implementations are
  modified to first see if the relevant global lock is already held and if
  so compare the global context (set by whoever is holding the lock)
  against their own context (via a call to get_current()).  If the two
  match then this function is a nested call from the one already holding
  the lock and we procede.  If the context does not match then procede to
  call mutex_lock and busy-wait for the existing task to complete.
  
  Thus this patch set does not increase concurrency for unrelated calls
  into the clock framework.  Instead it simply allows reentrancy by the
  single task which is currently holding the global clock framework lock.
  
  Thanks to Rajagoapl Venkat for the original idea to use get_current()
  and to David Brown for the suggestion to replace my previous rwlock
  scheme with atomic operations during code review at ELC 2013.
  
  Signed-off-by: Mike Turquette mturque...@linaro.org
  Cc: Rajagopal Venkat rajagopal.ven...@linaro.org
  Cc: David Brown dav...@codeaurora.org
  ---
 Hi Mike,
 
 Will this single patch be accepted? I guess you might not merge the
 whole series but I think this one is useful, is it possible that you can
 send out this single patch (or just merge this one) as an improvement of
 CCF? Or you think otherwise?
 

Bill,

Yes, I plan to merge this single patch for 3.10 and have posted a new
version fixing the issue pointed out by Ulf.  Please leave any review
comments you have.

Thanks,
Mike

 Thanks,
 Bill

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [RFC 1/1] clk: Add notifier support in clk_prepare_enable/clk_disable_unprepare

2013-03-21 Thread Mike Turquette
Quoting Ulf Hansson (2013-03-18 03:36:29)
 On 15 March 2013 20:38, Stephen Warren swar...@wwwdotorg.org wrote:
  On 03/15/2013 06:33 AM, Ulf Hansson wrote:
  On 15 March 2013 13:06, Bill Huang bilhu...@nvidia.com wrote:
  On Fri, 2013-03-15 at 18:08 +0800, Ulf Hansson wrote:
  ...
  Some prerequisites; I think am in favor of using the clk API to
  trigger DVFS changes and then I agree on that clk_prepare|unprepare
  needs to be possible to track from a DVFS perspective. clk_set_rate is
  not enough.
 
  So if we decide to do the above (using the clk API to trigger DVFS
  changes), I believe we should discuss two possible solutions;
  - clk notifiers or..
  - dvfs clock type.
 
  I am trying to make up my mind of what I think is the best solution.
  Have you considered dvfs clock type?
  I put some comments about this for [PATCH 2/5] clk: notifier handler
  for dynamic voltage scaling recently as well.
 
  What could the advantages/disadvantages be between the two options?
 
  I personally prefer clk notifiers since that's easy and all the existing
  device drivers don't need to be modified, a new clock or API might be
  more thoroughly considered (and hence maybe more graceful) but that
  means we need more time to cook and many drivers need to plug into that
  API when it comes out, a lot of test/verification or maybe chaos
  follows, I'm not sure will that be a little overkill.
 
  I guess you did not fully got what I meant with dvfs clock type. It
  will not affect the clock API. But instead the dvfs is handled by
  implementing a specific clk hw type. So the same thing is accomplished
  as with clk notifiers, no changes should be needed to device drivers.
 
  The difference is only that no notifiers will be needed, and all the
  dvfs stuff will be handled in the clk hw instead. It will mean that we
  will bundle dvfs stuff into the clock drivers, instead of separating
  the code outside the clock drivers. But, on the other hand no
  notifiers will be needed.
 
  The advantage here is that I assume that a notifier would continually
  have to check whether the clock being modified was one that the DVFS
  notifier cared about. By integrating the CVFS logic into the clk_hw
  itself, it'll only ever get executed for clocks that really care about
  DVFS. Presumably, the code that implements the clk_hw could also use
  some common DVFS library as part of the implementation, and still share
  code. Or perhaps, what about putting DVFS ops into a clk_hw alongside
  any other existing ops, and having the clock core call them whenever
  appropriate?
 
 Thanks for your comment Stephen.
 
 I agree to your reflections as well. It will probably be a more
 optimized solution going this direction and we don't have to add more
 clk notifier code to the clk API, which I guess is good.
 It would be interesting to get some input from some of the maintainers
 to this discussion as well, let's see.
 

I do not like the dvfs clock type at all.  For the set of DVFS problems
that we are trying to solve, voltage scaling is more of a function of a
device's requirements than of a clock.  Put another way, we don't scale
voltage because a clock runs at a rate, we scale voltage because a
device runs at a rate.  That is why the clock rate change notifiers were
interesting for dvfs: the device scales the voltage in response to a
clock frequency change.

However it seems the rate-change notifiers are a bit messy for dvfs.

As such I'm currently hacking on a new rfc to introduce a separate dvfs
api.  Based on recent discussions and some face-to-face feedback I think
that kicking off DVFS transitions from the clock framework (which looks
very enticing at first glance) is coming at the problem from the wrong
direction.  A new api that builds on top of clocks, regulators and opps
is straight-forward, requires no weird cross-layer calls and is
generally cleaner.  The downside is that driver authors will have to
choose between using clk_set_rate or magic_dvfs_set_rate apis.  That
dilemma is entirely analogous to the runtime pm versus
clk_enable/clk_disable dilemma and hopefully won't be a big hurdle to
acceptance.

I'll post in the v2 thread as well, specifically addressing the
devfreq/clk_set_rate idea.

Regards,
Mike

 Kind regards
 Ulf Hansson
 
 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 1/1] clk: Add notifier support in clk_prepare/clk_unprepare

2013-03-21 Thread Mike Turquette
Quoting Ulf Hansson (2013-03-20 14:06:14)
 On 20 March 2013 15:47, Mike Turquette mturque...@linaro.org wrote:
  Quoting Bill Huang (2013-03-19 21:39:44)
  On Wed, 2013-03-20 at 11:31 +0800, Mike Turquette wrote:
   Quoting Bill Huang (2013-03-19 19:55:49)
On Wed, 2013-03-20 at 01:01 +0800, Mike Turquette wrote:
 Quoting Bill Huang (2013-03-19 06:28:32)
  Add notifier calls in clk_prepare and clk_unprepare so drivers 
  which are
  interested in knowing that clk_prepare/unprepare call can act 
  accordingly.
 
  The existing clk_set_rate notifier is not enough for normal DVFS
  inplementation since clock might be enabled/disabled at runtime. 
  Adding
  these notifiers is useful on DVFS core which take clk_prepare as a 
  hint
  on that the notified clock might be enabled later so it can raise 
  voltage
  to a safe level before enabling the clock, and take clk_unprepare 
  as a
  hint that the clock has been disabled and is safe to lower the 
  voltage.
 
  The added notifier events are:
 
  PRE_CLK_PREPARE
  POST_CLK_PREPARE
  ABORT_CLK_PREPARE
  PRE_CLK_UNPREPARE
  POST_CLK_UNPREPARE
 
  Signed-off-by: Bill Huang bilhu...@nvidia.com

 I'm still not sure about this approach.  Based on feedback I got from
 Linaro Connect I am not convinced that scaling voltage through clk
 rate-change notifiers is the right way to go.  As I understand it 
 this
 patch only exists for that single purpose, so if the voltage-notifier
 idea gets dropped then I will not take this patch in.

Thanks Mike, actually we won't use your clk: notifier handler for
dynamic voltage scaling patch instead we are trying to port our DVFS
into Non-CPU DVFS framework devfreq which will need to hook those
notifiers, without the clock notifiers been extended the framework is
useless for us since we cannot do polling due to the fact that polling
is not in real time. If it ended up extending the notifiers cannot
happen then the only choice for us I think would be giving up devfreq
and implement them in Tegra's clk_hw.
  
   I'm familiar with the devfreq framework.  Can you explain further how
   you plan to use devfreq with the clock notifiers?  What does the call
   graph look like?
  
  The call graph will look like this, when any DVFS interested clock rate
  changes (including enable and disable) happen - Tegra devfreq clock
  notifier is called - call into update_devfreq if needed - in
  update_devfreq it will call into .get_target_freq in Tegra
  devfreq_governor - and then call into .target of tegra
  devfreq_dev_profile to set voltage and done. More details are as below.
 
  We'll create devfreq driver for Tegra VDD_CORE rail, and the safe
  voltage level of the rail is determined by tens of clocks (2d, 3d,
  mpe,...), all the frequency ladders of those clocks are defined in DT
  also the operating points for VDD_CORE is declared in DT where its
  frequency will be more of a virtual clock or index.
 
  operating-points = 
  /* virtual-kHz  uV */
  0   95
  1   100
  2   105
  3   110
  4   115
  5   120
  6   125
  7   130
  8   135
 
  Register a Tegra governor where the callback .get_target_freq is the
  function to determine the overall frequency it can go to, and
  the .target callback in devfreq_dev_profile will be the function
  really do the voltage scaling.
 
  Tegra devfreq driver will register clock notifiers on all its interested
  clock and hence when any of those clock rate changes, disabled, enabled,
  we'll specifically call update_devfreq in the notifier.
 
  Thank you for the explanation.  Do you plan to use actual devfreq
  governors (like simple-ondemand, or something custom) for changing OPPs,
  or do you just plan to use the clock framework as a trigger for DVFS?
 
  Regards,
  Mike
 
 At a recent discussion regarding a previous version of this patch
 [RFC 1/1] clk: Add notifier support in
 clk_prepare_enable/clk_disable_unprepare, we also discussed
 whether to use clk notifiers or to use a clk hw to implement DVFS.
 
 Stephen Warren an myself, kind of pointed out that there could be
 benefits of not using notifers. I would just like to add that to this
 discussion as well.
 
 The idea in principle, could be as an option to Bill's idea, using
 devfreq with notifiers, to implement a clk hw which possibly makes use
 of the opp libary and do implements the DVFS functionallity that is
 needed for each SoC.
 

To my knowledge, devfreq performs one task: implements an algorithm
(typically one that loops/polls) and applies this heuristic towards a
dvfs transition.

It is a policy layer, a high level layer.  It should not be used as a
lower-level mechanism.  Please correct me if my understanding

Re: [PATCH 1/1] clk: Add notifier support in clk_prepare/clk_unprepare

2013-03-20 Thread Mike Turquette
Quoting Bill Huang (2013-03-19 21:39:44)
 On Wed, 2013-03-20 at 11:31 +0800, Mike Turquette wrote:
  Quoting Bill Huang (2013-03-19 19:55:49)
   On Wed, 2013-03-20 at 01:01 +0800, Mike Turquette wrote:
Quoting Bill Huang (2013-03-19 06:28:32)
 Add notifier calls in clk_prepare and clk_unprepare so drivers which 
 are
 interested in knowing that clk_prepare/unprepare call can act 
 accordingly.
 
 The existing clk_set_rate notifier is not enough for normal DVFS
 inplementation since clock might be enabled/disabled at runtime. 
 Adding
 these notifiers is useful on DVFS core which take clk_prepare as a 
 hint
 on that the notified clock might be enabled later so it can raise 
 voltage
 to a safe level before enabling the clock, and take clk_unprepare as a
 hint that the clock has been disabled and is safe to lower the 
 voltage.
 
 The added notifier events are:
 
 PRE_CLK_PREPARE
 POST_CLK_PREPARE
 ABORT_CLK_PREPARE
 PRE_CLK_UNPREPARE
 POST_CLK_UNPREPARE
 
 Signed-off-by: Bill Huang bilhu...@nvidia.com

I'm still not sure about this approach.  Based on feedback I got from
Linaro Connect I am not convinced that scaling voltage through clk
rate-change notifiers is the right way to go.  As I understand it this
patch only exists for that single purpose, so if the voltage-notifier
idea gets dropped then I will not take this patch in.

   Thanks Mike, actually we won't use your clk: notifier handler for
   dynamic voltage scaling patch instead we are trying to port our DVFS
   into Non-CPU DVFS framework devfreq which will need to hook those
   notifiers, without the clock notifiers been extended the framework is
   useless for us since we cannot do polling due to the fact that polling
   is not in real time. If it ended up extending the notifiers cannot
   happen then the only choice for us I think would be giving up devfreq
   and implement them in Tegra's clk_hw.
  
  I'm familiar with the devfreq framework.  Can you explain further how
  you plan to use devfreq with the clock notifiers?  What does the call
  graph look like?
  
 The call graph will look like this, when any DVFS interested clock rate
 changes (including enable and disable) happen - Tegra devfreq clock
 notifier is called - call into update_devfreq if needed - in
 update_devfreq it will call into .get_target_freq in Tegra
 devfreq_governor - and then call into .target of tegra
 devfreq_dev_profile to set voltage and done. More details are as below.
 
 We'll create devfreq driver for Tegra VDD_CORE rail, and the safe
 voltage level of the rail is determined by tens of clocks (2d, 3d,
 mpe,...), all the frequency ladders of those clocks are defined in DT
 also the operating points for VDD_CORE is declared in DT where its
 frequency will be more of a virtual clock or index.
 
 operating-points = 
 /* virtual-kHz  uV */
 0   95
 1   100
 2   105
 3   110
 4   115
 5   120
 6   125
 7   130
 8   135
 
 Register a Tegra governor where the callback .get_target_freq is the
 function to determine the overall frequency it can go to, and
 the .target callback in devfreq_dev_profile will be the function
 really do the voltage scaling.
 
 Tegra devfreq driver will register clock notifiers on all its interested
 clock and hence when any of those clock rate changes, disabled, enabled,
 we'll specifically call update_devfreq in the notifier.

Thank you for the explanation.  Do you plan to use actual devfreq
governors (like simple-ondemand, or something custom) for changing OPPs,
or do you just plan to use the clock framework as a trigger for DVFS?

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 1/1] clk: Add notifier support in clk_prepare/clk_unprepare

2013-03-19 Thread Mike Turquette
Quoting Bill Huang (2013-03-19 06:28:32)
 Add notifier calls in clk_prepare and clk_unprepare so drivers which are
 interested in knowing that clk_prepare/unprepare call can act accordingly.
 
 The existing clk_set_rate notifier is not enough for normal DVFS
 inplementation since clock might be enabled/disabled at runtime. Adding
 these notifiers is useful on DVFS core which take clk_prepare as a hint
 on that the notified clock might be enabled later so it can raise voltage
 to a safe level before enabling the clock, and take clk_unprepare as a
 hint that the clock has been disabled and is safe to lower the voltage.
 
 The added notifier events are:
 
 PRE_CLK_PREPARE
 POST_CLK_PREPARE
 ABORT_CLK_PREPARE
 PRE_CLK_UNPREPARE
 POST_CLK_UNPREPARE
 
 Signed-off-by: Bill Huang bilhu...@nvidia.com

Is this a resend or a new version?  It would be nice to put RESEND in
the patch $SUBJECT or put a changelog from previous patches under the
--- below.

I'm still not sure about this approach.  Based on feedback I got from
Linaro Connect I am not convinced that scaling voltage through clk
rate-change notifiers is the right way to go.  As I understand it this
patch only exists for that single purpose, so if the voltage-notifier
idea gets dropped then I will not take this patch in.

Regards,
Mike

 ---
  drivers/clk/clk.c   |   88 
 ++-
  include/linux/clk.h |5 +++
  2 files changed, 57 insertions(+), 36 deletions(-)
 
 diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
 index ed87b24..ac07c6e 100644
 --- a/drivers/clk/clk.c
 +++ b/drivers/clk/clk.c
 @@ -516,6 +516,42 @@ struct clk *__clk_lookup(const char *name)
  
  /***clk api***/
  
 +/**
 + * __clk_notify - call clk notifier chain
 + * @clk: struct clk * that is changing rate
 + * @msg: clk notifier type (see include/linux/clk.h)
 + * @old_rate: old clk rate
 + * @new_rate: new clk rate
 + *
 + * Triggers a notifier call chain on the clk rate-change notification
 + * for 'clk'.  Passes a pointer to the struct clk and the previous
 + * and current rates to the notifier callback.  Intended to be called by
 + * internal clock code only.  Returns NOTIFY_DONE from the last driver
 + * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
 + * a driver returns that.
 + */
 +static int __clk_notify(struct clk *clk, unsigned long msg,
 +   unsigned long old_rate, unsigned long new_rate)
 +{
 +   struct clk_notifier *cn;
 +   struct clk_notifier_data cnd;
 +   int ret = NOTIFY_DONE;
 +
 +   cnd.clk = clk;
 +   cnd.old_rate = old_rate;
 +   cnd.new_rate = new_rate;
 +
 +   list_for_each_entry(cn, clk_notifier_list, node) {
 +   if (cn-clk == clk) {
 +   ret = srcu_notifier_call_chain(cn-notifier_head, 
 msg,
 +   cnd);
 +   break;
 +   }
 +   }
 +
 +   return ret;
 +}
 +
  void __clk_unprepare(struct clk *clk)
  {
 if (!clk)
 @@ -549,7 +585,14 @@ void __clk_unprepare(struct clk *clk)
  void clk_unprepare(struct clk *clk)
  {
 mutex_lock(prepare_lock);
 +
 +   if (clk-notifier_count)
 +   __clk_notify(clk, PRE_CLK_UNPREPARE, clk-rate, clk-rate);
 +
 __clk_unprepare(clk);
 +   if (clk-notifier_count)
 +   __clk_notify(clk, POST_CLK_UNPREPARE, clk-rate, clk-rate);
 +
 mutex_unlock(prepare_lock);
  }
  EXPORT_SYMBOL_GPL(clk_unprepare);
 @@ -597,7 +640,16 @@ int clk_prepare(struct clk *clk)
 int ret;
  
 mutex_lock(prepare_lock);
 +
 +   if (clk-notifier_count)
 +   __clk_notify(clk, PRE_CLK_PREPARE, clk-rate, clk-rate);
 +
 ret = __clk_prepare(clk);
 +   if (!ret  clk-notifier_count)
 +   __clk_notify(clk, POST_CLK_PREPARE, clk-rate, clk-rate);
 +   else if (clk-notifier_count)
 +   __clk_notify(clk, ABORT_CLK_PREPARE, clk-rate, clk-rate);
 +
 mutex_unlock(prepare_lock);
  
 return ret;
 @@ -749,42 +801,6 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
  EXPORT_SYMBOL_GPL(clk_round_rate);
  
  /**
 - * __clk_notify - call clk notifier chain
 - * @clk: struct clk * that is changing rate
 - * @msg: clk notifier type (see include/linux/clk.h)
 - * @old_rate: old clk rate
 - * @new_rate: new clk rate
 - *
 - * Triggers a notifier call chain on the clk rate-change notification
 - * for 'clk'.  Passes a pointer to the struct clk and the previous
 - * and current rates to the notifier callback.  Intended to be called by
 - * internal clock code only.  Returns NOTIFY_DONE from the last driver
 - * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
 - * a driver returns that.
 - */
 -static int __clk_notify(struct clk *clk, unsigned long msg,
 -   unsigned long old_rate, unsigned long new_rate)
 -{
 -   struct clk_notifier *cn;
 -   struct clk_notifier_data cnd;
 

Re: [PATCH 1/1] clk: Add notifier support in clk_prepare/clk_unprepare

2013-03-19 Thread Mike Turquette
Quoting Bill Huang (2013-03-19 19:55:49)
 On Wed, 2013-03-20 at 01:01 +0800, Mike Turquette wrote:
  Quoting Bill Huang (2013-03-19 06:28:32)
   Add notifier calls in clk_prepare and clk_unprepare so drivers which are
   interested in knowing that clk_prepare/unprepare call can act accordingly.
   
   The existing clk_set_rate notifier is not enough for normal DVFS
   inplementation since clock might be enabled/disabled at runtime. Adding
   these notifiers is useful on DVFS core which take clk_prepare as a hint
   on that the notified clock might be enabled later so it can raise voltage
   to a safe level before enabling the clock, and take clk_unprepare as a
   hint that the clock has been disabled and is safe to lower the voltage.
   
   The added notifier events are:
   
   PRE_CLK_PREPARE
   POST_CLK_PREPARE
   ABORT_CLK_PREPARE
   PRE_CLK_UNPREPARE
   POST_CLK_UNPREPARE
   
   Signed-off-by: Bill Huang bilhu...@nvidia.com
  
  I'm still not sure about this approach.  Based on feedback I got from
  Linaro Connect I am not convinced that scaling voltage through clk
  rate-change notifiers is the right way to go.  As I understand it this
  patch only exists for that single purpose, so if the voltage-notifier
  idea gets dropped then I will not take this patch in.
  
 Thanks Mike, actually we won't use your clk: notifier handler for
 dynamic voltage scaling patch instead we are trying to port our DVFS
 into Non-CPU DVFS framework devfreq which will need to hook those
 notifiers, without the clock notifiers been extended the framework is
 useless for us since we cannot do polling due to the fact that polling
 is not in real time. If it ended up extending the notifiers cannot
 happen then the only choice for us I think would be giving up devfreq
 and implement them in Tegra's clk_hw.

I'm familiar with the devfreq framework.  Can you explain further how
you plan to use devfreq with the clock notifiers?  What does the call
graph look like?

Thanks,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 1/5] clk: allow reentrant calls into the clk framework

2013-03-18 Thread Mike Turquette
Quoting Ulf Hansson (2013-02-28 01:54:34)
 On 28 February 2013 05:49, Mike Turquette mturque...@linaro.org wrote:
  @@ -703,10 +744,29 @@ int clk_enable(struct clk *clk)
  unsigned long flags;
  int ret;
 
  +   /* this call re-enters if it is from the same context */
  +   if (spin_is_locked(enable_lock) || mutex_is_locked(prepare_lock)) 
  {
  +   if ((void *) atomic_read(context) == get_current()) {
  +   ret = __clk_enable(clk);
  +   goto out;
  +   }
  +   }
 
 I beleive the clk_enable|disable code will be racy. What do you think
 about this scenario:
 
 1. Thread 1, calls clk_prepare - clk is not reentrant - mutex_lock
 - set_context to thread1.
 2. Thread 2, calls clk_enable - above if will mean that get_current
 returns thread 1 context and then clk_enable continues -
 spin_lock_irqsave - set_context to thread 2.
 3. Thread 1 continues and triggers a reentancy for clk_prepare - clk
 is not reentrant (since thread 2 has set a new context) - mutex_lock
 and we will hang forever.
 
 Do you think above scenario could happen?
 
 I think the solution would be to invent another static atomic_t
 context; which is used only for fast path functions
 (clk_enable|disable). That should do the trick I think.

Ulf,

You are correct.  In fact I have a branch that has two separate context
pointers, one for mutex-protected functions and one for
spinlock-protected functions.  Somehow I managed to discard that change
before settling on the final version that was published.

I'll add the change back in.

Thanks for the review,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 1/5] clk: allow reentrant calls into the clk framework

2013-03-18 Thread Mike Turquette
Quoting Russell King - ARM Linux (2013-03-18 14:00:11)
 On Mon, Mar 18, 2013 at 01:15:51PM -0700, Mike Turquette wrote:
  Quoting Ulf Hansson (2013-02-28 01:54:34)
   On 28 February 2013 05:49, Mike Turquette mturque...@linaro.org wrote:
@@ -703,10 +744,29 @@ int clk_enable(struct clk *clk)
unsigned long flags;
int ret;
   
+   /* this call re-enters if it is from the same context */
+   if (spin_is_locked(enable_lock) || 
mutex_is_locked(prepare_lock)) {
+   if ((void *) atomic_read(context) == get_current()) {
+   ret = __clk_enable(clk);
+   goto out;
+   }
+   }
   
   I beleive the clk_enable|disable code will be racy. What do you think
   about this scenario:
   
   1. Thread 1, calls clk_prepare - clk is not reentrant - mutex_lock
   - set_context to thread1.
   2. Thread 2, calls clk_enable - above if will mean that get_current
   returns thread 1 context and then clk_enable continues -
   spin_lock_irqsave - set_context to thread 2.
   3. Thread 1 continues and triggers a reentancy for clk_prepare - clk
   is not reentrant (since thread 2 has set a new context) - mutex_lock
   and we will hang forever.
   
   Do you think above scenario could happen?
   
   I think the solution would be to invent another static atomic_t
   context; which is used only for fast path functions
   (clk_enable|disable). That should do the trick I think.
  
  Ulf,
  
  You are correct.  In fact I have a branch that has two separate context
  pointers, one for mutex-protected functions and one for
  spinlock-protected functions.  Somehow I managed to discard that change
  before settling on the final version that was published.
 
 Err.
 
 Do not forget one very important point.
 
 Any clock which has clk_enable() called on it must have had clk_prepare()
 already called _and_ completed.  A second clk_prepare() call on the same
 clock should be a no-op other than to increase the prepare reference count
 on it.
 
 If you do anything else, you are going to get into sticky problems.

Correct usage of the api is of course still necessary.  The reentrancy
patch doesn't change api usage by drivers and does not violate the
sequencing of clk_prepare/clk_enable and clk_disable/clk_unprepare.  In
Ulf's example thread 2 should have already called clk_prepare before
calling clk_enable.

Ulf has correctly pointed out a bug in the locking/context logic due to
having two distinct lock's for fast/slow operations.  It will be fixed
in the next verison.

Thanks,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: LCA13: Video: Scheduler Internals by: Vincent Guittot

2013-03-17 Thread Mike Turquette
Quoting Amit Kucheria (2013-03-10 21:13:34)
 On Sun, Mar 10, 2013 at 8:38 AM, Viresh Kumar viresh.ku...@linaro.org wrote:
  Hi Guys,
 
  Below are hangout upstreams of Scheduler Internals by Vincent Guittot
  done in LCA13.
 
  We have got another version of this recording that is done by some
  other cameras, but
  its size was 30 GB and so hard to upstream. In case you need that
  please contact me.
 
 'Hard to upstream' - I like our razor-sharp focus on upstreaming :)
 
  Day 1: http://www.youtube.com/watch?v=2yzelou80JE
  Day 2: http://www.youtube.com/watch?v=fN11Lltx1nQ
 
  Thanks to Naresh for arranging for hangouts.
 
 
 Yes, thanks to Naresh and Viresh for getting this all recorded. And a
 big thanks to Vincent was taking the time to walk the team through the
 scheduler.
 

Thanks again to everyone for the scheduler talk.  I learned a lot and it
is a great way to jump-start into the scheduling domain (pun intended).

Mike

 /Amit
 
 ___
 linaro-kernel mailing list
 linaro-ker...@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-kernel

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 2/5] clk: notifier handler for dynamic voltage scaling

2013-03-03 Thread Mike Turquette
Quoting Richard Zhao (2013-03-02 00:22:19)
 On Fri, Mar 01, 2013 at 06:55:54PM -0800, Bill Huang wrote:
  On Sat, 2013-03-02 at 04:48 +0800, Mike Turquette wrote:
   Quoting Mike Turquette (2013-03-01 10:22:34)
Quoting Bill Huang (2013-03-01 01:41:31)
 On Thu, 2013-02-28 at 12:49 +0800, Mike Turquette wrote:
  Dynamic voltage and frequency scaling (dvfs) is a common power 
  saving
  technique in many of today's modern processors.  This patch 
  introduces a
  common clk rate-change notifier handler which scales voltage
  appropriately whenever clk_set_rate is called on an affected clock.
 
 I really think clk_enable and clk_disable should also be triggering
 notifier call and DVFS should act accordingly since there are cases
 drivers won't set clock rate but instead disable its clock directly, 
 do
 you agree?
  

Hi Bill,

I'll think about this.  Perhaps a better solution would be to adapt
these drivers to runtime PM.  Then a call to runtime_pm_put() would
result in a call to clk_disable(...) and regulator_set_voltage(...).

There is no performance-based equivalent to runtime PM, which is one
reason why clk_set_rate is a likely entry point into dvfs.  But for
operations that have nice api's like runtime PM it would be better to
use those interfaces and not overload the clk.h api unnecessarily.

   
   Bill,
   
   I wasn't thinking at all when I wrote this.  Trying to rush to the
   airport I guess...
   
   clk_enable() and clk_disable() must not sleep and all operations are
   done under a spinlock.  So this rules out most use of notifiers.  It is
   expected for some drivers to very aggressively enable/disable clocks in
   interrupt handlers so scaling voltage as a function of clk_{en|dis}able
   calls is also likely out of the question.
  
  Yeah for those existing drivers to call enable/disable clocks in
  interrupt have ruled out this, I didn't think through when I was asking.
   
   Some platforms have chosen to implement voltage scaling in their
   .prepare callbacks.  I personally do not like this and still prefer
   drivers be adapted to runtime pm and let those callbacks handle voltage
   scaling along with clock handling.
 Voltage scaling in clock notifiers seems similar. Clock and regulater
 embedded code into each other will cause things complicated.

Hi Richard,

Sorry, I do not follow the above statement.  Can you clarify what you
mean?

  
  I think different SoC have different mechanisms or constraints on doing
  their DVFS, such as Tegra VDD_CORE rail, it supplies power to many
  devices and as a consequence each device do not have their own power
  rail to control, instead a central driver to handle/control this power
  rail is needed (to set voltage at the maximum of the requested voltage
  from all its sub-devices), so I'm wondering even if every drivers are
  doing DVFS through runtime pm, we're still having hole on knowing
  whether or not clocks of the interested devices are enabled/disabled at
  runtime, I'm not familiar with runtime pm and hence do not know if there
  is a mechanism to handle this, I'll study a bit. Thanks.
   
   Regards,
   Mike
   
  There are three prerequisites to using this feature:
  
  1) the affected clocks must be using the common clk framework
  2) voltage must be scaled using the regulator framework
  3) clock frequency and regulator voltage values must be paired via 
  the
  OPP library
 
 Just a note, Tegra Core won't meet prerequisite #3 since each 
 regulator
 voltage values is associated with clocks driving those many sub-HW
 blocks in it.

This patch isn't the one and only way to perform dvfs.  It is just a
helper function for registering notifier handlers for systems that meet
the above three requirements.  Even if you do not use the OPP library
there is no reason why you could not register your own rate-change
notifier handler to implement dvfs using whatever lookup-table you use
today.

And patches are welcome to extend the usefulness of this helper.  I'd
like as many people to benefit from this mechanism as possible.
  
  The extension is not so easy for us though since OPP library is assuming
  each device has a 1-1 mapping on its operating frequency and voltage.
 Is there someone working on OPP clock/regulator sets support?
 

No, but I'm going to bring this up at LCA on Wednesday.  It would be
nice to have some DT bindings for declaring operating points that tie
clocks  regulators together.

Regards,
Mike

 Thanks
 Richard

At some point we should think hard about DT bindings for these operating
points...

Regards,
Mike
  
  
  
  ___
  linux-arm-kernel mailing list
  linux-arm-ker...@lists.infradead.org
  http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH 2/5] clk: notifier handler for dynamic voltage scaling

2013-03-03 Thread Mike Turquette
Quoting Richard Zhao (2013-03-03 05:27:52)
 Hi Mike,
 
 On Sun, Mar 03, 2013 at 02:54:24AM -0800, Mike Turquette wrote:
  Quoting Richard Zhao (2013-03-02 00:22:19)
   On Fri, Mar 01, 2013 at 06:55:54PM -0800, Bill Huang wrote:
On Sat, 2013-03-02 at 04:48 +0800, Mike Turquette wrote:
 Quoting Mike Turquette (2013-03-01 10:22:34)
  Quoting Bill Huang (2013-03-01 01:41:31)
   On Thu, 2013-02-28 at 12:49 +0800, Mike Turquette wrote:
Dynamic voltage and frequency scaling (dvfs) is a common power 
saving
technique in many of today's modern processors.  This patch 
introduces a
common clk rate-change notifier handler which scales voltage
appropriately whenever clk_set_rate is called on an affected 
clock.
   
   I really think clk_enable and clk_disable should also be 
   triggering
   notifier call and DVFS should act accordingly since there are 
   cases
   drivers won't set clock rate but instead disable its clock 
   directly, do
   you agree?

  
  Hi Bill,
  
  I'll think about this.  Perhaps a better solution would be to adapt
  these drivers to runtime PM.  Then a call to runtime_pm_put() would
  result in a call to clk_disable(...) and regulator_set_voltage(...).
  
  There is no performance-based equivalent to runtime PM, which is one
  reason why clk_set_rate is a likely entry point into dvfs.  But for
  operations that have nice api's like runtime PM it would be better 
  to
  use those interfaces and not overload the clk.h api unnecessarily.
  
 
 Bill,
 
 I wasn't thinking at all when I wrote this.  Trying to rush to the
 airport I guess...
 
 clk_enable() and clk_disable() must not sleep and all operations are
 done under a spinlock.  So this rules out most use of notifiers.  It 
 is
 expected for some drivers to very aggressively enable/disable clocks 
 in
 interrupt handlers so scaling voltage as a function of 
 clk_{en|dis}able
 calls is also likely out of the question.

Yeah for those existing drivers to call enable/disable clocks in
interrupt have ruled out this, I didn't think through when I was asking.
 
 Some platforms have chosen to implement voltage scaling in their
 .prepare callbacks.  I personally do not like this and still prefer
 drivers be adapted to runtime pm and let those callbacks handle 
 voltage
 scaling along with clock handling.
   Voltage scaling in clock notifiers seems similar. Clock and regulater
   embedded code into each other will cause things complicated.
  
  Hi Richard,
  
  Sorry, I do not follow the above statement.  Can you clarify what you
  mean?
 As we have agreement that a operating point may have multiple clocks
 and regulators, this patch is impossible to support multi clocks. And
 it might mislead dvfs implementer to use clock notifier. It may be good
 to have unified api like dvfs_set_opp(opp), or drivers can handle clocks
 and regulators theirselves which is more flexible. What do you think?
 

Yes, there is a long-standing question whether clk_set_rate is
sufficient to cover dvfs needs or if a new api is required.  There are
many possible solutions.

One solution is to use clk_set_rate and use the rate-change notifiers to
call clk_set_rate on the other required clocks.  This is graceful from
the perspective of the driver since the driver author only has to think
about directly managing the clock(s) for that device and the rest is
managed automagically.  It is more complicated for the platform
integrator that must make sure the automagical stuff is set up
correctly.  This might be considered a more distributed approach.

Another solution would be a new api which calls clk_set_rate
individually on the affected clocks (e.g. a functional clk, an async
bridge child clock, and some other related non-child clock).  This is
less complicated for the platform integrator and represents a more
centralized approach.  It is less graceful for the device driver
author who must learn a new api and decide whether to call the new api
or to call clk_set_rate.

A hybrid solution might be to set a flag on a clock (e.g.
CLK_SET_RATE_DVFS) which tells the clk framework that this clock is
special and clk_set_rate should call dvfs_set_opp(), where
dvfs_set_opp() is never exposed to drivers directly.

None of the above solutions are related to your point about scaling
voltage from clk_set_rate.  Voltage may still be scaled from the clock
rate-change notifier despite the method chose to scale groups of clocks.

Regards,
Mike

 Thanks
 Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 2/5] clk: notifier handler for dynamic voltage scaling

2013-03-01 Thread Mike Turquette
Quoting Bill Huang (2013-03-01 01:41:31)
 On Thu, 2013-02-28 at 12:49 +0800, Mike Turquette wrote:
  Dynamic voltage and frequency scaling (dvfs) is a common power saving
  technique in many of today's modern processors.  This patch introduces a
  common clk rate-change notifier handler which scales voltage
  appropriately whenever clk_set_rate is called on an affected clock.
 
 I really think clk_enable and clk_disable should also be triggering
 notifier call and DVFS should act accordingly since there are cases
 drivers won't set clock rate but instead disable its clock directly, do
 you agree?
  

Hi Bill,

I'll think about this.  Perhaps a better solution would be to adapt
these drivers to runtime PM.  Then a call to runtime_pm_put() would
result in a call to clk_disable(...) and regulator_set_voltage(...).

There is no performance-based equivalent to runtime PM, which is one
reason why clk_set_rate is a likely entry point into dvfs.  But for
operations that have nice api's like runtime PM it would be better to
use those interfaces and not overload the clk.h api unnecessarily.

  There are three prerequisites to using this feature:
  
  1) the affected clocks must be using the common clk framework
  2) voltage must be scaled using the regulator framework
  3) clock frequency and regulator voltage values must be paired via the
  OPP library
 
 Just a note, Tegra Core won't meet prerequisite #3 since each regulator
 voltage values is associated with clocks driving those many sub-HW
 blocks in it.

This patch isn't the one and only way to perform dvfs.  It is just a
helper function for registering notifier handlers for systems that meet
the above three requirements.  Even if you do not use the OPP library
there is no reason why you could not register your own rate-change
notifier handler to implement dvfs using whatever lookup-table you use
today.

And patches are welcome to extend the usefulness of this helper.  I'd
like as many people to benefit from this mechanism as possible.

At some point we should think hard about DT bindings for these operating
points...

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH 2/5] clk: notifier handler for dynamic voltage scaling

2013-03-01 Thread Mike Turquette
Quoting Mike Turquette (2013-03-01 10:22:34)
 Quoting Bill Huang (2013-03-01 01:41:31)
  On Thu, 2013-02-28 at 12:49 +0800, Mike Turquette wrote:
   Dynamic voltage and frequency scaling (dvfs) is a common power saving
   technique in many of today's modern processors.  This patch introduces a
   common clk rate-change notifier handler which scales voltage
   appropriately whenever clk_set_rate is called on an affected clock.
  
  I really think clk_enable and clk_disable should also be triggering
  notifier call and DVFS should act accordingly since there are cases
  drivers won't set clock rate but instead disable its clock directly, do
  you agree?
   
 
 Hi Bill,
 
 I'll think about this.  Perhaps a better solution would be to adapt
 these drivers to runtime PM.  Then a call to runtime_pm_put() would
 result in a call to clk_disable(...) and regulator_set_voltage(...).
 
 There is no performance-based equivalent to runtime PM, which is one
 reason why clk_set_rate is a likely entry point into dvfs.  But for
 operations that have nice api's like runtime PM it would be better to
 use those interfaces and not overload the clk.h api unnecessarily.
 

Bill,

I wasn't thinking at all when I wrote this.  Trying to rush to the
airport I guess...

clk_enable() and clk_disable() must not sleep and all operations are
done under a spinlock.  So this rules out most use of notifiers.  It is
expected for some drivers to very aggressively enable/disable clocks in
interrupt handlers so scaling voltage as a function of clk_{en|dis}able
calls is also likely out of the question.

Some platforms have chosen to implement voltage scaling in their
.prepare callbacks.  I personally do not like this and still prefer
drivers be adapted to runtime pm and let those callbacks handle voltage
scaling along with clock handling.

Regards,
Mike

   There are three prerequisites to using this feature:
   
   1) the affected clocks must be using the common clk framework
   2) voltage must be scaled using the regulator framework
   3) clock frequency and regulator voltage values must be paired via the
   OPP library
  
  Just a note, Tegra Core won't meet prerequisite #3 since each regulator
  voltage values is associated with clocks driving those many sub-HW
  blocks in it.
 
 This patch isn't the one and only way to perform dvfs.  It is just a
 helper function for registering notifier handlers for systems that meet
 the above three requirements.  Even if you do not use the OPP library
 there is no reason why you could not register your own rate-change
 notifier handler to implement dvfs using whatever lookup-table you use
 today.
 
 And patches are welcome to extend the usefulness of this helper.  I'd
 like as many people to benefit from this mechanism as possible.
 
 At some point we should think hard about DT bindings for these operating
 points...
 
 Regards,
 Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 4/5] HACK: set_parent callback for OMAP4 non-core DPLLs

2013-02-27 Thread Mike Turquette
This is a silly patch that demonstrates calling clk_set_parent from
within a .set_rate callback, which itself was called by clk_set_rate.
It may make your board burst into flames or otherwise void various
warrantees.

I do not suggest that the OMAP folks take this approach in unless they
really want to.  Instead it was a way for me to increase code coverage
while testing the reentrancy changes to the core clock framework.

Changes in this patch include removing __clk_prepare and __clk_unprepare
from omap3_noncore_dpll_set_rate and using the (now reentrant)
clk_prepare  clk_unprepare versions.  Most importantly this patch
introduces omap3_noncore_dpll_set_parent and adds it to the clk_ops for
all OMAP3+ DPLLs.

The net gain is that on OMAP4 platforms it is now possible to call
clk_set_parent(some_dpll_ck, ...) in order to change the PLL input from
the reference clock to the bypass clock, and vice versa.

omap3_noncore_dpll_set_rate is modified to call clk_set_parent when
appropriate as a way to test reentrancy.

Not-signed-off-by: Mike Turquette mturque...@linaro.org
---
 arch/arm/mach-omap2/cclock44xx_data.c |1 +
 arch/arm/mach-omap2/clock.h   |1 +
 arch/arm/mach-omap2/dpll3xxx.c|  107 +
 3 files changed, 84 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/cclock44xx_data.c 
b/arch/arm/mach-omap2/cclock44xx_data.c
index 5789a5e..df5da7f 100644
--- a/arch/arm/mach-omap2/cclock44xx_data.c
+++ b/arch/arm/mach-omap2/cclock44xx_data.c
@@ -386,6 +386,7 @@ static const struct clk_ops dpll_ck_ops = {
.round_rate = omap2_dpll_round_rate,
.set_rate   = omap3_noncore_dpll_set_rate,
.get_parent = omap2_init_dpll_parent,
+   .set_parent = omap3_noncore_dpll_set_parent,
 };
 
 static struct clk_hw_omap dpll_iva_ck_hw = {
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index b402048..1cf43a5 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -367,6 +367,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long 
target_rate,
 unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
 int omap3_noncore_dpll_enable(struct clk_hw *hw);
 void omap3_noncore_dpll_disable(struct clk_hw *hw);
+int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index);
 int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
 u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index 0a02aab5..bae123e 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -450,6 +450,76 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
clkdm_clk_disable(clk-clkdm, hw-clk);
 }
 
+/* Non-CORE DPLL set parent code */
+
+/**
+ * omap3_noncore_dpll_set_parent - set non-core DPLL input
+ * @hw: hardware object for this clock/dpll
+ * @index: parent to switch to in the array of possible parents
+ *
+ * Sets the input to the DPLL to either the reference clock or bypass
+ * clock.  Returns error code upon failure or 0 upon success.
+ */
+int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+   u16 freqsel = 0;
+   struct dpll_data *dd;
+   int ret;
+
+   if (!hw)
+   return -EINVAL;
+
+   dd = clk-dpll_data;
+   if (!dd)
+   return -EINVAL;
+
+   clk_prepare(dd-clk_bypass);
+   clk_enable(dd-clk_bypass);
+   clk_prepare(dd-clk_ref);
+   clk_enable(dd-clk_ref);
+
+   /* FIXME hard coded magic numbers are gross */
+   switch (index) {
+   /* dpll input is the reference clock */
+   case 0:
+   if (dd-last_rounded_rate == 0)
+   return -EINVAL;
+
+   /* No freqsel on OMAP4 and OMAP3630 */
+   if (!cpu_is_omap44xx()  !cpu_is_omap3630()) {
+   freqsel = _omap3_dpll_compute_freqsel(clk,
+   dd-last_rounded_n);
+   WARN_ON(!freqsel);
+   }
+
+   pr_debug(%s: %s: set rate: locking rate to %lu.\n,
+   __func__, __clk_get_name(hw-clk), 
dd-last_rounded_rate);
+
+   ret = omap3_noncore_dpll_program(clk, freqsel);
+   break;
+
+   /* dpll input is the bypass clock */
+   case 1:
+   pr_debug(%s: %s: set rate: entering bypass.\n,
+   __func__, __clk_get_name(hw-clk));
+
+   ret = _omap3_noncore_dpll_bypass(clk);
+   break;
+
+   default:
+   pr_warn(%s: %s: set parent: invalid parent

[PATCH v3 0/5] common clk framework reentrancy dvfs, take 3

2013-02-27 Thread Mike Turquette
Hello,

This series implements reentrancy for the common clk implementation of
the clk.h api.  Making reentrant calls into the clock framework is both
necessary and desirable for many use cases such as enabling off-chip
clocks via i2c.  The first patch in the series implements this.

A neat side effect of reentrancy is that it is possible for platforms
using voltage regulators controlled via i2c to register rate-change
notifier handlers to scale voltage as a function of clock rate.  This is
an effective way to implement dynamic voltage  frequency scaling.
Patch #2 implements a helper function for registering such a notifier
handler.

The third patch in the series demonstrates dvfs on OMAP platforms by
modifying the cpufreq-omap driver; it migrates the voltage scaling logic
out of the cpufreq driver's .target callback and registers callbacks via
the helper introduced in patch #2.

Patches four and five are purely test coverage.  And what better way to
test than to muck with fragile PLL programming code?  These patches test
out a lot of the aforementioned reentrancy in the OMAP3+ DPLL code.
They are not for merging, but as a demonstration of what is now
possible.

Finally, I know that Documentation/clk.txt needs an update for these
changes but I wanted this on the list before I flew out to LCA 2013.
I'll provide that update during or after the conference.

Two previous (and considerably more insane) attempts at this,
v1: http://article.gmane.org/gmane.linux.kernel/1327866
v2: http://marc.info/?l=linux-kernelm=134507429302463w=2

Mike Turquette (5):
  clk: allow reentrant calls into the clk framework
  clk: notifier handler for dynamic voltage scaling
  cpufreq: omap: scale regulator from clk notifier
  HACK: set_parent callback for OMAP4 non-core DPLLs
  HACK: omap: opp: add fake 400MHz OPP to bypass MPU

 arch/arm/mach-omap2/cclock44xx_data.c |1 +
 arch/arm/mach-omap2/clock.h   |1 +
 arch/arm/mach-omap2/dpll3xxx.c|  107 ++
 arch/arm/mach-omap2/opp4xxx_data.c|   18 +++
 drivers/clk/Makefile  |1 +
 drivers/clk/clk.c |  254 -
 drivers/clk/dvfs.c|  125 
 drivers/cpufreq/omap-cpufreq.c|   82 +++
 include/linux/clk.h   |   27 +++-
 9 files changed, 459 insertions(+), 157 deletions(-)
 create mode 100644 drivers/clk/dvfs.c

-- 
1.7.10.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 5/5] HACK: omap: opp: add fake 400MHz OPP to bypass MPU

2013-02-27 Thread Mike Turquette
From: Mike Turquette mturque...@ti.com

The following is another silly patch which was done to test calling
clk_set_parent from within a call to clk_set_rate.  It may make your
board burst into flames or otherwise void various warrantees.

This patch introduces a 400MHz OPP for the MPU, which happens to
correspond to the bypass clk rate on the 4430 Panda board and 4460 Panda
ES board, both using a 38.4MHz SYS_CLK oscillator rate.

One may test this by using the cpufreq-userspace governor and executing:
echo 40  /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

On Panda ES validation can be done via:
$ find /debug/clk/ -iname dpll_mpu_ck
/debug/clk/virt_3840_ck/sys_clkin_ck/dpll_mpu_ck
$ echo 40  scaling_setspeed
$ find /debug/clk/ -iname dpll_mpu_ck
/debug/clk/virt_3840_ck/sys_clkin_ck/dpll_core_ck/dpll_core_x2_ck/dpll_core_m5x2_ck/div_mpu_hs_clk/dpll_mpu_ck
$ cat /proc/cpuinfo
...
BogoMIPS: 794.26
...
$ cat /sys/class/regulator/regulator.3/microvolts
120

Not-signed-off-by: Mike Turquette mturque...@ti.com
---
 arch/arm/mach-omap2/opp4xxx_data.c |   18 ++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/mach-omap2/opp4xxx_data.c 
b/arch/arm/mach-omap2/opp4xxx_data.c
index d470b72..c7bccf7 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -67,6 +67,15 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = {
 static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
OPP_INITIALIZER(mpu, true, 3, OMAP4430_VDD_MPU_OPP50_UV),
+   /*
+* MPU OPP1.5 - 400MHz - completely FAKE - not endorsed by TI
+*
+* DPLL_MPU is in Low Power Bypass driven by DPLL_CORE.  After
+* transitioning to this OPP you can see the migration in debugfs:
+* /d/clk/virt_3840_ck/sys_clkin_ck/dpll_mpu_ck to
+* /d/.../dpll_core_ck/dpll_core_x2_ck/dpll_core_m5x2_ck/div_mpu_hs_clk
+*/
+   OPP_INITIALIZER(mpu, true, 4, 110),
/* MPU OPP2 - OPP100 */
OPP_INITIALIZER(mpu, true, 6, OMAP4430_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
@@ -126,6 +135,15 @@ struct omap_volt_data omap446x_vdd_core_volt_data[] = {
 static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
OPP_INITIALIZER(mpu, true, 35000, OMAP4460_VDD_MPU_OPP50_UV),
+   /*
+* MPU OPP1.5 - 400MHz - completely FAKE - not endorsed by TI
+*
+* DPLL_MPU is in Low Power Bypass driven by DPLL_CORE.  After
+* transitioning to this OPP you can see the migration in debugfs:
+* /d/clk/virt_3840_ck/sys_clkin_ck/dpll_mpu_ck to
+* /d/.../dpll_core_ck/dpll_core_x2_ck/dpll_core_m5x2_ck/div_mpu_hs_clk
+*/
+   OPP_INITIALIZER(mpu, true, 4, 110),
/* MPU OPP2 - OPP100 */
OPP_INITIALIZER(mpu, true, 7, OMAP4460_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
-- 
1.7.10.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 2/5] clk: notifier handler for dynamic voltage scaling

2013-02-27 Thread Mike Turquette
Dynamic voltage and frequency scaling (dvfs) is a common power saving
technique in many of today's modern processors.  This patch introduces a
common clk rate-change notifier handler which scales voltage
appropriately whenever clk_set_rate is called on an affected clock.

There are three prerequisites to using this feature:

1) the affected clocks must be using the common clk framework
2) voltage must be scaled using the regulator framework
3) clock frequency and regulator voltage values must be paired via the
OPP library

If a platform or device meets these requirements then using the notifier
handler is straightforward.  A struct device is used as the basis for
performing initial look-ups for clocks via clk_get and regulators via
regulator_get.  This means that notifiers are subscribed on a per-device
basis and multiple devices can have notifiers subscribed to the same
clock.  Put another way, the voltage chosen for a rail during a call to
clk_set_rate is a function of the device, not the clock.

Signed-off-by: Mike Turquette mturque...@linaro.org
---
 drivers/clk/Makefile |1 +
 drivers/clk/dvfs.c   |  125 ++
 include/linux/clk.h  |   27 ++-
 3 files changed, 152 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/dvfs.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e73b1d6..e720b7c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_COMMON_CLK)+= clk-fixed-factor.o
 obj-$(CONFIG_COMMON_CLK)   += clk-fixed-rate.o
 obj-$(CONFIG_COMMON_CLK)   += clk-gate.o
 obj-$(CONFIG_COMMON_CLK)   += clk-mux.o
+obj-$(CONFIG_COMMON_CLK)   += dvfs.o
 
 # SoCs specific
 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
diff --git a/drivers/clk/dvfs.c b/drivers/clk/dvfs.c
new file mode 100644
index 000..d916d0b
--- /dev/null
+++ b/drivers/clk/dvfs.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011-2012 Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Helper functions for dynamic voltage  frequency transitions using
+ * the OPP library.
+ */
+
+#include linux/clk.h
+#include linux/regulator/consumer.h
+#include linux/opp.h
+#include linux/device.h
+#include linux/slab.h
+#include linux/module.h
+
+/*
+ * XXX clk, regulator  tolerance should be stored in the OPP table?
+ */
+struct dvfs_info {
+   struct device *dev;
+   struct clk *clk;
+   struct regulator *reg;
+   int tol;
+   struct notifier_block nb;
+};
+
+#define to_dvfs_info(_nb) container_of(_nb, struct dvfs_info, nb)
+
+static int dvfs_clk_notifier_handler(struct notifier_block *nb,
+   unsigned long flags, void *data)
+{
+   struct clk_notifier_data *cnd = data;
+   struct dvfs_info *di = to_dvfs_info(nb);
+   int ret, volt_new, volt_old;
+   struct opp *opp;
+
+   volt_old = regulator_get_voltage(di-reg);
+   rcu_read_lock();
+   opp = opp_find_freq_floor(di-dev, cnd-new_rate);
+   volt_new = opp_get_voltage(opp);
+   rcu_read_unlock();
+
+   /* scaling up?  scale voltage before frequency */
+   if (flags  PRE_RATE_CHANGE  cnd-new_rate  cnd-old_rate) {
+   dev_dbg(di-dev, %s: %d mV -- %d mV\n,
+   __func__, volt_old, volt_new);
+
+   ret = regulator_set_voltage_tol(di-reg, volt_new, di-tol);
+
+   if (ret) {
+   dev_warn(di-dev, %s: unable to scale voltage up.\n,
+__func__);
+   return notifier_from_errno(ret);
+   }
+   }
+
+   /* scaling down?  scale voltage after frequency */
+   if (flags  POST_RATE_CHANGE  cnd-new_rate  cnd-old_rate) {
+   dev_dbg(di-dev, %s: %d mV -- %d mV\n,
+   __func__, volt_old, volt_new);
+
+   ret = regulator_set_voltage_tol(di-reg, volt_new, di-tol);
+
+   if (ret) {
+   dev_warn(di-dev, %s: unable to scale voltage down.\n,
+__func__);
+   return notifier_from_errno(ret);
+   }
+   }
+
+   return NOTIFY_OK;
+}
+
+struct dvfs_info *dvfs_clk_notifier_register(struct dvfs_info_init *dii)
+{
+   struct dvfs_info *di;
+   int ret = 0;
+
+   if (!dii)
+   return ERR_PTR(-EINVAL);
+
+   di = kzalloc(sizeof(struct dvfs_info), GFP_KERNEL);
+   if (!di)
+   return ERR_PTR(-ENOMEM);
+
+   di-dev = dii-dev;
+   di-clk = clk_get(di-dev, dii-con_id);
+   if (IS_ERR(di-clk)) {
+   ret = -ENOMEM;
+   goto err;
+   }
+
+   di-reg = regulator_get(di-dev, dii-reg_id);
+   if (IS_ERR(di-reg)) {
+   ret = -ENOMEM;
+   goto err

[PATCH 3/5] cpufreq: omap: scale regulator from clk notifier

2013-02-27 Thread Mike Turquette
This patch moves direct control of the MPU voltage regulator out of the
cpufreq driver .target callback and instead uses the common dvfs clk
rate-change notifier infrastructure.

Ideally it would be nice to reduce the .target callback for omap's
cpufreq driver to a simple call to clk_set_rate.  For now there is still
some other stuff needed there (jiffies per loop, rounding the rate, etc
etc).

Signed-off-by: Mike Turquette mturque...@linaro.org
---
 drivers/cpufreq/omap-cpufreq.c |   82 ++--
 1 file changed, 20 insertions(+), 62 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 1f3417a..6bec1c4 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -37,7 +37,7 @@ static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
 static struct device *mpu_dev;
-static struct regulator *mpu_reg;
+static struct dvfs_info *di;
 
 static int omap_verify_speed(struct cpufreq_policy *policy)
 {
@@ -62,10 +62,9 @@ static int omap_target(struct cpufreq_policy *policy,
   unsigned int relation)
 {
unsigned int i;
-   int r, ret = 0;
+   int ret = 0;
struct cpufreq_freqs freqs;
-   struct opp *opp;
-   unsigned long freq, volt = 0, volt_old = 0, tol = 0;
+   unsigned long freq;
 
if (!freq_table) {
dev_err(mpu_dev, %s: cpu%d: no freq table!\n, __func__,
@@ -109,50 +108,13 @@ static int omap_target(struct cpufreq_policy *policy,
}
freq = ret;
 
-   if (mpu_reg) {
-   opp = opp_find_freq_ceil(mpu_dev, freq);
-   if (IS_ERR(opp)) {
-   dev_err(mpu_dev, %s: unable to find MPU OPP for %d\n,
-   __func__, freqs.new);
-   return -EINVAL;
-   }
-   volt = opp_get_voltage(opp);
-   tol = volt * OPP_TOLERANCE / 100;
-   volt_old = regulator_get_voltage(mpu_reg);
-   }
-
-   dev_dbg(mpu_dev, cpufreq-omap: %u MHz, %ld mV -- %u MHz, %ld mV\n, 
-   freqs.old / 1000, volt_old ? volt_old / 1000 : -1,
-   freqs.new / 1000, volt ? volt / 1000 : -1);
-
-   /* scaling up?  scale voltage before frequency */
-   if (mpu_reg  (freqs.new  freqs.old)) {
-   r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
-   if (r  0) {
-   dev_warn(mpu_dev, %s: unable to scale voltage up.\n,
-__func__);
-   freqs.new = freqs.old;
-   goto done;
-   }
-   }
+   dev_dbg(mpu_dev, cpufreq-omap: %u MHz -- %u MHz\n,
+   freqs.old / 1000, freqs.new / 1000); 
 
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
 
-   /* scaling down?  scale voltage after frequency */
-   if (mpu_reg  (freqs.new  freqs.old)) {
-   r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
-   if (r  0) {
-   dev_warn(mpu_dev, %s: unable to scale voltage down.\n,
-__func__);
-   ret = clk_set_rate(mpu_clk, freqs.old * 1000);
-   freqs.new = freqs.old;
-   goto done;
-   }
-   }
-
freqs.new = omap_getspeed(policy-cpu);
 
-done:
/* notifiers */
for_each_cpu(i, policy-cpus) {
freqs.cpu = i;
@@ -172,10 +134,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy 
*policy)
 {
int result = 0;
 
-   mpu_clk = clk_get(NULL, cpufreq_ck);
-   if (IS_ERR(mpu_clk))
-   return PTR_ERR(mpu_clk);
-
if (policy-cpu = NR_CPUS) {
result = -EINVAL;
goto fail_ck;
@@ -253,34 +211,34 @@ static struct cpufreq_driver omap_driver = {
 
 static int __init omap_cpufreq_init(void)
 {
+   struct dvfs_info_init dii;
+
+   mpu_clk = clk_get(NULL, cpufreq_ck);
+   if (IS_ERR(mpu_clk))
+   return PTR_ERR(mpu_clk);
+
mpu_dev = get_cpu_device(0);
if (!mpu_dev) {
pr_warning(%s: unable to get the mpu device\n, __func__);
return -EINVAL;
}
 
-   mpu_reg = regulator_get(mpu_dev, vcc);
-   if (IS_ERR(mpu_reg)) {
-   pr_warning(%s: unable to get MPU regulator\n, __func__);
-   mpu_reg = NULL;
-   } else {
-   /* 
-* Ensure physical regulator is present.
-* (e.g. could be dummy regulator.)
-*/
-   if (regulator_get_voltage(mpu_reg)  0) {
-   pr_warn(%s: physical regulator not present for MPU\n,
+   dii.dev = mpu_dev;
+   dii.con_id = cpufreq_ck;
+   dii.reg_id = vcc;
+   dii.tol = OPP_TOLERANCE;
+
+   di

[PATCH 1/5] clk: allow reentrant calls into the clk framework

2013-02-27 Thread Mike Turquette
Reentrancy into the clock framework from the clk.h api is highly
desirable.  This feature is necessary for clocks that are prepared and
unprepared via i2c_transfer (which includes many PMICs and discrete
audio chips) and it is also necessary for performing dynamic voltage 
frequency scaling via clock rate-change notifiers.

This patch implements reentrancy by adding a global atomic_t which
tracks the context of the current caller.  Context in this case is the
return value from get_current().  The clk.h api implementations are
modified to first see if the relevant global lock is already held and if
so compare the global context (set by whoever is holding the lock)
against their own context (via a call to get_current()).  If the two
match then this function is a nested call from the one already holding
the lock and we procede.  If the context does not match then procede to
call mutex_lock and busy-wait for the existing task to complete.

Thus this patch set does not increase concurrency for unrelated calls
into the clock framework.  Instead it simply allows reentrancy by the
single task which is currently holding the global clock framework lock.

Thanks to Rajagoapl Venkat for the original idea to use get_current()
and to David Brown for the suggestion to replace my previous rwlock
scheme with atomic operations during code review at ELC 2013.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Rajagopal Venkat rajagopal.ven...@linaro.org
Cc: David Brown dav...@codeaurora.org
---
 drivers/clk/clk.c |  254 ++---
 1 file changed, 185 insertions(+), 69 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fabbfe1..b7d6a0a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -19,9 +19,11 @@
 #include linux/of.h
 #include linux/device.h
 #include linux/init.h
+#include linux/sched.h
 
 static DEFINE_SPINLOCK(enable_lock);
 static DEFINE_MUTEX(prepare_lock);
+static atomic_t context;
 
 static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
@@ -433,27 +435,6 @@ unsigned int __clk_get_prepare_count(struct clk *clk)
return !clk ? 0 : clk-prepare_count;
 }
 
-unsigned long __clk_get_rate(struct clk *clk)
-{
-   unsigned long ret;
-
-   if (!clk) {
-   ret = 0;
-   goto out;
-   }
-
-   ret = clk-rate;
-
-   if (clk-flags  CLK_IS_ROOT)
-   goto out;
-
-   if (!clk-parent)
-   ret = 0;
-
-out:
-   return ret;
-}
-
 unsigned long __clk_get_flags(struct clk *clk)
 {
return !clk ? 0 : clk-flags;
@@ -524,6 +505,35 @@ struct clk *__clk_lookup(const char *name)
return NULL;
 }
 
+/***  locking  reentrancy ***/
+
+static void clk_fwk_lock(void)
+{
+   /* hold the framework-wide lock, context == NULL */
+   mutex_lock(prepare_lock);
+
+   /* set context for any reentrant calls */
+   atomic_set(context, (int) get_current());
+}
+
+static void clk_fwk_unlock(void)
+{
+   /* clear the context */
+   atomic_set(context, 0);
+
+   /* release the framework-wide lock, context == NULL */
+   mutex_unlock(prepare_lock);
+}
+
+static bool clk_is_reentrant(void)
+{
+   if (mutex_is_locked(prepare_lock))
+   if ((void *) atomic_read(context) == get_current())
+   return true;
+
+   return false;
+}
+
 /***clk api***/
 
 void __clk_unprepare(struct clk *clk)
@@ -558,9 +568,15 @@ void __clk_unprepare(struct clk *clk)
  */
 void clk_unprepare(struct clk *clk)
 {
-   mutex_lock(prepare_lock);
+   /* re-enter if call is from the same context */
+   if (clk_is_reentrant()) {
+   __clk_unprepare(clk);
+   return;
+   }
+
+   clk_fwk_lock();
__clk_unprepare(clk);
-   mutex_unlock(prepare_lock);
+   clk_fwk_unlock();
 }
 EXPORT_SYMBOL_GPL(clk_unprepare);
 
@@ -606,10 +622,16 @@ int clk_prepare(struct clk *clk)
 {
int ret;
 
-   mutex_lock(prepare_lock);
-   ret = __clk_prepare(clk);
-   mutex_unlock(prepare_lock);
+   /* re-enter if call is from the same context */
+   if (clk_is_reentrant()) {
+   ret = __clk_prepare(clk);
+   goto out;
+   }
 
+   clk_fwk_lock();
+   ret = __clk_prepare(clk);
+   clk_fwk_unlock();
+out:
return ret;
 }
 EXPORT_SYMBOL_GPL(clk_prepare);
@@ -650,8 +672,27 @@ void clk_disable(struct clk *clk)
 {
unsigned long flags;
 
+   /* must check both the global spinlock and the global mutex */
+   if (spin_is_locked(enable_lock) || mutex_is_locked(prepare_lock)) {
+   if ((void *) atomic_read(context) == get_current()) {
+   __clk_disable(clk);
+   return;
+   }
+   }
+
+   /* hold the framework-wide lock, context == NULL */
spin_lock_irqsave(enable_lock, flags);
+
+   /* set context for any reentrant calls

Re: [powerdebug,1/1] clock: support common clock framework

2013-01-25 Thread Mike Turquette
Quoting Amit Kucheria (2013-01-25 03:18:05)
 On Fri, Jan 25, 2013 at 9:08 AM, Sanjay Singh Rawat
 sanjay.ra...@linaro.org wrote:
  On Thursday 24 January 2013 11:24 PM, Mike Turquette wrote:
 
  Quoting Sanjay Singh Rawat (2013-01-24 08:01:33)
 
 
 You're missing a changelog describing why this patch is required. :)
 
 
  Signed-off-by: Sanjay Singh Rawat sanjay.ra...@linaro.com
 
 
  Sanjay,
 
  Have you seen the patch to dump the CCF tree from a single sysfs file,
  in JSON format?
 
 
  http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=commitdiff;h=bddca8944a7ab6699984c4b1b677261eb1c8d819;hp=1af599df6bdad9ee34ae9e50efcda273e12b9d4f
 
  This is much nicer than parsing a directory structure.  It is faster and
  most importantly the data is atomic.  A lock is held across the clock
  framework while the data is accessed so you don't have to worry about
  data changing in between reads like you do with the directory method.
 
  Regards,
  Mike
 
  Thanks Mike, yes i remember your point. This change is for addressing the
  bug of clock entries not getting populated on CCF enabled kernel.
 
  Will check for clock_tree_dump file implementation separately.
 
 I think what Mike is saying is that you could get rid of all the
 directory parsing code and just read this one file for all of your
 clock data.
 

I think leaving the legacy code in is fine.  The current powerdebug code
already checks to see if this is a CCF or legacy clk tree, so we could
leave the legacy code in and change the CCF method to use the clk-dump
sysfs file when CCF is detected.


 But it wouldn't work for platforms that haven't converted over to CCF.
 Mike, all member platforms converted over now?
 

I'll have to check, but as stated above we don't need to remove the
legacy clk code.

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [powerdebug,1/1] clock: support common clock framework

2013-01-24 Thread Mike Turquette
Quoting Sanjay Singh Rawat (2013-01-24 08:01:33)
 Signed-off-by: Sanjay Singh Rawat sanjay.ra...@linaro.com

Sanjay,

Have you seen the patch to dump the CCF tree from a single sysfs file,
in JSON format?

http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=commitdiff;h=bddca8944a7ab6699984c4b1b677261eb1c8d819;hp=1af599df6bdad9ee34ae9e50efcda273e12b9d4f

This is much nicer than parsing a directory structure.  It is faster and
most importantly the data is atomic.  A lock is held across the clock
framework while the data is accessed so you don't have to worry about
data changing in between reads like you do with the directory method.

Regards,
Mike

 ---
  clocks.c |   69 
 ++
  1 file changed, 56 insertions(+), 13 deletions(-)
 
 diff --git a/clocks.c b/clocks.c
 index 2611a0d..95acf57 100644
 --- a/clocks.c
 +++ b/clocks.c
 @@ -42,9 +42,19 @@ struct clock_info {
 int usecount;
 bool expanded;
 char *prefix;
 +   int preparecount;
 +   int enablecount;
 +   int notifiercount;
  } *clocks_info;
  
 +enum clock_fw_type{
 +   CCF,/* common clock framework */
 +   OCF,/* old clock framework */
 +   MAX,
 +};
 +
  static struct tree *clock_tree = NULL;
 +static int clock_fw;
  
  static int locate_debugfs(char *clk_path)
  {
 @@ -144,9 +154,18 @@ static inline int read_clock_cb(struct tree *t, void 
 *data)
  {
 struct clock_info *clk = t-private;
  
 -   file_read_value(t-path, flags, %x, clk-flags);
 -   file_read_value(t-path, rate, %d, clk-rate);
 -   file_read_value(t-path, usecount, %d, clk-usecount);
 +   if(clock_fw == CCF) {
 +   file_read_value(t-path, clk_flags, %x, clk-flags);
 +   file_read_value(t-path, clk_rate, %d, clk-rate);
 +   file_read_value(t-path, clk_prepare_count, %d, 
 clk-preparecount);
 +   file_read_value(t-path, clk_enable_count, %d, 
 clk-enablecount);
 +   file_read_value(t-path, clk_notifier_count, %d, 
 clk-notifiercount);
 +   }
 +   else {
 +   file_read_value(t-path, flags, %x, clk-flags);
 +   file_read_value(t-path, rate, %d, clk-rate);
 +   file_read_value(t-path, usecount, %d, clk-usecount);
 +   }
  
 return 0;
  }
 @@ -206,9 +225,17 @@ static char *clock_line(struct tree *t)
 if (asprintf(clkrate, %d%s, rate, clkunit)  0)
 goto free_clkname;
  
 -   if (asprintf(clkline, %-55s 0x%-16x %-12s %-9d %-8d, clkname,
 -clk-flags, clkrate, clk-usecount, t-nrchild)  0)
 -   goto free_clkrate;
 +   if(clock_fw == CCF) {
 +   if (asprintf(clkline, %-35s 0x%-8x %-12s %-10d %-11d %-15d 
 %-14d %-10d,
 +clkname, clk-flags, clkrate, clk-usecount, 
 t-nrchild,
 +clk-preparecount, clk-enablecount, 
 clk-notifiercount)  0)
 +   goto free_clkrate;
 +   }
 +   else {
 +   if (asprintf(clkline, %-55s 0x%-16x %-12s %-9d %-8d,
 +clkname, clk-flags, clkrate, clk-usecount, 
 t-nrchild)  0)
 +   goto free_clkrate;
 +   }
  
  free_clkrate:
 free(clkrate);
 @@ -259,9 +286,17 @@ static int clock_print_header(void)
 char *buf;
 int ret;
  
 -   if (asprintf(buf, %-55s %-16s %-12s %-9s %-8s,
 +   if(clock_fw == CCF) {
 +   if (asprintf(buf, %-35s %-10s %-12s %-10s %-11s %-15s %-14s 
 %-14s,
 +Name, Flags, Rate, Usecount, Children, 
 Prepare_Count,
 +Enable_Count, Notifier_Count)  0)
 +   return -1;
 +   }
 +   else {
 +   if (asprintf(buf, %-55s %-16s %-12s %-9s %-8s,
  Name, Flags, Rate, Usecount, Children)  0)
 return -1;
 +   }
  
 ret = display_column_name(buf);
  
 @@ -384,17 +419,25 @@ static struct display_ops clock_ops = {
   */
  int clock_init(void)
  {
 -   char clk_dir_path[PATH_MAX];
 +   char clk_dir_path[MAX+1][PATH_MAX];
  
 -   if (locate_debugfs(clk_dir_path))
 +   if (locate_debugfs(clk_dir_path[CCF]) || 
 locate_debugfs(clk_dir_path[OCF]))
 return -1;
  
 -   sprintf(clk_dir_path, %s/clock, clk_dir_path);
 -
 -   if (access(clk_dir_path, F_OK))
 +   sprintf(clk_dir_path[CCF], %s/clk, clk_dir_path[CCF]);
 +   sprintf(clk_dir_path[OCF], %s/clock, clk_dir_path[OCF]);
 +   if (!access(clk_dir_path[CCF], F_OK)) {
 +   clock_fw = CCF;
 +   strcpy(clk_dir_path[MAX],clk_dir_path[CCF]);
 +   }
 +   else if(!access(clk_dir_path[OCF], F_OK)) {
 +   clock_fw = OCF;
 +   strcpy(clk_dir_path[MAX],clk_dir_path[OCF]);
 +   }
 +   else
 return -1;
  
 -   clock_tree = tree_load(clk_dir_path, NULL, false);
 +   

Re: [PATCH] clk: remove unreachable code

2013-01-18 Thread Mike Turquette
Quoting Rajagopal Venkat (2013-01-16 04:45:13)
 On 16 January 2013 04:15, Mike Turquette mturque...@linaro.org wrote:
  Quoting Rajagopal Venkat (2013-01-08 22:29:48)
  while reparenting a clock, NULL check is done for clock in
  consideration and its new parent. So re-check is not required.
  If done, else part becomes unreachable.
 
  Signed-off-by: Rajagopal Venkat rajagopal.ven...@linaro.org
  ---
   drivers/clk/clk.c |   13 ++---
   1 file changed, 2 insertions(+), 11 deletions(-)
 
  diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
  index 251e45d..1c4097c 100644
  --- a/drivers/clk/clk.c
  +++ b/drivers/clk/clk.c
  @@ -1040,7 +1040,6 @@ void __clk_reparent(struct clk *clk, struct clk 
  *new_parent)
   {
   #ifdef CONFIG_COMMON_CLK_DEBUG
  struct dentry *d;
  -   struct dentry *new_parent_d;
   #endif
 
  if (!clk || !new_parent)
  @@ -1048,22 +1047,14 @@ void __clk_reparent(struct clk *clk, struct clk 
  *new_parent)
 
  hlist_del(clk-child_node);
 
  -   if (new_parent)
  -   hlist_add_head(clk-child_node, new_parent-children);
  -   else
  -   hlist_add_head(clk-child_node, clk_orphan_list);
  +   hlist_add_head(clk-child_node, new_parent-children);
 
  Rajagopal,
 
  You found a bug, but not the right one :)
 
  This change would result in never moving a clock into the orphan list if
  the parent is missing.  The right thing to do is to allow the operation
  to succeed and migrate this clock into the orphan list.  In keeping
  with the clk.h api we need to treat struct clk new_parent as an opaque
  cookie and not care whether or not it is NULL.
 
 Mike,
 
 The only path where __clk_reparent() can get new parent as NULL is from
 clk_set_parent() api. Tracing this path, here are the reasons why I submitted
 this patch.
 
 1. The clk_set_parent() function takes new parent for granted and tries to
 access new_parent-rate when notifiers are registered,
 2. For clocks with multiple parents, the __clk_set_parent() function also
 takes new parent for granted and tries to access parent name while finding
 the index of new parent from cached parent pointers.
 
 But if the design decision is to allow clock to be re-parented to orphan list
 when new parent is missing, I can provide the new working patch.
 

Rajagopal,

Yes, reparenting a clock to the orphan list should be supported.  Let me
know if you are going to spin a new patch or not.

Thanks,
Mike

  Untested patch below fixes the real bug:
 
 
 
  From a4d56e3ee51452366365749873710e16631e9de7 Mon Sep 17 00:00:00 2001
  From: Mike Turquette mturque...@linaro.org
  Date: Tue, 15 Jan 2013 14:39:06 -0800
  Subject: [PATCH] clk: allow re-parenting to NULL clks
 
  __clk_reparent presently bails early if the new parent of a clk is NULL.
  This is wrong and prevents dynamically migrating clocks into the orphan
  list.  The fix is to remove the NULL pointer check for new_parent in
  __clk_parent.
 
  Signed-off-by: Mike Turquette mturque...@linaro.org
  ---
   drivers/clk/clk.c |2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)
 
  diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
  index 593a2e4..f056230 100644
  --- a/drivers/clk/clk.c
  +++ b/drivers/clk/clk.c
  @@ -1186,7 +1186,7 @@ void __clk_reparent(struct clk *clk, struct clk 
  *new_parent)
  struct dentry *new_parent_d;
   #endif
 
  -   if (!clk || !new_parent)
  +   if (!clk)
  return;
 
  hlist_del(clk-child_node);
  --
  1.7.10.4
 
 
 
 
 -- 
 Regards,
 Rajagopal

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH] clk: remove unreachable code

2013-01-15 Thread Mike Turquette
Quoting Rajagopal Venkat (2013-01-08 22:29:48)
 while reparenting a clock, NULL check is done for clock in
 consideration and its new parent. So re-check is not required.
 If done, else part becomes unreachable.
 
 Signed-off-by: Rajagopal Venkat rajagopal.ven...@linaro.org
 ---
  drivers/clk/clk.c |   13 ++---
  1 file changed, 2 insertions(+), 11 deletions(-)
 
 diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
 index 251e45d..1c4097c 100644
 --- a/drivers/clk/clk.c
 +++ b/drivers/clk/clk.c
 @@ -1040,7 +1040,6 @@ void __clk_reparent(struct clk *clk, struct clk 
 *new_parent)
  {
  #ifdef CONFIG_COMMON_CLK_DEBUG
 struct dentry *d;
 -   struct dentry *new_parent_d;
  #endif
  
 if (!clk || !new_parent)
 @@ -1048,22 +1047,14 @@ void __clk_reparent(struct clk *clk, struct clk 
 *new_parent)
  
 hlist_del(clk-child_node);
  
 -   if (new_parent)
 -   hlist_add_head(clk-child_node, new_parent-children);
 -   else
 -   hlist_add_head(clk-child_node, clk_orphan_list);
 +   hlist_add_head(clk-child_node, new_parent-children);

Rajagopal,

You found a bug, but not the right one :)

This change would result in never moving a clock into the orphan list if
the parent is missing.  The right thing to do is to allow the operation
to succeed and migrate this clock into the orphan list.  In keeping
with the clk.h api we need to treat struct clk new_parent as an opaque
cookie and not care whether or not it is NULL.

Untested patch below fixes the real bug:



From a4d56e3ee51452366365749873710e16631e9de7 Mon Sep 17 00:00:00 2001
From: Mike Turquette mturque...@linaro.org
Date: Tue, 15 Jan 2013 14:39:06 -0800
Subject: [PATCH] clk: allow re-parenting to NULL clks

__clk_reparent presently bails early if the new parent of a clk is NULL.
This is wrong and prevents dynamically migrating clocks into the orphan
list.  The fix is to remove the NULL pointer check for new_parent in
__clk_parent.

Signed-off-by: Mike Turquette mturque...@linaro.org
---
 drivers/clk/clk.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 593a2e4..f056230 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1186,7 +1186,7 @@ void __clk_reparent(struct clk *clk, struct clk 
*new_parent)
struct dentry *new_parent_d;
 #endif
 
-   if (!clk || !new_parent)
+   if (!clk)
return;
 
hlist_del(clk-child_node);
-- 
1.7.10.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: Question: What is the current level of Free Software support by vendors?

2012-10-01 Thread Mike Turquette
Quoting Graeme Russ (2012-10-01 19:58:14)
 Hello,
 
 Firstly, sorry if this is the wrong forum - please feel free to
 re-direct me to a more appropriate place.
 
 I've been searching around for the 'net for a while but really have
 not come across a conclusive answer to just how well the free software
 community is supported by ARM vendors. Now I know that is a rather
 vague statement, so I will elaborate by framing it is a personal
 desire...
 
 What I would like is a 'device' which I can hack on (and contribute to
 the community) with the following features:
  - Ethernet (at least 100Mb/s, but 1Gb/s and/or WiFi would be a bonus)
  - USB 2.0 (3.0 would be a bonus)
  - HDMI (dual monitor support would be a big bonus)
  - 1080p video output
  - Hi-definition video codec
  - SATA
  - MMC/SD
  - 3D graphics not a big desire, but would be a bonus
 
 Essentially, I'm after a device I can use as a media box / thin-client
 X-term / hacker platform where every single byte of code that runs on
 the device is free software. This includes:
  - Boot loader (including SDRAM init)
  - Operating system (GNU / Linux would be my personal choice)
  - All drivers (no binary blobs, no 'firmware' blobs)
  - All application software
 

Have you checked out the list of platforms on the eLinux wiki?

http://elinux.org/Development_Platforms

In particular I have soft spot for TI's Pandaboard (full disclosure: TI
gives me paper money in exchange for C codes):
http://omappedia.org/wiki/PandaBoard

 I have yet to see such a platform. A lot come close, but it seems to
 me that most fall short when it comes to drivers for the video codecs.
 

Many platforms have some binary blobs which you can download to get
video decoders and 3D graphics.  The ARM cores are getting so fast today
that you can probably decode hi-res videos using FFMPEG...

Anyways you can always find such stuff in the Linaro LEBs or from the
board support website.  E.g:
http://omappedia.org/wiki/PandaBoard_FAQ#What_will_Graphics.2FGFX_support_be_like.3F_Will_drivers_be_released.3F

 Am I living a pipe-dream, or does such a device really exist?
 

I think it exists, but others may disagree.  Lots of folks use
Pandboards for set-top boxes running XBMC, hooked up to a TV via HDMI.

Happy hacking,
Mike

 Regards,
 
 Graeme
 
 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


omapconf tool publicly released

2012-09-21 Thread Mike Turquette
Hi all,

Some of you may have heard of a tool we use inside TI for debugging on
OMAP.  It's a nice userspace tool which can inspect many aspects of
hardware state called omapconf.  The tool has just been open sourced
and can be found at:

https://github.com/omapconf/omapconf

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: First cut of a TCP/IP triggered NI battery simulator power measurement

2012-09-14 Thread Mike Turquette
Quoting Zach Pfeffer (2012-09-13 23:51:47)
 Video here:
 
 https://plus.google.com/u/0/104422661029399872488/posts/gKZxeTmEkMe
 
 This is cool because it lets us easily integrate the system into LAVA.
 

It *is* cool.  Are setup instructions captured somewhere on a wiki?
This would be useful to many people.

Regards,
Mike

 -- 
 Zach Pfeffer
 Android Platform Team Lead, Linaro Platform Teams
 Linaro.org | Open source software for ARM SoCs
 Follow Linaro: http://www.facebook.com/pages/Linaro
 http://twitter.com/#!/linaroorg - http://www.linaro.org/linaro-blog
 
 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [RFC] power: opp: rcu reclaim

2012-09-13 Thread Mike Turquette
+Nishanth Menon

Quoting Vincent Guittot (2012-09-12 21:13:33)
 synchronize_rcu blocks the caller of opp_enable/disbale
 for a complete grace period. This blocking duration prevents
 any intensive use of the functions. Replace synchronize_rcu
 by call_rcu which will call our function for freeing the old
 opp element.
 
 The duration of opp_enable and opp_disable will be no more
  dependant of the grace period.
 
 Signed-off-by: Vincent Guittot vincent.guit...@linaro.org
 ---
  drivers/base/power/opp.c |   19 ++-
  1 file changed, 14 insertions(+), 5 deletions(-)
 
 diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
 index ac993ea..49e4626 100644
 --- a/drivers/base/power/opp.c
 +++ b/drivers/base/power/opp.c
 @@ -64,6 +64,7 @@ struct opp {
 unsigned long u_volt;
  
 struct device_opp *dev_opp;
 +   struct rcu_head head;
  };
  
  /**
 @@ -441,6 +442,17 @@ int opp_add(struct device *dev, unsigned long freq, 
 unsigned long u_volt)
  }
  
  /**
 + * opp_free_rcu() - helper to clear the struct opp when grace period has
 + * elapsed without blocking the the caller of opp_set_availability
 + */
 +static void opp_free_rcu(struct rcu_head *head)
 +{
 +   struct opp *opp = container_of(head, struct opp, head);
 +
 +   kfree(opp);
 +}
 +
 +/**
   * opp_set_availability() - helper to set the availability of an opp
   * @dev:   device for which we do this operation
   * @freq:  OPP frequency to modify availability
 @@ -511,7 +523,7 @@ static int opp_set_availability(struct device *dev, 
 unsigned long freq,
  
 list_replace_rcu(opp-node, new_opp-node);
 mutex_unlock(dev_opp_list_lock);
 -   synchronize_rcu();
 +   call_rcu(opp-head, opp_free_rcu);
  
 /* Notify the change of the OPP availability */
 if (availability_req)
 @@ -521,13 +533,10 @@ static int opp_set_availability(struct device *dev, 
 unsigned long freq,
 srcu_notifier_call_chain(dev_opp-head, OPP_EVENT_DISABLE,
  new_opp);
  
 -   /* clean up old opp */
 -   new_opp = opp;
 -   goto out;
 +   return 0;
  
  unlock:
 mutex_unlock(dev_opp_list_lock);
 -out:
 kfree(new_opp);
 return r;
  }
 -- 
 1.7.9.5
 
 
 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 1/5] MAINTAINERS: add entry for common clk framework

2012-05-06 Thread Mike Turquette
Signed-off-by: Mike Turquette mturque...@linaro.org
---
 MAINTAINERS |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1a2f8f5..164e9a1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1882,6 +1882,16 @@ F:   Documentation/filesystems/coda.txt
 F: fs/coda/
 F: include/linux/coda*.h
 
+COMMON CLK FRAMEWORK
+M: Mike Turquette mturque...@ti.com
+M: Mike Turquette mturque...@linaro.org
+L: linux-arm-ker...@lists.infradead.org (same as CLK API  CLKDEV)
+T: git git://git.linaro.org/people/mturquette/linux.git
+S: Maintained
+F: drivers/clk/clk.c
+F: drivers/clk/clk-*
+F: include/linux/clk-pr*
+
 COMMON INTERNET FILE SYSTEM (CIFS)
 M: Steve French sfre...@samba.org
 L: linux-c...@vger.kernel.org
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 2/5] clk: prevent spurious parent rate propagation

2012-05-06 Thread Mike Turquette
Patch 'clk: always pass parent_rate into .round_rate' made a subtle
change to the semantics of .round_rate.  It is now expected for the
parent's rate to always be passed in, simplifying the implemenation of
various .round_rate callback definitions.

However the patch also introduced a bug in clk_calc_new_rates whereby a
clock without the CLK_SET_RATE_PARENT flag set could still propagate a
rate change up to a parent clock if the the .round_rate callback
modified the best_parent_rate value in any way.

This patch fixes the issue at the framework level (in
clk_calc_new_rates) by specifically handling the case where the
CLK_SET_RATE_PARENT flag is not set.

Signed-off-by: Mike Turquette mturque...@linaro.org
Reported-by: Sascha Hauers.ha...@pengutronix.de
---
 drivers/clk/clk.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8149764..7ceca0e 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -774,12 +774,18 @@ static struct clk *clk_calc_new_rates(struct clk *clk, 
unsigned long rate)
if (IS_ERR_OR_NULL(clk))
return NULL;
 
+   /* save parent rate, if it exists */
+   if (clk-parent)
+   best_parent_rate = clk-parent-rate;
+
/* never propagate up to the parent */
if (!(clk-flags  CLK_SET_RATE_PARENT)) {
if (!clk-ops-round_rate) {
clk-new_rate = clk-rate;
return NULL;
}
+   new_rate = clk-ops-round_rate(clk-hw, rate, 
best_parent_rate);
+   goto out;
}
 
/* need clk-parent from here on out */
@@ -795,7 +801,6 @@ static struct clk *clk_calc_new_rates(struct clk *clk, 
unsigned long rate)
goto out;
}
 
-   best_parent_rate = clk-parent-rate;
new_rate = clk-ops-round_rate(clk-hw, rate, best_parent_rate);
 
if (best_parent_rate != clk-parent-rate) {
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 4/5] clk: mux: assign init data

2012-05-06 Thread Mike Turquette
The original conversion to struct clk_hw_init failed to add the pointer
assignment in clk_register_mux.

Signed-off-by: Mike Turquette mturque...@linaro.org
Reported-by: Sascha Hauer s.ha...@pengutronix.de
---
 drivers/clk/clk-mux.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 8e97491..fd36a8e 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -116,6 +116,7 @@ struct clk *clk_register_mux(struct device *dev, const char 
*name,
mux-width = width;
mux-flags = clk_mux_flags;
mux-lock = lock;
+   mux-hw.init = init;
 
clk = clk_register(dev, mux-hw);
 
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 3/5] clk: remove COMMON_CLK_DISABLE_UNUSED

2012-05-06 Thread Mike Turquette
Exposing this option generates confusion and incorrect behavior for
single-image builds across platforms.  Enable this behavior permanently.

Signed-off-by: Mike Turquette mturque...@linaro.org
---
 drivers/clk/Kconfig |   11 ---
 drivers/clk/clk.c   |2 --
 2 files changed, 0 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index f05a60d..4864407 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -23,17 +23,6 @@ config COMMON_CLK
 menu Common Clock Framework
depends on COMMON_CLK
 
-config COMMON_CLK_DISABLE_UNUSED
-   bool Disabled unused clocks at boot
-   depends on COMMON_CLK
-   ---help---
- Traverses the entire clock tree and disables any clocks that are
- enabled in hardware but have not been enabled by any device drivers.
- This saves power and keeps the software model of the clock in line
- with reality.
-
- If in doubt, say N.
-
 config COMMON_CLK_DEBUG
bool DebugFS representation of clock tree
depends on COMMON_CLK
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 7ceca0e..e5d5dc1 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -196,7 +196,6 @@ late_initcall(clk_debug_init);
 static inline int clk_debug_register(struct clk *clk) { return 0; }
 #endif
 
-#ifdef CONFIG_COMMON_CLK_DISABLE_UNUSED
 /* caller must hold prepare_lock */
 static void clk_disable_unused_subtree(struct clk *clk)
 {
@@ -246,7 +245,6 @@ static int clk_disable_unused(void)
return 0;
 }
 late_initcall(clk_disable_unused);
-#endif
 
 /***helper functions   ***/
 
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 02/13] clk: core: remove dead code paths

2012-04-11 Thread Mike Turquette
Some static inline dummy functions were left over from before the clock
core was consolidated from several C files down to one.  Remove them.

Reported-by: Shawn Guo shawn@linaro.org
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 3ed36d3..4daacf5 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -194,7 +194,7 @@ static int __init clk_debug_init(void)
 late_initcall(clk_debug_init);
 #else
 static inline int clk_debug_register(struct clk *clk) { return 0; }
-#endif /* CONFIG_COMMON_CLK_DEBUG */
+#endif
 
 #ifdef CONFIG_COMMON_CLK_DISABLE_UNUSED
 /* caller must hold prepare_lock */
@@ -246,9 +246,7 @@ static int clk_disable_unused(void)
return 0;
 }
 late_initcall(clk_disable_unused);
-#else
-static inline int clk_disable_unused(struct clk *clk) { return 0; }
-#endif /* CONFIG_COMMON_CLK_DISABLE_UNUSED */
+#endif
 
 /***helper functions   ***/
 
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 05/13] clk: use kzalloc in clk_register_mux

2012-04-11 Thread Mike Turquette
From: Shawn Guo shawn@linaro.org

Change clk_register_mux to use kzalloc, just like what all other basic
clk registration functions do.

Signed-off-by: Shawn Guo shawn@linaro.org
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk-mux.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index c71ad1f..50e0595 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -97,7 +97,7 @@ struct clk *clk_register_mux(struct device *dev, const char 
*name,
 {
struct clk_mux *mux;
 
-   mux = kmalloc(sizeof(struct clk_mux), GFP_KERNEL);
+   mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
 
if (!mux) {
pr_err(%s: could not allocate mux clk\n, __func__);
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 03/13] clk: core: clk_calc_new_rates handles NULL parents

2012-04-11 Thread Mike Turquette
It is possible to call clk_set_rate on a clock with a NULL parent.  One
such example is an adjustable-rate root clock.  Ensure that
clk_calc_new_rates does not dereference parent without checking first
and also handle the corner cases gracefully.

Reported-by: Rajendra Nayak rna...@ti.com
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk.c |   29 +
 1 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 4daacf5..d83a9e0 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -763,25 +763,38 @@ static void clk_calc_subtree(struct clk *clk, unsigned 
long new_rate)
 static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
 {
struct clk *top = clk;
-   unsigned long best_parent_rate = clk-parent-rate;
+   unsigned long best_parent_rate;
unsigned long new_rate;
 
-   if (!clk-ops-round_rate  !(clk-flags  CLK_SET_RATE_PARENT)) {
-   clk-new_rate = clk-rate;
+   /* sanity */
+   if (IS_ERR_OR_NULL(clk))
+   return NULL;
+
+   /* never propagate up to the parent */
+   if (!(clk-flags  CLK_SET_RATE_PARENT)) {
+   if (!clk-ops-round_rate) {
+   clk-new_rate = clk-rate;
+   return NULL;
+   } else {
+   new_rate = clk-ops-round_rate(clk-hw, rate, NULL);
+   goto out;
+   }
+   }
+
+   /* need clk-parent from here on out */
+   if (!clk-parent) {
+   pr_debug(%s: %s has NULL parent\n, __func__, clk-name);
return NULL;
}
 
-   if (!clk-ops-round_rate  (clk-flags  CLK_SET_RATE_PARENT)) {
+   if (!clk-ops-round_rate) {
top = clk_calc_new_rates(clk-parent, rate);
new_rate = clk-new_rate = clk-parent-new_rate;
 
goto out;
}
 
-   if (clk-flags  CLK_SET_RATE_PARENT)
-   new_rate = clk-ops-round_rate(clk-hw, rate, 
best_parent_rate);
-   else
-   new_rate = clk-ops-round_rate(clk-hw, rate, NULL);
+   new_rate = clk-ops-round_rate(clk-hw, rate, best_parent_rate);
 
if (best_parent_rate != clk-parent-rate) {
top = clk_calc_new_rates(clk-parent, best_parent_rate);
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 10/13] clk: Remove comment for end of CONFIG_COMMON_CLK section

2012-04-11 Thread Mike Turquette
From: Mark Brown broo...@opensource.wolfsonmicro.com

The comment is inaccurate (it actually ends the CONFIG_COMMON_CLK
section, there's no else) and given that we've just got a single level
of ifdef isn't really needed anyway.

Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 include/linux/clk.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index b025272..c9547d9 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -81,7 +81,7 @@ int clk_notifier_register(struct clk *clk, struct 
notifier_block *nb);
 
 int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
 
-#endif /* !CONFIG_COMMON_CLK */
+#endif
 
 /**
  * clk_get - lookup and obtain a reference to a clock producer.
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 09/13] clk: Make clk_get_rate() return 0 on error

2012-04-11 Thread Mike Turquette
From: Rajendra Nayak rna...@ti.com

Most users of clk_get_rate() actually assume a non zero
return value as a valid rate returned. Returing -EINVAL
might confuse such users, so make it instead return zero
on error.

Besides the return value of clk_get_rate seems to be
'unsigned long'.

Signed-off-by: Rajendra nayak rna...@ti.com
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 9924aec..a24b121 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -285,7 +285,7 @@ unsigned long __clk_get_rate(struct clk *clk)
unsigned long ret;
 
if (!clk) {
-   ret = -EINVAL;
+   ret = 0;
goto out;
}
 
@@ -295,7 +295,7 @@ unsigned long __clk_get_rate(struct clk *clk)
goto out;
 
if (!clk-parent)
-   ret = -ENODEV;
+   ret = 0;
 
 out:
return ret;
@@ -560,7 +560,7 @@ EXPORT_SYMBOL_GPL(clk_enable);
  * @clk: the clk whose rate is being returned
  *
  * Simply returns the cached rate of the clk.  Does not query the hardware.  If
- * clk is NULL then returns -EINVAL.
+ * clk is NULL then returns 0.
  */
 unsigned long clk_get_rate(struct clk *clk)
 {
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 06/13] clk: remove unnecessary EXPORT_SYMBOL_GPL

2012-04-11 Thread Mike Turquette
From: Shawn Guo shawn@linaro.org

It makes no sense to have EXPORT_SYMBOL_GPL on static functions.

Signed-off-by: Shawn Guo shawn@linaro.org
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk-divider.c|3 ---
 drivers/clk/clk-fixed-rate.c |1 -
 drivers/clk/clk-gate.c   |3 ---
 drivers/clk/clk-mux.c|2 --
 4 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index d5ac6a7..231cd6e 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -45,7 +45,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw 
*hw,
 
return parent_rate / div;
 }
-EXPORT_SYMBOL_GPL(clk_divider_recalc_rate);
 
 /*
  * The reverse of DIV_ROUND_UP: The maximum number which
@@ -117,7 +116,6 @@ static long clk_divider_round_rate(struct clk_hw *hw, 
unsigned long rate,
return r / div;
}
 }
-EXPORT_SYMBOL_GPL(clk_divider_round_rate);
 
 static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate)
 {
@@ -147,7 +145,6 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned 
long rate)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(clk_divider_set_rate);
 
 struct clk_ops clk_divider_ops = {
.recalc_rate = clk_divider_recalc_rate,
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 90c79fb..651b06f 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -32,7 +32,6 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw 
*hw,
 {
return to_clk_fixed_rate(hw)-fixed_rate;
 }
-EXPORT_SYMBOL_GPL(clk_fixed_rate_recalc_rate);
 
 struct clk_ops clk_fixed_rate_ops = {
.recalc_rate = clk_fixed_rate_recalc_rate,
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index b5902e2..b688f47 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -71,7 +71,6 @@ static int clk_gate_enable(struct clk_hw *hw)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(clk_gate_enable);
 
 static void clk_gate_disable(struct clk_hw *hw)
 {
@@ -82,7 +81,6 @@ static void clk_gate_disable(struct clk_hw *hw)
else
clk_gate_clear_bit(gate);
 }
-EXPORT_SYMBOL_GPL(clk_gate_disable);
 
 static int clk_gate_is_enabled(struct clk_hw *hw)
 {
@@ -99,7 +97,6 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
 
return reg ? 1 : 0;
 }
-EXPORT_SYMBOL_GPL(clk_gate_is_enabled);
 
 struct clk_ops clk_gate_ops = {
.enable = clk_gate_enable,
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 50e0595..45cad61 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -55,7 +55,6 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
 
return val;
 }
-EXPORT_SYMBOL_GPL(clk_mux_get_parent);
 
 static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
@@ -82,7 +81,6 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(clk_mux_set_parent);
 
 struct clk_ops clk_mux_ops = {
.get_parent = clk_mux_get_parent,
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 11/13] clk: Constify parent name arrays

2012-04-11 Thread Mike Turquette
From: Mark Brown broo...@opensource.wolfsonmicro.com

Drivers should be able to declare their arrays of parent names as const
so the APIs need to accept const arguments.

Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
[mturque...@linaro.org: constified gate]
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk-mux.c|2 +-
 drivers/clk/clk.c|2 +-
 include/linux/clk-private.h  |2 +-
 include/linux/clk-provider.h |8 
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 5424488..bd5e598 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -89,7 +89,7 @@ const struct clk_ops clk_mux_ops = {
 EXPORT_SYMBOL_GPL(clk_mux_ops);
 
 struct clk *clk_register_mux(struct device *dev, const char *name,
-   char **parent_names, u8 num_parents, unsigned long flags,
+   const char **parent_names, u8 num_parents, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock)
 {
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a24b121..ddade87 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1328,7 +1328,7 @@ out:
  */
 struct clk *clk_register(struct device *dev, const char *name,
const struct clk_ops *ops, struct clk_hw *hw,
-   char **parent_names, u8 num_parents, unsigned long flags)
+   const char **parent_names, u8 num_parents, unsigned long flags)
 {
struct clk *clk;
 
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index f19fee0..e9c8b98 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -30,7 +30,7 @@ struct clk {
const struct clk_ops*ops;
struct clk_hw   *hw;
struct clk  *parent;
-   char**parent_names;
+   const char  **parent_names;
struct clk  **parents;
u8  num_parents;
unsigned long   rate;
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 6eb8e5d..8981435 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -176,7 +176,7 @@ struct clk_gate {
u8  bit_idx;
u8  flags;
spinlock_t  *lock;
-   char*parent[1];
+   const char  *parent[1];
 };
 
 #define CLK_GATE_SET_TO_DISABLEBIT(0)
@@ -214,7 +214,7 @@ struct clk_divider {
u8  width;
u8  flags;
spinlock_t  *lock;
-   char*parent[1];
+   const char  *parent[1];
 };
 
 #define CLK_DIVIDER_ONE_BASED  BIT(0)
@@ -257,7 +257,7 @@ struct clk_mux {
 
 extern const struct clk_ops clk_mux_ops;
 struct clk *clk_register_mux(struct device *dev, const char *name,
-   char **parent_names, u8 num_parents, unsigned long flags,
+   const char **parent_names, u8 num_parents, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock);
 
@@ -278,7 +278,7 @@ struct clk *clk_register_mux(struct device *dev, const char 
*name,
  */
 struct clk *clk_register(struct device *dev, const char *name,
const struct clk_ops *ops, struct clk_hw *hw,
-   char **parent_names, u8 num_parents, unsigned long flags);
+   const char **parent_names, u8 num_parents, unsigned long flags);
 
 /* helper functions */
 const char *__clk_get_name(struct clk *clk);
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 00/13] common clk framework misc fixes

2012-04-11 Thread Mike Turquette
This series collects many of the fixes posted for the recently merged
common clock framework as well as some general clean-up.  Most of the
code classifies as a clean-up moreso than a bug fix; hopefully this is
not a problem since the common clk framework is new code pulled for 3.4.

Patches are based on v3.4-rc2 and can be pulled from:
git://git.linaro.org/people/mturquette/linux.git v3.4-rc2-clk-fixes

Please let me know I missed any critical fixes that were posted to the
list already.

Arnd  Olof, if there are no objections to these changes can this get
pulled through the arm-soc tree?

Thanks,
Mike

Mark Brown (2):
  clk: Remove comment for end of CONFIG_COMMON_CLK section
  clk: Constify parent name arrays

Mike Turquette (6):
  clk: core: correct clk_set_rate kerneldoc
  clk: core: remove dead code paths
  clk: core: clk_calc_new_rates handles NULL parents
  clk: core: enforce clk_ops consistency
  clk: core: copy parent_names  return error codes
  clk: basic: improve parent_names  return errors

Rajendra Nayak (1):
  clk: Make clk_get_rate() return 0 on error

Shawn Guo (4):
  clk: use kzalloc in clk_register_mux
  clk: remove unnecessary EXPORT_SYMBOL_GPL
  clk: add const for clk_ops of basic clks
  clk: declare clk_ops of basic clks in clk-provider.h

 drivers/clk/clk-divider.c|   51 +
 drivers/clk/clk-fixed-rate.c |   57 +--
 drivers/clk/clk-gate.c   |   53 ++-
 drivers/clk/clk-mux.c|   16 +++--
 drivers/clk/clk.c|  159 ++---
 include/linux/clk-private.h  |   14 +---
 include/linux/clk-provider.h |   13 ++--
 include/linux/clk.h  |2 +-
 8 files changed, 230 insertions(+), 135 deletions(-)

-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 04/13] clk: core: enforce clk_ops consistency

2012-04-11 Thread Mike Turquette
Documentation/clk.txt has some handsome ASCII art outlining which
clk_ops are mandatory for a given clock, given the capability of the
hardware.  Enforce those mandates with sanity checks in __clk_init.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk.c |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d83a9e0..9924aec 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1202,6 +1202,20 @@ void __clk_init(struct device *dev, struct clk *clk)
if (__clk_lookup(clk-name))
goto out;
 
+   /* check that clk_ops are sane.  See Documentation/clk.txt */
+   if (clk-ops-set_rate 
+   !(clk-ops-round_rate  clk-ops-recalc_rate)) {
+   pr_warning(%s: %s must implement .round_rate  .recalc_rate\n,
+   __func__, clk-name);
+   goto out;
+   }
+
+   if (clk-ops-set_parent  !clk-ops-get_parent) {
+   pr_warning(%s: %s must implement .get_parent  .set_parent\n,
+   __func__, clk-name);
+   goto out;
+   }
+
/* throw a WARN if any entries in parent_names are NULL */
for (i = 0; i  clk-num_parents; i++)
WARN(!clk-parent_names[i],
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 07/13] clk: add const for clk_ops of basic clks

2012-04-11 Thread Mike Turquette
From: Shawn Guo shawn@linaro.org

The clk_ops of basic clks should have const to match the definition
in struct clk and clk_register prototype.

Signed-off-by: Shawn Guo shawn@linaro.org
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk-divider.c|2 +-
 drivers/clk/clk-fixed-rate.c |2 +-
 drivers/clk/clk-gate.c   |2 +-
 drivers/clk/clk-mux.c|2 +-
 include/linux/clk-private.h  |8 
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 231cd6e..b1c4b02 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -146,7 +146,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned 
long rate)
return 0;
 }
 
-struct clk_ops clk_divider_ops = {
+const struct clk_ops clk_divider_ops = {
.recalc_rate = clk_divider_recalc_rate,
.round_rate = clk_divider_round_rate,
.set_rate = clk_divider_set_rate,
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 651b06f..027e477 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -33,7 +33,7 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw 
*hw,
return to_clk_fixed_rate(hw)-fixed_rate;
 }
 
-struct clk_ops clk_fixed_rate_ops = {
+const struct clk_ops clk_fixed_rate_ops = {
.recalc_rate = clk_fixed_rate_recalc_rate,
 };
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index b688f47..fe2ff9e 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -98,7 +98,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
return reg ? 1 : 0;
 }
 
-struct clk_ops clk_gate_ops = {
+const struct clk_ops clk_gate_ops = {
.enable = clk_gate_enable,
.disable = clk_gate_disable,
.is_enabled = clk_gate_is_enabled,
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 45cad61..5424488 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -82,7 +82,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
return 0;
 }
 
-struct clk_ops clk_mux_ops = {
+const struct clk_ops clk_mux_ops = {
.get_parent = clk_mux_get_parent,
.set_parent = clk_mux_set_parent,
 };
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 5e4312b..5f4ccd7 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -55,7 +55,7 @@ struct clk {
  * alternative macro for static initialization
  */
 
-extern struct clk_ops clk_fixed_rate_ops;
+extern const struct clk_ops clk_fixed_rate_ops;
 
 #define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate,\
_fixed_rate_flags)  \
@@ -78,7 +78,7 @@ extern struct clk_ops clk_fixed_rate_ops;
.flags = _flags,\
};
 
-extern struct clk_ops clk_gate_ops;
+extern const struct clk_ops clk_gate_ops;
 
 #define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr,  \
_flags, _reg, _bit_idx, \
@@ -110,7 +110,7 @@ extern struct clk_ops clk_gate_ops;
.flags = _flags,\
};
 
-extern struct clk_ops clk_divider_ops;
+extern const struct clk_ops clk_divider_ops;
 
 #define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,   \
_flags, _reg, _shift, _width,   \
@@ -143,7 +143,7 @@ extern struct clk_ops clk_divider_ops;
.flags = _flags,\
};
 
-extern struct clk_ops clk_mux_ops;
+extern const struct clk_ops clk_mux_ops;
 
 #define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags, \
_reg, _shift, _width,   \
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 13/13] clk: basic: improve parent_names return errors

2012-04-11 Thread Mike Turquette
This patch is the basic clk version of 'clk: core: copy parent_names 
return error codes'.

The registration functions are changed to allow the core code to copy
the array of strings and allow platforms to declare those arrays as
__initdata.

This patch also converts all of the basic clk registration functions to
return error codes which better aligns them with the existing clk.h api.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk-divider.c|   46 ++-
 drivers/clk/clk-fixed-rate.c |   54 ++---
 drivers/clk/clk-gate.c   |   48 +++--
 drivers/clk/clk-mux.c|8 +-
 include/linux/clk-provider.h |2 -
 5 files changed, 110 insertions(+), 48 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index b1c4b02..add784b 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -153,16 +153,29 @@ const struct clk_ops clk_divider_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ops);
 
+/**
+ * clk_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
 struct clk *clk_register_divider(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, spinlock_t *lock)
 {
struct clk_divider *div;
-   struct clk *clk;
+   struct clk *clk = ERR_PTR(-ENOMEM);
+   const char *parent_names[1];
 
+   /* allocate the divider */
div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
-
if (!div) {
pr_err(%s: could not allocate divider clk\n, __func__);
return NULL;
@@ -175,23 +188,32 @@ struct clk *clk_register_divider(struct device *dev, 
const char *name,
div-flags = clk_divider_flags;
div-lock = lock;
 
+   /* allocate the temporary parent_names */
if (parent_name) {
-   div-parent[0] = kstrdup(parent_name, GFP_KERNEL);
-   if (!div-parent[0])
-   goto out;
+   parent_names[0] = kstrdup(parent_name, GFP_KERNEL);
+   if (!parent_names[0]) {
+   pr_err(%s: could not allocate parent_names\n,
+   __func__);
+   goto fail_parent_names;
+   }
}
 
+   /* register the clock */
clk = clk_register(dev, name,
clk_divider_ops, div-hw,
-   div-parent,
+   (parent_name ? parent_names: NULL),
(parent_name ? 1 : 0),
flags);
-   if (clk)
-   return clk;
 
-out:
-   kfree(div-parent[0]);
-   kfree(div);
+   /* free the temporary parent_names */
+   if (parent_name)
+   kfree(parent_names[0]);
+
+   if (!IS_ERR(clk))
+   goto out;
 
-   return NULL;
+fail_parent_names:
+   kfree(div);
+out:
+   return clk;
 }
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 027e477..ecd20ae 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -38,44 +38,58 @@ const struct clk_ops clk_fixed_rate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
 
+/**
+ * clk_register_fixed_rate - register fixed-rate clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate)
 {
struct clk_fixed_rate *fixed;
-   char **parent_names = NULL;
-   u8 len;
+   struct clk *clk = ERR_PTR(-ENOMEM);
+   const char *parent_names[1];
 
+   /* allocate fixed-rate clock */
fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
-
if (!fixed

[PATCH 08/13] clk: declare clk_ops of basic clks in clk-provider.h

2012-04-11 Thread Mike Turquette
From: Shawn Guo shawn@linaro.org

Besides the static initialization, the clk_ops of basic clks could
also be used by particular clk type being subclass of the basic clks.

For example, clk_busy_divider has the same clk_ops as clk_divider,
except it has to wait for a busy bit before return success with
.set_rate.  clk_busy_divider will somehow reuse clk_ops of clk_divider.

Since clk-provider.h is included by clk-private.h, it's safe to move
those clk_ops declaration of basic clks form  clk-private.h into
clk-provider.h, so that implementation of clks like clk_busy_divider
above do not need to include clk-private.h to access those clk_ops.

Signed-off-by: Shawn Guo shawn@linaro.org
Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 include/linux/clk-private.h  |8 
 include/linux/clk-provider.h |4 
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 5f4ccd7..f19fee0 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -55,8 +55,6 @@ struct clk {
  * alternative macro for static initialization
  */
 
-extern const struct clk_ops clk_fixed_rate_ops;
-
 #define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate,\
_fixed_rate_flags)  \
static struct clk _name;\
@@ -78,8 +76,6 @@ extern const struct clk_ops clk_fixed_rate_ops;
.flags = _flags,\
};
 
-extern const struct clk_ops clk_gate_ops;
-
 #define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr,  \
_flags, _reg, _bit_idx, \
_gate_flags, _lock) \
@@ -110,8 +106,6 @@ extern const struct clk_ops clk_gate_ops;
.flags = _flags,\
};
 
-extern const struct clk_ops clk_divider_ops;
-
 #define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,   \
_flags, _reg, _shift, _width,   \
_divider_flags, _lock)  \
@@ -143,8 +137,6 @@ extern const struct clk_ops clk_divider_ops;
.flags = _flags,\
};
 
-extern const struct clk_ops clk_mux_ops;
-
 #define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags, \
_reg, _shift, _width,   \
_mux_flags, _lock)  \
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 5508897..6eb8e5d 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -149,6 +149,7 @@ struct clk_fixed_rate {
u8  flags;
 };
 
+extern const struct clk_ops clk_fixed_rate_ops;
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate);
@@ -180,6 +181,7 @@ struct clk_gate {
 
 #define CLK_GATE_SET_TO_DISABLEBIT(0)
 
+extern const struct clk_ops clk_gate_ops;
 struct clk *clk_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
@@ -218,6 +220,7 @@ struct clk_divider {
 #define CLK_DIVIDER_ONE_BASED  BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO   BIT(1)
 
+extern const struct clk_ops clk_divider_ops;
 struct clk *clk_register_divider(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
@@ -252,6 +255,7 @@ struct clk_mux {
 #define CLK_MUX_INDEX_ONE  BIT(0)
 #define CLK_MUX_INDEX_BIT  BIT(1)
 
+extern const struct clk_ops clk_mux_ops;
 struct clk *clk_register_mux(struct device *dev, const char *name,
char **parent_names, u8 num_parents, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 12/13] clk: core: copy parent_names return error codes

2012-04-11 Thread Mike Turquette
This patch cleans up clk_register and solves a few bugs by teaching
clk_register and __clk_init to return error codes (instead of just NULL)
to better align with the existing clk.h api.

Along with that change this patch also introduces a new behavior whereby
clk_register copies the parent_names array, thus allowing platforms to
declare their parent_names arrays as __initdata.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Olof Johansson o...@lixom.net
Cc: Russell King li...@arm.linux.org.uk
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Andrew Lunn and...@lunn.ch
Cc: Rajendra Nayak rna...@ti.com
Cc: Viresh Kumar viresh.ku...@st.com
---
 drivers/clk/clk.c|   61 +
 include/linux/clk-private.h  |4 ++-
 include/linux/clk-provider.h |3 +-
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ddade87..af2bf12 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1185,34 +1185,41 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
  * very large numbers of clocks that need to be statically initialized.  It is
  * a layering violation to include clk-private.h from any code which implements
  * a clock's .ops; as such any statically initialized clock data MUST be in a
- * separate C file from the logic that implements it's operations.
+ * separate C file from the logic that implements it's operations.  Returns 0
+ * on success, otherwise an error code.
  */
-void __clk_init(struct device *dev, struct clk *clk)
+int __clk_init(struct device *dev, struct clk *clk)
 {
-   int i;
+   int i, ret = 0;
struct clk *orphan;
struct hlist_node *tmp, *tmp2;
 
if (!clk)
-   return;
+   return -EINVAL;
 
mutex_lock(prepare_lock);
 
/* check to see if a clock with this name is already registered */
-   if (__clk_lookup(clk-name))
+   if (__clk_lookup(clk-name)) {
+   pr_debug(%s: clk %s already initialized\n,
+   __func__, clk-name);
+   ret = -EEXIST;
goto out;
+   }
 
/* check that clk_ops are sane.  See Documentation/clk.txt */
if (clk-ops-set_rate 
!(clk-ops-round_rate  clk-ops-recalc_rate)) {
pr_warning(%s: %s must implement .round_rate  .recalc_rate\n,
__func__, clk-name);
+   ret = -EINVAL;
goto out;
}
 
if (clk-ops-set_parent  !clk-ops-get_parent) {
pr_warning(%s: %s must implement .get_parent  .set_parent\n,
__func__, clk-name);
+   ret = -EINVAL;
goto out;
}
 
@@ -1308,7 +1315,7 @@ void __clk_init(struct device *dev, struct clk *clk)
 out:
mutex_unlock(prepare_lock);
 
-   return;
+   return ret;
 }
 
 /**
@@ -1324,29 +1331,59 @@ out:
  * clk_register is the primary interface for populating the clock tree with new
  * clock nodes.  It returns a pointer to the newly allocated struct clk which
  * cannot be dereferenced by driver code but may be used in conjuction with the
- * rest of the clock API.
+ * rest of the clock API.  In the event of an error clk_register will return an
+ * error code; drivers must test for an error code after calling clk_register.
  */
 struct clk *clk_register(struct device *dev, const char *name,
const struct clk_ops *ops, struct clk_hw *hw,
const char **parent_names, u8 num_parents, unsigned long flags)
 {
+   int i, ret = -ENOMEM;
struct clk *clk;
 
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
-   if (!clk)
-   return NULL;
+   if (!clk) {
+   pr_err(%s: could not allocate clk\n, __func__);
+   goto fail_out;
+   }
 
clk-name = name;
clk-ops = ops;
clk-hw = hw;
clk-flags = flags;
-   clk-parent_names = parent_names;
clk-num_parents = num_parents;
hw-clk = clk;
 
-   __clk_init(dev, clk);
+   /* allocate local copy in case parent_names is __initdata */
+   clk-parent_names = kzalloc((sizeof(char*) * num_parents),
+   GFP_KERNEL);
+
+   if (!clk-parent_names) {
+   pr_err(%s: could not allocate clk-parent_names\n, __func__);
+   goto fail_parent_names;
+   }
+
+   /* copy each string name in case parent_names is __initdata */
+   for (i = 0; i  num_parents; i++) {
+   clk-parent_names[i] = kstrdup(parent_names[i], GFP_KERNEL);
+   if (!clk-parent_names[i]) {
+   pr_err(%s: could not copy parent_names\n, __func__

[PATCH v7 3/3] clk: basic clock hardware types

2012-03-16 Thread Mike Turquette
Many platforms support simple gateable clocks, fixed-rate clocks,
adjustable divider clocks and multi-parent multiplexer clocks.

This patch introduces basic clock types for the above-mentioned hardware
which share some common characteristics.

Based on original work by Jeremy Kerr and contribution by Jamie Iles.
Dividers and multiplexor clocks originally contributed by Richard Zhao 
Sascha Hauer.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Reviewed-by: Andrew Lunn and...@lunn.ch
Tested-by: Andrew Lunn and...@lunn.ch
Reviewed-by: Rob Herring rob.herr...@calxeda.com
Cc: Russell King li...@arm.linux.org.uk
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Jamie Iles ja...@jamieiles.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
---
Changes since v6:
 * fixed up clk_divider's .round_rate logic (thanks Sascha)
 * removed useless locking around basic clock types

Changes since v5:
 * standardized the hw-specific locking in the basic clock types
 * export the individual ops for each basic clock type
 * improve registration for single-parent basic clocks (thanks Sascha)
 * fixed bugs in gate clock's static initializers (thanks Andrew)

 drivers/clk/Makefile |3 +-
 drivers/clk/clk-divider.c|  200 ++
 drivers/clk/clk-fixed-rate.c |   82 +
 drivers/clk/clk-gate.c   |  150 +++
 drivers/clk/clk-mux.c|  116 
 include/linux/clk-private.h  |  124 ++
 include/linux/clk-provider.h |  127 ++
 7 files changed, 801 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clk/clk-divider.c
 create mode 100644 drivers/clk/clk-fixed-rate.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-mux.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ff362c4..1f736bc 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,4 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
-obj-$(CONFIG_COMMON_CLK)   += clk.o
+obj-$(CONFIG_COMMON_CLK)   += clk.o clk-fixed-rate.o clk-gate.o \
+  clk-mux.o clk-divider.o
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
new file mode 100644
index 000..d5ac6a7
--- /dev/null
+++ b/drivers/clk/clk-divider.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix s.ha...@pengutronix.de
+ * Copyright (C) 2011 Richard Zhao, Linaro richard.z...@linaro.org
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Adjustable divider clock implementation
+ */
+
+#include linux/clk-provider.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+#include linux/string.h
+
+/*
+ * DOC: basic adjustable divider clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk-rate = parent-rate / divisor
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
+#define div_mask(d)((1  (d-width)) - 1)
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct clk_divider *divider = to_clk_divider(hw);
+   unsigned int div;
+
+   div = readl(divider-reg)  divider-shift;
+   div = div_mask(divider);
+
+   if (!(divider-flags  CLK_DIVIDER_ONE_BASED))
+   div++;
+
+   return parent_rate / div;
+}
+EXPORT_SYMBOL_GPL(clk_divider_recalc_rate);
+
+/*
+ * The reverse of DIV_ROUND_UP: The maximum number which
+ * divided by m is r
+ */
+#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
+
+static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+   unsigned long *best_parent_rate)
+{
+   struct clk_divider *divider = to_clk_divider(hw);
+   int i, bestdiv = 0;
+   unsigned long parent_rate, best = 0, now, maxdiv;
+
+   if (!rate)
+   rate = 1;
+
+   maxdiv = (1  divider-width);
+
+   if (divider-flags

[PATCH v7 0/3] common clk framework

2012-03-16 Thread Mike Turquette
The common clock framework defines a common struct clk as well as an
implementation of the clk api that unifies clock operations on various
platforms and devices.

The net result is consolidation of many different struct clk definitions
and platform-specific clock framework implementations.

This series is the feature freeze for the common clock framework.
Unless any major bugs are reported this should be the final version of
this patchset.  Now is the time to add any acked-by's, reviewed-by's or
tested-by's.  I've carried over the *-by's from v6; I hope everyone is
OK with that.

Big thanks to Sascha Hauer for his changes to clk_set_rate in this
version.

Major changes since v6:
 * clk_set_rate rewritten to set clock rates from top-to-bottom
   * should also reduce pre-rate change notifier noise (thanks Sascha)
 * fixed up clk_divider's .round_rate logic (thanks Sascha)
 * removed useless locking around basic clock types
 * fixed return types for __clk_get_(enable|prepare)_count
 * some NULL pointer fixes for handling .parent_names and .parents
 * removed unnecessary checks for recursive calls in a few helpers
 * made __clk_round_rate more sane and aligned with clk_round_rate
   * parent rates are returned if .round_rate is not implemented
 * fixed CONFIG_COMMON_CLK_DEBUGFS to select DEBUG_FS
 * rebased onto Linus' v3.3-rc7 tag

Major changes since v5:
 * removed redundant HAVE_CLK_PREPARE in Kconfig
 * new CONFIG_COMMON_CLK_DISABLE_UNUSED feature
   * results in a new clk_op callback, .is_enabled
 * standardized the hw-specific locking in the basic clock types
 * export the individual ops for each basic clock type
 * improve registration for single-parent basic clocks (thanks Sascha)
 * fixed bugs in gate clock's static initializers (thanks Andrew)
 * overall improvements to Documentation/clk.txt
 * rebased onto Linus' v3.3-rc6 tag

Major changes since v4:
 * rolled in TGLX's comments on overall design.  We now have,
   * proper handling of root clocks and orphan clocks
   * multi-parent clocks are handled in the core
   * struct clk is shielded from struct clk_foo and vice versa
 * this is a return to the previous struct clk_hw design
 * split basic clock types out into separate files
 * split headers up by purpose
   * clk.h remains the driver-level interface
 * declarations for rate change notifiers are the only additions
   * clk-provider.h is primary header for implementing clock operations
   * clk-private.h allows for static initialization of clock data
 * validation and bug fixes
 * rebased onto Linus' v3.3-rc5 tag

Patches can be pulled from:
git://git.linaro.org/people/mturquette/linux.git v3.3-rc7-clkv7

v6 can be found at,
http://article.gmane.org/gmane.linux.kernel/1265022

v5 can be found at,
http://article.gmane.org/gmane.linux.kernel/1261472

v4 can be found at,
http://article.gmane.org/gmane.linux.linaro.devel/8896/

v3 can be found at,
http://article.gmane.org/gmane.linux.kernel/1218622

Mike Turquette (3):
  Documentation: common clk API
  clk: introduce the common clock framework
  clk: basic clock hardware types

 Documentation/clk.txt|  233 +++
 drivers/clk/Kconfig  |   40 ++
 drivers/clk/Makefile |2 +
 drivers/clk/clk-divider.c|  200 ++
 drivers/clk/clk-fixed-rate.c |   82 +++
 drivers/clk/clk-gate.c   |  150 +
 drivers/clk/clk-mux.c|  116 
 drivers/clk/clk.c| 1461 ++
 include/linux/clk-private.h  |  196 ++
 include/linux/clk-provider.h |  300 +
 include/linux/clk.h  |   68 ++-
 11 files changed, 2843 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/clk.txt
 create mode 100644 drivers/clk/clk-divider.c
 create mode 100644 drivers/clk/clk-fixed-rate.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-mux.c
 create mode 100644 drivers/clk/clk.c
 create mode 100644 include/linux/clk-private.h
 create mode 100644 include/linux/clk-provider.h

-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v7 1/3] Documentation: common clk API

2012-03-16 Thread Mike Turquette
Provide documentation for the common clk structures and APIs.  This code
can be found in drivers/clk/ and include/linux/clk*.h.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Reviewed-by: Andrew Lunn and...@lunn.ch
Cc: Russell King li...@arm.linux.org.uk
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
---
No changes since v6

Changes since v5:
 * __clk_init must be called for statically initialized clocks
 * added clk_ops matrix to better clarify which ops are mandatory

 Documentation/clk.txt |  233 +
 1 files changed, 233 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/clk.txt

diff --git a/Documentation/clk.txt b/Documentation/clk.txt
new file mode 100644
index 000..1943fae
--- /dev/null
+++ b/Documentation/clk.txt
@@ -0,0 +1,233 @@
+   The Common Clk Framework
+   Mike Turquette mturque...@ti.com
+
+This document endeavours to explain the common clk framework details,
+and how to port a platform over to this framework.  It is not yet a
+detailed explanation of the clock api in include/linux/clk.h, but
+perhaps someday it will include that information.
+
+   Part 1 - introduction and interface split
+
+The common clk framework is an interface to control the clock nodes
+available on various devices today.  This may come in the form of clock
+gating, rate adjustment, muxing or other operations.  This framework is
+enabled with the CONFIG_COMMON_CLK option.
+
+The interface itself is divided into two halves, each shielded from the
+details of its counterpart.  First is the common definition of struct
+clk which unifies the framework-level accounting and infrastructure that
+has traditionally been duplicated across a variety of platforms.  Second
+is a common implementation of the clk.h api, defined in
+drivers/clk/clk.c.  Finally there is struct clk_ops, whose operations
+are invoked by the clk api implementation.
+
+The second half of the interface is comprised of the hardware-specific
+callbacks registered with struct clk_ops and the corresponding
+hardware-specific structures needed to model a particular clock.  For
+the remainder of this document any reference to a callback in struct
+clk_ops, such as .enable or .set_rate, implies the hardware-specific
+implementation of that code.  Likewise, references to struct clk_foo
+serve as a convenient shorthand for the implementation of the
+hardware-specific bits for the hypothetical foo hardware.
+
+Tying the two halves of this interface together is struct clk_hw, which
+is defined in struct clk_foo and pointed to within struct clk.  This
+allows easy for navigation between the two discrete halves of the common
+clock interface.
+
+   Part 2 - common data structures and api
+
+Below is the common struct clk definition from
+include/linux/clk-private.h, modified for brevity:
+
+   struct clk {
+   const char  *name;
+   const struct clk_ops*ops;
+   struct clk_hw   *hw;
+   char**parent_names;
+   struct clk  **parents;
+   struct clk  *parent;
+   struct hlist_head   children;
+   struct hlist_node   child_node;
+   ...
+   };
+
+The members above make up the core of the clk tree topology.  The clk
+api itself defines several driver-facing functions which operate on
+struct clk.  That api is documented in include/linux/clk.h.
+
+Platforms and devices utilizing the common struct clk use the struct
+clk_ops pointer in struct clk to perform the hardware-specific parts of
+the operations defined in clk.h:
+
+   struct clk_ops {
+   int (*prepare)(struct clk_hw *hw);
+   void(*unprepare)(struct clk_hw *hw);
+   int (*enable)(struct clk_hw *hw);
+   void(*disable)(struct clk_hw *hw);
+   int (*is_enabled)(struct clk_hw *hw);
+   unsigned long   (*recalc_rate)(struct clk_hw *hw,
+   unsigned long parent_rate);
+   long(*round_rate)(struct clk_hw *hw, unsigned long,
+   unsigned long

[PATCH v6 0/3] common clk framework

2012-03-09 Thread Mike Turquette
The common clock framework defines a common struct clk as well as an
implementation of the clk api that unifies clock operations on various
platforms and devices.

The net result is consolidation of many different struct clk definitions
and platform-specific clock framework implementations.

Thanks to Sascha Hauer and Andrew Lunn for their great review and
feedback on the previous v5 series.

Major changes since v5:
 * removed redundant HAVE_CLK_PREPARE in Kconfig
 * new CONFIG_COMMON_CLK_DISABLE_UNUSED feature
  * results in a new clk_op callback, .is_enabled
 * standardized the hw-specific locking in the basic clock types
 * export the individual ops for each basic clock type
 * improve registration for single-parent basic clocks (thanks Sascha)
 * fixed bugs in gate clock's static initializers (thanks Andrew)
 * overall improvements to Documentation/clk.txt
 * rebased onto Linus' v3.3-rc6 tag

Major changes since v4:
 * rolled in TGLX's comments on overall design.  We now have,
   * proper handling of root clocks and orphan clocks
   * multi-parent clocks are handled in the core
   * struct clk is shielded from struct clk_foo and vice versa
 * this is a return to the previous struct clk_hw design
 * split basic clock types out into separate files
 * split headers up by purpose
   * clk.h remains the driver-level interface
 * declarations for rate change notifiers are the only additions
   * clk-provider.h is primary header for implementing clock operations
   * clk-private.h allows for static initialization of clock data
 * validation and bug fixes
 * rebased onto Linus' v3.3-rc5 tag

Patches can be pulled from:
git://git.linaro.org/people/mturquette/linux.git v3.3-rc6-clkv6

v5 can be found at,
http://article.gmane.org/gmane.linux.kernel/1261472

v4 can be found at,
http://article.gmane.org/gmane.linux.linaro.devel/8896/

v3 can be found at,
http://article.gmane.org/gmane.linux.kernel/1218622

Mike Turquette (3):
  Documentation: common clk API
  clk: introduce the common clock framework
  clk: basic clock hardware types

 Documentation/clk.txt|  233 +++
 drivers/clk/Kconfig  |   39 ++
 drivers/clk/Makefile |2 +
 drivers/clk/clk-divider.c|  204 ++
 drivers/clk/clk-fixed-rate.c |   82 +++
 drivers/clk/clk-gate.c   |  157 +
 drivers/clk/clk-mux.c|  123 
 drivers/clk/clk.c| 1424 ++
 include/linux/clk-private.h  |  192 ++
 include/linux/clk-provider.h |  298 +
 include/linux/clk.h  |   68 ++-
 11 files changed, 2817 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/clk.txt
 create mode 100644 drivers/clk/clk-divider.c
 create mode 100644 drivers/clk/clk-fixed-rate.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-mux.c
 create mode 100644 drivers/clk/clk.c
 create mode 100644 include/linux/clk-private.h
 create mode 100644 include/linux/clk-provider.h

-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v6 1/3] Documentation: common clk API

2012-03-09 Thread Mike Turquette
Provide documentation for the common clk structures and APIs.  This code
can be found in drivers/clk/ and include/linux/clk*.h.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Cc: Russell King li...@arm.linux.org.uk
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
Changes since v5:
 * __clk_init must be called for statically initialized clocks
 * added clk_ops matrix to better clarify which ops are mandatory

 Documentation/clk.txt |  233 +
 1 files changed, 233 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/clk.txt

diff --git a/Documentation/clk.txt b/Documentation/clk.txt
new file mode 100644
index 000..1943fae
--- /dev/null
+++ b/Documentation/clk.txt
@@ -0,0 +1,233 @@
+   The Common Clk Framework
+   Mike Turquette mturque...@ti.com
+
+This document endeavours to explain the common clk framework details,
+and how to port a platform over to this framework.  It is not yet a
+detailed explanation of the clock api in include/linux/clk.h, but
+perhaps someday it will include that information.
+
+   Part 1 - introduction and interface split
+
+The common clk framework is an interface to control the clock nodes
+available on various devices today.  This may come in the form of clock
+gating, rate adjustment, muxing or other operations.  This framework is
+enabled with the CONFIG_COMMON_CLK option.
+
+The interface itself is divided into two halves, each shielded from the
+details of its counterpart.  First is the common definition of struct
+clk which unifies the framework-level accounting and infrastructure that
+has traditionally been duplicated across a variety of platforms.  Second
+is a common implementation of the clk.h api, defined in
+drivers/clk/clk.c.  Finally there is struct clk_ops, whose operations
+are invoked by the clk api implementation.
+
+The second half of the interface is comprised of the hardware-specific
+callbacks registered with struct clk_ops and the corresponding
+hardware-specific structures needed to model a particular clock.  For
+the remainder of this document any reference to a callback in struct
+clk_ops, such as .enable or .set_rate, implies the hardware-specific
+implementation of that code.  Likewise, references to struct clk_foo
+serve as a convenient shorthand for the implementation of the
+hardware-specific bits for the hypothetical foo hardware.
+
+Tying the two halves of this interface together is struct clk_hw, which
+is defined in struct clk_foo and pointed to within struct clk.  This
+allows easy for navigation between the two discrete halves of the common
+clock interface.
+
+   Part 2 - common data structures and api
+
+Below is the common struct clk definition from
+include/linux/clk-private.h, modified for brevity:
+
+   struct clk {
+   const char  *name;
+   const struct clk_ops*ops;
+   struct clk_hw   *hw;
+   char**parent_names;
+   struct clk  **parents;
+   struct clk  *parent;
+   struct hlist_head   children;
+   struct hlist_node   child_node;
+   ...
+   };
+
+The members above make up the core of the clk tree topology.  The clk
+api itself defines several driver-facing functions which operate on
+struct clk.  That api is documented in include/linux/clk.h.
+
+Platforms and devices utilizing the common struct clk use the struct
+clk_ops pointer in struct clk to perform the hardware-specific parts of
+the operations defined in clk.h:
+
+   struct clk_ops {
+   int (*prepare)(struct clk_hw *hw);
+   void(*unprepare)(struct clk_hw *hw);
+   int (*enable)(struct clk_hw *hw);
+   void(*disable)(struct clk_hw *hw);
+   int (*is_enabled)(struct clk_hw *hw);
+   unsigned long   (*recalc_rate)(struct clk_hw *hw,
+   unsigned long parent_rate);
+   long(*round_rate)(struct clk_hw *hw, unsigned long,
+   unsigned long *);
+   int

[PATCH v6 2/3] clk: introduce the common clock framework

2012-03-09 Thread Mike Turquette
The common clock framework defines a common struct clk useful across
most platforms as well as an implementation of the clk api that drivers
can use safely for managing clocks.

The net result is consolidation of many different struct clk definitions
and platform-specific clock framework implementations.

This patch introduces the common struct clk, struct clk_ops and an
implementation of the well-known clock api in include/clk/clk.h.
Platforms may define their own hardware-specific clock structure and
their own clock operation callbacks, so long as it wraps an instance of
struct clk_hw.

See Documentation/clk.txt for more details.

This patch is based on the work of Jeremy Kerr, which in turn was based
on the work of Ben Herrenschmidt.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Cc: Russell King li...@arm.linux.org.uk
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
Changes since v5:
 * new CONFIG_COMMON_CLK_DISABLE_UNUSED feature
  * results in a new clk_op callback, .is_enabled
 * new helpers
  * __clk_get_prepare_count
  * __clk_get_enable_count
  * __clk_is_enabled
 * fix bug in __clk_get_rate for orphan clocks

 drivers/clk/Kconfig  |   39 ++
 drivers/clk/Makefile |1 +
 drivers/clk/clk.c| 1424 ++
 include/linux/clk-private.h  |   68 ++
 include/linux/clk-provider.h |  171 +
 include/linux/clk.h  |   68 ++-
 6 files changed, 1766 insertions(+), 5 deletions(-)
 create mode 100644 drivers/clk/clk.c
 create mode 100644 include/linux/clk-private.h
 create mode 100644 include/linux/clk-provider.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9b3cd08..31ceb27 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -8,3 +8,42 @@ config HAVE_CLK_PREPARE
 
 config HAVE_MACH_CLKDEV
bool
+
+menuconfig COMMON_CLK
+   bool Common Clock Framework
+   select HAVE_CLK_PREPARE
+   ---help---
+ The common clock framework is a single definition of struct
+ clk, useful across many platforms, as well as an
+ implementation of the clock API in include/linux/clk.h.
+ Architectures utilizing the common struct clk should select
+ this automatically, but it may be necessary to manually select
+ this option for loadable modules requiring the common clock
+ framework.
+
+ If in doubt, say N.
+
+if COMMON_CLK
+
+config COMMON_CLK_DISABLE_UNUSED
+   bool Disabled unused clocks at boot
+   depends on COMMON_CLK
+   ---help---
+ Traverses the entire clock tree and disables any clocks that are
+ enabled in hardware but have not been enabled by any device drivers.
+ This saves power and keeps the software model of the clock in line
+ with reality.
+
+ If in doubt, say N.
+
+config COMMON_CLK_DEBUG
+   bool DebugFS representation of clock tree
+   depends on COMMON_CLK
+   ---help---
+ Creates a directory hierchy in debugfs for visualizing the clk
+ tree structure.  Each directory contains read-only members
+ that export information specific to that clk node: clk_rate,
+ clk_flags, clk_prepare_count, clk_enable_count 
+ clk_notifier_count.
+
+endif
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 07613fa..ff362c4 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
+obj-$(CONFIG_COMMON_CLK)   += clk.o
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
new file mode 100644
index 000..c7c3bc5
--- /dev/null
+++ b/drivers/clk/clk.c
@@ -0,0 +1,1424 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.com
+ * Copyright (C) 2011-2012 Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Standard functionality for the common clock API.  See Documentation/clk.txt
+ */
+
+#include linux/clk-private.h
+#include linux/module.h
+#include linux/mutex.h
+#include linux/spinlock.h
+#include linux/err.h
+#include linux/list.h
+#include linux/slab.h
+
+static DEFINE_SPINLOCK(enable_lock

[PATCH v6 3/3] clk: basic clock hardware types

2012-03-09 Thread Mike Turquette
Many platforms support simple gateable clocks, fixed-rate clocks,
adjustable divider clocks and multi-parent multiplexer clocks.

This patch introduces basic clock types for the above-mentioned hardware
which share some common characteristics.

Based on original work by Jeremy Kerr and contribution by Jamie Iles.
Dividers and multiplexor clocks originally contributed by Richard Zhao 
Sascha Hauer.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Cc: Russell King li...@arm.linux.org.uk
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Jamie Iles ja...@jamieiles.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
Changes since v5:
 * standardized the hw-specific locking in the basic clock types
 * export the individual ops for each basic clock type
 * improve registration for single-parent basic clocks (thanks Sascha)
 * fixed bugs in gate clock's static initializers (thanks Andrew)

 drivers/clk/Makefile |3 +-
 drivers/clk/clk-divider.c|  204 ++
 drivers/clk/clk-fixed-rate.c |   82 +
 drivers/clk/clk-gate.c   |  157 
 drivers/clk/clk-mux.c|  123 +
 include/linux/clk-private.h  |  124 +
 include/linux/clk-provider.h |  127 ++
 7 files changed, 819 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clk/clk-divider.c
 create mode 100644 drivers/clk/clk-fixed-rate.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-mux.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ff362c4..1f736bc 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,4 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
-obj-$(CONFIG_COMMON_CLK)   += clk.o
+obj-$(CONFIG_COMMON_CLK)   += clk.o clk-fixed-rate.o clk-gate.o \
+  clk-mux.o clk-divider.o
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
new file mode 100644
index 000..c0c4e0b
--- /dev/null
+++ b/drivers/clk/clk-divider.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix s.ha...@pengutronix.de
+ * Copyright (C) 2011 Richard Zhao, Linaro richard.z...@linaro.org
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Adjustable divider clock implementation
+ */
+
+#include linux/clk-provider.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+#include linux/string.h
+
+/*
+ * DOC: basic adjustable divider clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk-rate = parent-rate / divisor
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct clk_divider *divider = to_clk_divider(hw);
+   unsigned int div;
+   unsigned long flags = 0;
+
+   if (divider-lock)
+   spin_lock_irqsave(divider-lock, flags);
+
+   div = readl(divider-reg)  divider-shift;
+   div = (1  divider-width) - 1;
+
+   if (divider-lock)
+   spin_unlock_irqrestore(divider-lock, flags);
+
+   if (!(divider-flags  CLK_DIVIDER_ONE_BASED))
+   div++;
+
+   return parent_rate / div;
+}
+EXPORT_SYMBOL_GPL(clk_divider_recalc_rate);
+
+static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+   unsigned long *best_parent_rate)
+{
+   struct clk_divider *divider = to_clk_divider(hw);
+   int i, bestdiv = 0;
+   unsigned long parent_rate, best = 0, now, maxdiv;
+
+   maxdiv = (1  divider-width);
+
+   if (divider-flags  CLK_DIVIDER_ONE_BASED)
+   maxdiv--;
+
+   if (!(__clk_get_flags(hw-clk)  CLK_SET_RATE_PARENT)) {
+   parent_rate = __clk_get_rate(__clk_get_parent(hw-clk));
+   bestdiv

[PATCH v5 1/4] Documentation: common clk API

2012-03-03 Thread Mike Turquette
Provide documentation for the common clk structures and APIs.  This code
can be found in drivers/clk/ and include/linux/clk*.h.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
 Documentation/clk.txt |  201 +
 1 files changed, 201 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/clk.txt

diff --git a/Documentation/clk.txt b/Documentation/clk.txt
new file mode 100644
index 000..d4db278
--- /dev/null
+++ b/Documentation/clk.txt
@@ -0,0 +1,201 @@
+   The Common Clk Framework
+   Mike Turquette mturque...@ti.com
+
+This document endeavours to explain the common clk framework details,
+and how to port a platform over to this framework.  It is not yet a
+detailed explanation of the clock api in include/linux/clk.h, but
+perhaps someday it will include that information.
+
+   Part 1 - introduction and interface split
+
+The common clk framework is an interface to control the clock nodes
+available on various devices today.  This may come in the form of clock
+gating, rate adjustment, muxing or other operations.  This framework is
+enabled with the CONFIG_COMMON_CLK option.
+
+The interface itself is divided into two halves, each shielded from the
+details of its counterpart.  First is the common definition of struct
+clk which attempts to unify the framework-level accounting and
+infrastructure that has traditionally been replicated across a variety of
+platforms.  This includes a top-level implementation of the clk.h api,
+defined in drivers/clk/clk.c.  The definition of struct clk_ops, whose
+operations are invoked by the clk api implementation, rounds out the
+first half the interface.
+
+The second half of the interface is comprised of the hardware-specific 
callbacks
+registered with struct clk_ops and the corresponding hardware-specific
+structures needed to model a particular clock.  For the remainder of this
+document any reference to a callback in struct clk_ops, such as .enable
+or .set_rate, implies the hardware-specific implementation of that code.
+Likewise references to struct clk_foo are a convenient shorthand for the
+hypothetical implementation of the clocks in the wildly popular foo
+hardware.
+
+Tying the two halves of this interface together is struct clk_hw, which is
+defined in struct clk_foo and pointed to within struct clk.  This allows easy
+navigaton between the two.
+
+   Part 2 - common data structures and api
+
+Below is the common struct clk definition from include/linux/clk.h, modified 
for brevity:
+
+   struct clk {
+   const char  *name;
+   const struct clk_ops*ops;
+   struct clk_hw   *hw;
+   char**parent_names;
+   struct clk  **parents;
+   struct clk  *parent;
+   struct hlist_head   children;
+   struct hlist_node   child_node;
+   ...
+   };
+
+The members above make up the core of the clk tree topology.  The clk
+api itself defines several driver-facing functions which operate on
+struct clk.  That api is documented in include/linux/clk.h.
+
+Platforms and devices utilizing the common struct clk use the struct
+clk_ops pointer in struct clk to perform the hardware-specific parts of
+the operations defined in clk.h:
+
+   struct clk_ops {
+   int (*prepare)(struct clk_hw *hw);
+   void(*unprepare)(struct clk_hw *hw);
+   int (*enable)(struct clk_hw *hw);
+   void(*disable)(struct clk_hw *hw);
+   unsigned long   (*recalc_rate)(struct clk_hw *hw,
+   unsigned long parent_rate);
+   long(*round_rate)(struct clk_hw *hw, unsigned long,
+   unsigned long *);
+   int (*set_parent)(struct clk_hw *hw, u8 index);
+   u8  (*get_parent)(struct clk_hw *hw);
+   int (*set_rate)(struct clk_hw *hw, unsigned long);
+   void(*init)(struct clk_hw *hw);
+   };
+
+   Part 3 - hardware clk

[PATCH v5 2/4] clk: Kconfig: add entry for HAVE_CLK_PREPARE

2012-03-03 Thread Mike Turquette
The common clk framework provides clk_prepare and clk_unprepare
implementations.  Create an entry for HAVE_CLK_PREPARE so that
COMMON_CLK can select it.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Acked-by: Shawn Guo shawn@linaro.org
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
 drivers/clk/Kconfig |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9b3cd08..3912576 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -8,3 +8,6 @@ config HAVE_CLK_PREPARE
 
 config HAVE_MACH_CLKDEV
bool
+
+config HAVE_CLK_PREPARE
+   bool
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v5 0/4] common clk framework

2012-03-03 Thread Mike Turquette
From: Mike Turquette mturque...@ti.com

The common clock framework defines a common struct clk as well as an
implementation of the clk api that unifies clock operations on various
platforms and devices.

The net result is consolidation of many different struct clk definitions
and platform-specific clock framework implementations.

I consider this version merge-worthy pending ACKs from the relevant
maintainers; namely Russell, Thomas and the platform folks interested in
porting to this framework.

I would like to thank everyone who participated in the common clk
sessions at Linaro Connect and ELC; the feedback was invaluable.

Also I would like to thank Shawn Guo, Richard Zhao, Saravana Kannan and
Magnus Damm for tirelessly updating their platforms for the last few
revisions of this patch series and providng excellent feedback each
time.

Major changes since v4:
 * rolled in TGLX's comments on overall design.  We now have,
   * proper handling of root clocks and orphan clocks
   * multi-parent clocks are handled in the core
   * struct clk is shielded from struct clk_foo and vice versa
 * this is a return to the previous struct clk_hw design
 * split basic clock types out into separate files
 * split headers up by purpose
   * clk.h remains the driver-level interface
 * declarations for rate change notifiers are the only additions
   * clk-provider.h is primary header for implementing clock operations
   * clk-private.h allows for static initialization of clock data
 * validation and bug fixes
 * rebased onto Linus' v3.3-rc5 tag

Patches can be pulled from:
git://git.linaro.org/people/mturquette/linux.git v3.3-rc5-clkv5

v4 can be found at,
http://article.gmane.org/gmane.linux.linaro.devel/8896/

v3 can be found at,
http://article.gmane.org/gmane.linux.kernel/1218622

Mike Turquette (4):
  Documentation: common clk API
  clk: Kconfig: add entry for HAVE_CLK_PREPARE
  clk: introduce the common clock framework
  clk: basic clock hardware types

 Documentation/clk.txt|  201 +++
 drivers/clk/Kconfig  |   31 +
 drivers/clk/Makefile |2 +
 drivers/clk/clk-divider.c|  199 +++
 drivers/clk/clk-fixed-rate.c |   81 +++
 drivers/clk/clk-gate.c   |  121 
 drivers/clk/clk-mux.c|  114 
 drivers/clk/clk.c| 1323 ++
 include/linux/clk-private.h  |  192 ++
 include/linux/clk-provider.h |  294 ++
 include/linux/clk.h  |   68 ++-
 11 files changed, 2621 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/clk.txt
 create mode 100644 drivers/clk/clk-divider.c
 create mode 100644 drivers/clk/clk-fixed-rate.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-mux.c
 create mode 100644 drivers/clk/clk.c
 create mode 100644 include/linux/clk-private.h
 create mode 100644 include/linux/clk-provider.h

Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch

-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v5 3/4] clk: introduce the common clock framework

2012-03-03 Thread Mike Turquette
The common clock framework defines a common struct clk useful across
most platforms as well as an implementation of the clk api that drivers
can use safely for managing clocks.

The net result is consolidation of many different struct clk definitions
and platform-specific clock framework implementations.

This patch introduces the common struct clk, struct clk_ops and an
implementation of the well-known clock api in include/clk/clk.h.
Platforms may define their own hardware-specific clock structure and
their own clock operation callbacks, so long as it wraps an instance of
struct clk_hw.

See Documentation/clk.txt for more details.

This patch is based on the work of Jeremy Kerr, which in turn was based
on the work of Ben Herrenschmidt.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
 drivers/clk/Kconfig  |   28 +
 drivers/clk/Makefile |1 +
 drivers/clk/clk.c| 1323 ++
 include/linux/clk-private.h  |   68 +++
 include/linux/clk-provider.h |  169 ++
 include/linux/clk.h  |   68 ++-
 6 files changed, 1652 insertions(+), 5 deletions(-)
 create mode 100644 drivers/clk/clk.c
 create mode 100644 include/linux/clk-private.h
 create mode 100644 include/linux/clk-provider.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3912576..18eb8c2 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -11,3 +11,31 @@ config HAVE_MACH_CLKDEV
 
 config HAVE_CLK_PREPARE
bool
+
+menuconfig COMMON_CLK
+   bool Common Clock Framework
+   select HAVE_CLK_PREPARE
+   ---help---
+ The common clock framework is a single definition of struct
+ clk, useful across many platforms, as well as an
+ implementation of the clock API in include/linux/clk.h.
+ Architectures utilizing the common struct clk should select
+ this automatically, but it may be necessary to manually select
+ this option for loadable modules requiring the common clock
+ framework.
+
+ If in doubt, say N.
+
+if COMMON_CLK
+
+config COMMON_CLK_DEBUG
+   bool DebugFS representation of clock tree
+   depends on COMMON_CLK
+   ---help---
+ Creates a directory hierchy in debugfs for visualizing the clk
+ tree structure.  Each directory contains read-only members
+ that export information specific to that clk node: clk_rate,
+ clk_flags, clk_prepare_count, clk_enable_count 
+ clk_notifier_count.
+
+endif
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 07613fa..ff362c4 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
+obj-$(CONFIG_COMMON_CLK)   += clk.o
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
new file mode 100644
index 000..b979d74
--- /dev/null
+++ b/drivers/clk/clk.c
@@ -0,0 +1,1323 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.com
+ * Copyright (C) 2011-2012 Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Standard functionality for the common clock API.  See Documentation/clk.txt
+ */
+
+#include linux/clk-private.h
+#include linux/module.h
+#include linux/mutex.h
+#include linux/spinlock.h
+#include linux/err.h
+#include linux/list.h
+#include linux/slab.h
+
+static DEFINE_SPINLOCK(enable_lock);
+static DEFINE_MUTEX(prepare_lock);
+
+static HLIST_HEAD(clk_root_list);
+static HLIST_HEAD(clk_orphan_list);
+static LIST_HEAD(clk_notifier_list);
+
+/***debugfs support***/
+
+#ifdef CONFIG_COMMON_CLK_DEBUG
+#include linux/debugfs.h
+
+static struct dentry *rootdir;
+static struct dentry *orphandir;
+static int inited = 0;
+
+/* caller must hold prepare_lock */
+static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
+{
+   struct dentry *d;
+   int ret = -ENOMEM;
+
+   if (!clk || !pdentry) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   d = debugfs_create_dir(clk-name, pdentry);
+   if (!d)
+   goto out;
+
+   clk-dentry = d;
+
+   d

[PATCH v5 4/4] clk: basic clock hardware types

2012-03-03 Thread Mike Turquette
Many platforms support simple gateable clocks, fixed-rate clocks,
adjustable divider clocks and multi-parent multiplexer clocks.

This patch introduces basic clock types for the above-mentioned hardware
which share some common characteristics.

Based on original work by Jeremy Kerr and contribution by Jamie Iles.
Dividers and multiplexor clocks originally contributed by Richard Zhao 
Sascha Hauer.

Signed-off-by: Mike Turquette mturque...@linaro.org
Signed-off-by: Mike Turquette mturque...@ti.com
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Arnd Bergman arnd.bergm...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
Cc: Shawn Guo shawn@freescale.com
Cc: Sascha Hauer s.ha...@pengutronix.de
Cc: Jamie Iles ja...@jamieiles.com
Cc: Richard Zhao richard.z...@linaro.org
Cc: Saravana Kannan skan...@codeaurora.org
Cc: Magnus Damm magnus.d...@gmail.com
Cc: Rob Herring rob.herr...@calxeda.com
Cc: Mark Brown broo...@opensource.wolfsonmicro.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Stephen Boyd sb...@codeaurora.org
Cc: Amit Kucheria amit.kuche...@linaro.org
Cc: Deepak Saxena dsax...@linaro.org
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Andrew Lunn and...@lunn.ch
---
 drivers/clk/Makefile |3 +-
 drivers/clk/clk-divider.c|  198 ++
 drivers/clk/clk-fixed-rate.c |   81 +
 drivers/clk/clk-gate.c   |  121 +
 drivers/clk/clk-mux.c|  114 
 include/linux/clk-private.h  |  124 ++
 include/linux/clk-provider.h |  125 ++
 7 files changed, 765 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clk/clk-divider.c
 create mode 100644 drivers/clk/clk-fixed-rate.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-mux.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ff362c4..1f736bc 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,4 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
-obj-$(CONFIG_COMMON_CLK)   += clk.o
+obj-$(CONFIG_COMMON_CLK)   += clk.o clk-fixed-rate.o clk-gate.o \
+  clk-mux.o clk-divider.o
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
new file mode 100644
index 000..8f02930
--- /dev/null
+++ b/drivers/clk/clk-divider.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix s.ha...@pengutronix.de
+ * Copyright (C) 2011 Richard Zhao, Linaro richard.z...@linaro.org
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Adjustable divider clock implementation
+ */
+
+#include linux/clk-provider.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+#include linux/string.h
+
+/*
+ * DOC: basic adjustable divider clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk-rate = parent-rate / divisor
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct clk_divider *divider = to_clk_divider(hw);
+   unsigned int div;
+
+   div = readl(divider-reg)  divider-shift;
+   div = (1  divider-width) - 1;
+
+   if (!(divider-flags  CLK_DIVIDER_ONE_BASED))
+   div++;
+
+   return parent_rate / div;
+}
+
+static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+   unsigned long *best_parent_rate)
+{
+   struct clk_divider *divider = to_clk_divider(hw);
+   int i, bestdiv = 0;
+   unsigned long parent_rate, best = 0, now, maxdiv;
+
+   maxdiv = (1  divider-width);
+
+   if (divider-flags  CLK_DIVIDER_ONE_BASED)
+   maxdiv--;
+
+   if (!(__clk_get_flags(hw-clk)  CLK_SET_RATE_PARENT)) {
+   parent_rate = __clk_get_rate(__clk_get_parent(hw-clk));
+   bestdiv = parent_rate / rate;
+   bestdiv = bestdiv == 0 ? 1 : bestdiv;
+   bestdiv = bestdiv  maxdiv ? maxdiv : bestdiv;
+   goto out;
+   }
+
+   /*
+* The maximum divider we can use without overflowing
+* unsigned long in rate * i below
+*/
+   maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+   for (i = 1; i = maxdiv; i++) {
+   int div;
+   parent_rate = __clk_round_rate(__clk_get_parent(hw-clk),
+   rate * i);
+   div = parent_rate / rate

Re: using cpuidle on panda board

2012-01-13 Thread Mike Turquette
On Fri, Jan 13, 2012 at 2:41 PM, Amit Kucheria amit.kuche...@linaro.org wrote:
 On Fri, Jan 13, 2012 at 7:14 PM, Dechesne, Nicolas n-deche...@ti.com wrote:


 On Fri, Jan 13, 2012 at 5:59 PM, Andy Green andy.gr...@linaro.org wrote:

 Amit, do you know of a good place to raid for better cpuidle, closer to
 upstream than OZ?


 wasn't that merged in 3.2? are you looking for that :
 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=9827266

 What was merged depends on hotplug, it isn't SMP cpuidle. At this
 point, I'm quite confused about the history on what happened to the
 SMP cpuidle driver and why it wasn't merged. Mike or Kevin should
 know.

Amit is correct.  The hotplug-dependent cpuidle got merged.

The SMP CPUidle patches have been put on the list and should work
patch into a recent kernel:
http://article.gmane.org/gmane.linux.ports.tegra/2649

However the OMAP4 support seems to be missing:
http://article.gmane.org/gmane.linux.ports.arm.omap/69186

So this isn't straightforward, but at least it's headed in the right direction.

Regards,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 1/6] clk: Kconfig: add entry for HAVE_CLK_PREPARE

2011-12-13 Thread Mike Turquette
The common clk framework provides clk_prepare and clk_unprepare
implementations.  Create an entry for HAVE_CLK_PREPARE so that
GENERIC_CLK can select it.

Signed-off-by: Mike Turquette mturque...@linaro.org
Acked-by: Shawn Guo shawn@linaro.org
---
 drivers/clk/Kconfig |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3530927..7a9899bd 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -5,3 +5,6 @@ config CLKDEV_LOOKUP
 
 config HAVE_MACH_CLKDEV
bool
+
+config HAVE_CLK_PREPARE
+   bool
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 5/6] clk: basic gateable and fixed-rate clks

2011-12-13 Thread Mike Turquette
Many platforms support simple gateable clks and fixed-rate clks that
should not be re-implemented by every platform.

This patch introduces a gateable clk with a common programming model of
gate control via a write of 1 bit to a register.  Both set-to-enable and
clear-to-enable are supported.

Also introduced is a fixed-rate clk which has no reprogrammable aspects.

The purpose of both types of clks is documented in drivers/clk/basic.c.

TODO: add support for a simple divider, simple mux and a dummy clk for
stubbing out platform support.

Based on original patch by Jeremy Kerr and contribution by Jamie Iles.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Jamie Iles ja...@jamieiles.com
---
 drivers/clk/Kconfig |7 ++
 drivers/clk/Makefile|5 +-
 drivers/clk/clk-basic.c |  208 +++
 include/linux/clk.h |   35 
 4 files changed, 253 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/clk-basic.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index adc0586..ba7eb8c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -12,3 +12,10 @@ config HAVE_CLK_PREPARE
 config GENERIC_CLK
bool
select HAVE_CLK_PREPARE
+
+config GENERIC_CLK_BASIC
+   bool Basic clock definitions
+   depends on GENERIC_CLK
+   help
+  Allow use of basic, single-function clock types.  These
+  common definitions can be used across many platforms.
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 570d5b9..68b20a1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,4 @@
 
-obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
-obj-$(CONFIG_GENERIC_CLK)  += clk.o
+obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
+obj-$(CONFIG_GENERIC_CLK)  += clk.o
+obj-$(CONFIG_GENERIC_CLK_BASIC)+= clk-basic.o
diff --git a/drivers/clk/clk-basic.c b/drivers/clk/clk-basic.c
new file mode 100644
index 000..a065bc8
--- /dev/null
+++ b/drivers/clk/clk-basic.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.com
+ * Copyright (C) 2011 Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Basic single-function clk implementations
+ */
+
+/* TODO add basic divider clk, basic mux clk and dummy clk */
+
+#include linux/clk.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/io.h
+
+/*
+ * NOTE: all of the basic clks here are just that: single-function
+ * simple clks.  One assumption in their implementation is that existing
+ * locking mechanisms (prepare_mutex and enable_spinlock) are enough to
+ * prevent race conditions during register accesses.  If this is not
+ * true for your platform then please implement your own version of
+ * these clks which take such issues into account.
+ */
+
+#define to_clk_hw_gate(ck) container_of(ck, struct clk_hw_gate, clk)
+#define to_clk_hw_fixed(ck) container_of(ck, struct clk_hw_fixed, clk)
+
+/**
+ * DOC: basic gatable clock which can gate and ungate it's ouput
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare  clk_unprepare do nothing
+ * enable - clk_enable and clk_disable are functional  control gating
+ * rate - inherits rate from parent.  No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ *
+ * note: parent should not be NULL for this clock, but we check because we're
+ * paranoid
+ */
+
+static unsigned long clk_hw_gate_recalc_rate(struct clk *clk)
+{
+   if (clk-parent)
+   return clk-parent-rate;
+   else
+   return 0;
+}
+
+static struct clk *clk_hw_gate_get_parent(struct clk *clk)
+{
+   return to_clk_hw_gate(clk)-fixed_parent;
+}
+
+static void clk_hw_gate_set_bit(struct clk *clk)
+{
+   struct clk_hw_gate *gate = to_clk_hw_gate(clk);
+   u32 reg;
+
+   reg = readl(gate-reg);
+   reg |= BIT(gate-bit_idx);
+   writel(reg, gate-reg);
+}
+
+static void clk_hw_gate_clear_bit(struct clk *clk)
+{
+   struct clk_hw_gate *gate = to_clk_hw_gate(clk);
+   u32 reg;
+
+   reg = readl(gate-reg);
+   reg = ~BIT(gate-bit_idx);
+   writel(reg, gate-reg);
+}
+
+static int clk_hw_gate_enable_set(struct clk *clk)
+{
+   clk_hw_gate_set_bit(clk);
+
+   return 0;
+}
+
+static void clk_hw_gate_disable_clear(struct clk *clk)
+{
+   clk_hw_gate_clear_bit(clk);
+}
+
+struct clk_hw_ops clk_hw_gate_set_enable_ops = {
+   .enable = clk_hw_gate_enable_set,
+   .disable = clk_hw_gate_disable_clear,
+   .recalc_rate = clk_hw_gate_recalc_rate,
+   .get_parent = clk_hw_gate_get_parent,
+};
+EXPORT_SYMBOL_GPL(clk_hw_gate_set_enable_ops);
+
+static int clk_hw_gate_enable_clear(struct clk *clk)
+{
+   clk_hw_gate_clear_bit(clk

[PATCH v4 6/6] clk: export the clk tree topology to debugfs

2011-12-13 Thread Mike Turquette
Represents the clk tree as a directory hieraching in debugfs.  Each clk
is a directory filled with the following read-only entries:

clk_rate
clk_flags
clk_prepare_count
clk_enable_count
clk_notifier_count

This commit borrows some code from Yong Shen's patch to export clkdev
clk's to debugfs:
http://git.pengutronix.de/?p=imx/linux-2.6.git;a=commit;h=30aa15230747b3b92da16d841b1cf369f07192e7

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Yong Shen yong.s...@linaro.org
Cc: Sascha Hauer s.ha...@pengutronix.de
---
 drivers/clk/Kconfig |9 +++
 drivers/clk/clk.c   |  176 ++-
 include/linux/clk.h |3 +
 3 files changed, 186 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index ba7eb8c..09cc198 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -19,3 +19,12 @@ config GENERIC_CLK_BASIC
help
   Allow use of basic, single-function clock types.  These
   common definitions can be used across many platforms.
+
+config GENERIC_CLK_DEBUG
+   bool Clock tree representation in debugs
+   depends on GENERIC_CLK
+   help
+ Creates a directory hierchy in debugfs for visualizing the clk
+ tree structure as well.  Each directory contains read-only
+ members that export information specific to that clk node:
+ clk_rate, clk_flags, clk_prepare_count  clk_enable_count.
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index f86cb98..a6ddbb1 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -23,6 +23,166 @@ static DEFINE_MUTEX(prepare_lock);
 static HLIST_HEAD(clk_root_list);
 static LIST_HEAD(clk_notifier_list);
 
+/***debugfs support***/
+
+#ifdef CONFIG_GENERIC_CLK_DEBUG
+#include linux/debugfs.h
+
+static struct dentry *rootdir;
+static int inited = 0;
+
+/* caller must hold prepare_lock */
+static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
+{
+   struct dentry *d;
+   int ret = -ENOMEM;
+
+   if (!clk || !pdentry) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   d = debugfs_create_dir(clk-name, pdentry);
+   if (!d)
+   goto out;
+
+   clk-dentry = d;
+
+   d = debugfs_create_u64(clk_rate, S_IRUGO, clk-dentry,
+   (u64 *)clk-rate);
+   if (!d)
+   goto err_out;
+
+   d = debugfs_create_x32(clk_flags, S_IRUGO, clk-dentry,
+   (u32 *)clk-flags);
+   if (!d)
+   goto err_out;
+
+   d = debugfs_create_u32(clk_prepare_count, S_IRUGO, clk-dentry,
+   (u32 *)clk-prepare_count);
+   if (!d)
+   goto err_out;
+
+   d = debugfs_create_u32(clk_enable_count, S_IRUGO, clk-dentry,
+   (u32 *)clk-enable_count);
+   if (!d)
+   goto err_out;
+
+   d = debugfs_create_u32(clk_notifier_count, S_IRUGO, clk-dentry,
+   (u32 *)clk-notifier_count);
+   if (!d)
+   goto err_out;
+
+   ret = 0;
+   goto out;
+
+err_out:
+   debugfs_remove(clk-dentry);
+out:
+   return ret;
+}
+
+/* caller must hold prepare_lock */
+static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry)
+{
+   struct clk *child;
+   struct hlist_node *tmp;
+   int ret = -EINVAL;;
+
+   if (!clk || !pdentry)
+   goto out;
+
+   ret = clk_debug_create_one(clk, pdentry);
+
+   if (ret)
+   goto out;
+
+   hlist_for_each_entry(child, tmp, clk-children, child_node)
+   clk_debug_create_subtree(child, clk-dentry);
+
+   ret = 0;
+out:
+   return ret;
+}
+
+/**
+ * clk_debug_register - add a clk node to the debugfs clk tree
+ * @clk: the clk being added to the debugfs clk tree
+ *
+ * Dynamically adds a clk to the debugfs clk tree if debugfs has been
+ * initialized.  Otherwise it bails out early since the debugfs clk tree
+ * will be created lazily by clk_debug_init as part of a late_initcall.
+ *
+ * Caller must hold prepare_lock.  Only clk_init calls this function (so
+ * far) so this is taken care.
+ */
+static int clk_debug_register(struct clk *clk)
+{
+   struct clk *parent;
+   struct dentry *pdentry;
+   int ret = 0;
+
+   if (!inited)
+   goto out;
+
+   parent = clk-parent;
+
+   /*
+* Check to see if a clk is a root clk.  Also check that it is
+* safe to add this clk to debugfs
+*/
+   if (!parent)
+   pdentry = rootdir;
+   else
+   if (parent-dentry)
+   pdentry = parent-dentry;
+   else
+   goto out;
+
+   ret = clk_debug_create_subtree(clk, pdentry);
+
+out:
+   return ret;
+}
+
+/**
+ * clk_debug_init - lazily create the debugfs clk tree visualization
+ *
+ * clks are often initialized very early during boot before memory can

[PATCH v4 4/6] clk: introduce rate change notifiers

2011-12-13 Thread Mike Turquette
Many devices support dynamic clk frequency changes, but often need to
handle these clk frequency changes with care.  Examples of these devices
range from processors such as CPUs and GPUs to IO controllers such as
DDR controllers or MMC/SD card controllers and fixed-function hardware
such as video decoding logic.

To accomodate these needs this patch introduces clk rate change
notifiers to the common clk framework.  Drivers may subscribe to a
specific clk and recieve asynchronous notifications before a clk's rate
changes, after a clk's rate has been changed and also if the rate change
operation was aborted.

This patch is heavily based on Paul Walmsley's OMAP clk notifier
patches, of which several version have been posted over time:
http://article.gmane.org/gmane.linux.ports.arm.omap/18374
http://article.gmane.org/gmane.linux.ports.arm.omap/15200

There are subtle differences in this implementation, such as use of SRCU
notifers instead of blocking, and the use of a new .speculate_rate
function pointer (similar .recalc_rate) for predicting rate changes down
the sub-tree of clks.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Paul Walmsley p...@pwsan.com
---
 drivers/clk/clk.c   |  296 +++
 include/linux/clk.h |   64 +++
 2 files changed, 340 insertions(+), 20 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8cadadd..f86cb98 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -15,11 +15,13 @@
 #include linux/spinlock.h
 #include linux/err.h
 #include linux/list.h
+#include linux/slab.h
 
 static DEFINE_SPINLOCK(enable_lock);
 static DEFINE_MUTEX(prepare_lock);
 
 static HLIST_HEAD(clk_root_list);
+static LIST_HEAD(clk_notifier_list);
 
 /***clk API***/
 
@@ -248,31 +250,128 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
 /**
+ * __clk_notify - call clk notifier chain
+ * @clk: struct clk * that is changing rate
+ * @msg: clk notifier type (see include/linux/clk.h)
+ * @old_rate: old clk rate
+ * @new_rate: new clk rate
+ *
+ * Triggers a notifier call chain on the clk rate-change notification
+ * for 'clk'.  Passes a pointer to the struct clk and the previous
+ * and current rates to the notifier callback.  Intended to be called by
+ * internal clock code only.  Returns NOTIFY_DONE from the last driver
+ * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
+ * a driver returns that.
+ */
+static int __clk_notify(struct clk *clk, unsigned long msg,
+   unsigned long old_rate, unsigned long new_rate)
+{
+   struct clk_notifier *cn;
+   struct clk_notifier_data cnd;
+   int ret = NOTIFY_DONE;
+
+   cnd.clk = clk;
+   cnd.old_rate = old_rate;
+   cnd.new_rate = new_rate;
+
+   list_for_each_entry(cn, clk_notifier_list, node) {
+   if (cn-clk == clk) {
+   ret = srcu_notifier_call_chain(cn-notifier_head, msg,
+   cnd);
+   break;
+   }
+   }
+
+   return ret;
+}
+
+/**
  * __clk_recalc_rates
  * @clk: first clk in the subtree
+ * @msg: notification type (see include/linux/clk.h)
  *
  * Walks the subtree of clks starting with clk and recalculates rates as it
  * goes.  Note that if a clk does not implement the recalc_rate operation then
  * propagation of that subtree stops and all of that clks children will not
- * have their rates updated.  Caller must hold prepare_lock.
+ * have their rates updated.
+ *
+ * clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
+ * if necessary.
+ *
+ * Caller must hold prepare_lock.
+ */
+static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
+{
+   unsigned long old_rate;
+   struct hlist_node *tmp;
+   struct clk *child;
+
+   old_rate = clk-rate;
+
+   if (clk-ops-recalc_rate)
+   clk-rate = clk-ops-recalc_rate(clk);
+
+   /* ignore return value for POST_RATE_CHANGE  ABORT_RATE_CHANGE */
+   if (clk-notifier_count)
+   __clk_notify(clk, msg, old_rate, clk-rate);
+
+   hlist_for_each_entry(child, tmp, clk-children, child_node)
+   __clk_recalc_rates(child, msg);
+}
+
+/**
+ * __clk_speculate_rates
+ * @clk: first clk in the subtree
+ * @parent_rate: the future rate of clk's parent
+ *
+ * Walks the subtree of clks starting with clk, speculating rates as it
+ * goes and firing off PRE_RATE_CHANGE notifications as necessary.  Note
+ * that if a clk does not implement the speculate_rate operation then
+ * propagation of that subtree stops and all of that clks children will
+ * not have their rates speculated.
+ *
+ * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending
+ * pre-rate change notifications and returns early if no clks in the
+ * subtree have subscribed to the notifications.
+ *
+ * It is not required to have a .speculate_rate callback

[PATCH v4 3/6] clk: introduce the common clock framework

2011-12-13 Thread Mike Turquette
The common clk framework is an attempt to define a common struct clk
which can be used by most platforms, and an API that drivers can always
use safely for managing clks.

The net result is consolidation of many different struct clk definitions
and platform-specific clk framework implementations.

This patch introduces the common struct clk, struct clk_ops and
definitions for the long-standing clk API in include/clk/clk.h.
Platforms may define their own hardware-specific clk structure, so long
as it wraps an instance of the common struct clk which is passed to
clk_init at initialization time.  From this point on all of the usual
clk APIs should be supported, so long as the platform supports them
through hardware-specific callbacks in struct clk_ops.

See Documentation/clk.txt for more details.

This patch is based on the work of Jeremy Kerr, which in turn was based
on the work of Ben Herrenschmidt.  Big thanks to both of them for
kickstarting this effort.

Signed-off-by: Mike Turquette mturque...@linaro.org
Cc: Jeremy Kerr jeremy.k...@canonical.com
---
 drivers/clk/Kconfig  |4 +
 drivers/clk/Makefile |1 +
 drivers/clk/clk.c|  564 ++
 include/linux/clk.h  |  130 +++-
 4 files changed, 695 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/clk.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7a9899bd..adc0586 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -8,3 +8,7 @@ config HAVE_MACH_CLKDEV
 
 config HAVE_CLK_PREPARE
bool
+
+config GENERIC_CLK
+   bool
+   select HAVE_CLK_PREPARE
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 07613fa..570d5b9 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
+obj-$(CONFIG_GENERIC_CLK)  += clk.o
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
new file mode 100644
index 000..8cadadd
--- /dev/null
+++ b/drivers/clk/clk.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.com
+ * Copyright (C) 2011 Linaro Ltd mturque...@linaro.org
+ *
+ * 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.
+ *
+ * Standard functionality for the common clock API.  See Documentation/clk.txt
+ */
+
+#include linux/clk.h
+#include linux/module.h
+#include linux/mutex.h
+#include linux/spinlock.h
+#include linux/err.h
+#include linux/list.h
+
+static DEFINE_SPINLOCK(enable_lock);
+static DEFINE_MUTEX(prepare_lock);
+
+static HLIST_HEAD(clk_root_list);
+
+/***clk API***/
+
+void __clk_unprepare(struct clk *clk)
+{
+   if (!clk)
+   return;
+
+   if (WARN_ON(clk-prepare_count == 0))
+   return;
+
+   if (--clk-prepare_count  0)
+   return;
+
+   WARN_ON(clk-enable_count  0);
+
+   if (clk-ops-unprepare)
+   clk-ops-unprepare(clk);
+
+   __clk_unprepare(clk-parent);
+}
+
+/**
+ * clk_unprepare - perform the slow part of a clk gate
+ * @clk: the clk being gated
+ *
+ * clk_unprepare may sleep, which differentiates it from clk_disable.  In a
+ * simple case, clk_unprepare can be used instead of clk_disable to gate a clk
+ * if the operation may sleep.  One example is a clk which is accessed over
+ * I2c.  In the complex case a clk gate operation may require a fast and a slow
+ * part.  It is this reason that clk_unprepare and clk_disable are not mutually
+ * exclusive.  In fact clk_disable must be called before clk_unprepare.
+ */
+void clk_unprepare(struct clk *clk)
+{
+   mutex_lock(prepare_lock);
+   __clk_unprepare(clk);
+   mutex_unlock(prepare_lock);
+}
+EXPORT_SYMBOL_GPL(clk_unprepare);
+
+int __clk_prepare(struct clk *clk)
+{
+   int ret = 0;
+
+   if (!clk)
+   return 0;
+
+   if (clk-prepare_count == 0) {
+   ret = __clk_prepare(clk-parent);
+   if (ret)
+   return ret;
+
+   if (clk-ops-prepare) {
+   ret = clk-ops-prepare(clk);
+   if (ret) {
+   __clk_unprepare(clk-parent);
+   return ret;
+   }
+   }
+   }
+
+   clk-prepare_count++;
+
+   return 0;
+}
+
+/**
+ * clk_prepare - perform the slow part of a clk ungate
+ * @clk: the clk being ungated
+ *
+ * clk_prepare may sleep, which differentiates it from clk_enable.  In a simple
+ * case, clk_prepare can be used instead of clk_enable to ungate a clk if the
+ * operation may sleep.  One example is a clk which is accessed over I2c.  In
+ * the complex case a clk ungate operation may require a fast and a slow part.
+ * It is this reason that clk_prepare and clk_enable are not mutually
+ * exclusive.  In fact clk_prepare must be called before

[PATCH 6/7] omap: dss: use clk_prepare in dss reset

2011-12-13 Thread Mike Turquette
Signed-off-by: Mike Turquette mturque...@ti.com
---
 arch/arm/mach-omap2/display.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index dce9905..21f8fcc 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -297,8 +297,10 @@ int omap_dss_reset(struct omap_hwmod *oh)
}
 
for (i = oh-opt_clks_cnt, oc = oh-opt_clks; i  0; i--, oc++)
-   if (oc-_clk)
+   if (oc-_clk) {
+   clk_prepare(oc-_clk);
clk_enable(oc-_clk);
+   }
 
dispc_disable_outputs();
 
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 1/7] OMAP: Kconfig: select GENERIC_CLK

2011-12-13 Thread Mike Turquette
From: Mike Turquette mturque...@linaro.org

Signed-off-by: Mike Turquette mturque...@ti.com
---
 arch/arm/mach-omap2/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index e1293aa..921451c 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -17,6 +17,7 @@ config ARCH_OMAP2PLUS_TYPICAL
select MENELAUS if ARCH_OMAP2
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
+   select GENERIC_CLK
help
  Compile a kernel suitable for booting most boards
 
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 0/7] RFC: convert OMAP to common struct clk

2011-12-13 Thread Mike Turquette
This patch series is an RFC for converting OMAP to the common struct
clk.  These patches are based on v4 of the common struct clk series:
https://lkml.org/lkml/2011/12/13/451

OMAP's old struct clk has been renamed to struct clk_hw_omap, but left
essentially the same.  This series only targets OMAP4 and was only
tested on a 4430 Panda.

The next step is to figure out:
 * what are the various clk types we want to support in separate
   structures
 * where does the clk driver code live (still in mach-omap2?)
 * kill off plat-omap/clock.* completely?  I vote yes.

These patches can also be found at,
http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=shortlog;h=refs/heads/v3.2-rc5-clkv4-omap

The same series merged with Kevin's PM branch (to get CPUfreq working)
can be found at,
http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=shortlog;h=refs/heads/v3.2-rc5-clkv4-omap-pm

This series will be followed up shortly with another set of patches for
testing the clk rate change notifiers, parent propagation of rate
changes and debugfs re-parenting.

Mike Turquette (7):
  OMAP: Kconfig: select GENERIC_CLK
  HACK: omap4: clk: convert to common struct clk
  HACK: omap: convert 44xx data to common struct clk
  omap: hwmod: convert to use common struct clk
  omap: panda: use clk_prepare in ehci init
  omap: dss: use clk_prepare in dss reset
  HACK: comment WARN_ON in _clkdm_clk_hwmod_disable

 arch/arm/mach-omap2/Kconfig |1 +
 arch/arm/mach-omap2/board-omap4panda.c  |1 +
 arch/arm/mach-omap2/clkt_clksel.c   |  195 +-
 arch/arm/mach-omap2/clkt_dpll.c |   54 +-
 arch/arm/mach-omap2/clock.c |  363 +--
 arch/arm/mach-omap2/clock.h |   59 +-
 arch/arm/mach-omap2/clock44xx_data.c| 4615 ++-
 arch/arm/mach-omap2/clockdomain.c   |2 +-
 arch/arm/mach-omap2/display.c   |4 +-
 arch/arm/mach-omap2/dpll3xxx.c  |  228 +-
 arch/arm/mach-omap2/dpll44xx.c  |   62 +-
 arch/arm/mach-omap2/omap_hwmod.c|   54 +-
 arch/arm/plat-omap/clock.c  |  315 +--
 arch/arm/plat-omap/include/plat/clock.h |   96 +-
 14 files changed, 3415 insertions(+), 2634 deletions(-)

-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 7/7] HACK: comment WARN_ON in _clkdm_clk_hwmod_disable

2011-12-13 Thread Mike Turquette
Not-signed-off-by: Mike Turquette mturque...@ti.com
---
 arch/arm/mach-omap2/clockdomain.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
index ad07689..825248b 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -941,7 +941,7 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain 
*clkdm)
return -EINVAL;
 
if (atomic_read(clkdm-usecount) == 0) {
-   WARN_ON(1); /* underflow */
+   //WARN_ON(1); /* underflow */
return -ERANGE;
}
 
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 4/6] HACK: cpufreq: omap: change mpu_clk's rate

2011-12-13 Thread Mike Turquette
As a proof of concept, change OMAP's cpufreq driver to use mpu_clk in
place of directly using the DPLL.  This better reflects reality as there
are some functional clks between the ARM IP and the PLL.

To make this work mpu_clk uses the new .round_rate function
omap2_passthrough_round_rate, which simplies passing up a rate change
request to the parent.

Not for merging, just to get discussion going around the common clk
patches and future OMAP adaptations.

Not-signed-off-by: Mike Turquette mturque...@ti.com
---
 drivers/cpufreq/omap-cpufreq.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5d04c57..45cb7f9 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -247,7 +247,7 @@ static int __init omap_cpufreq_init(void)
else if (cpu_is_omap34xx())
mpu_clk_name = dpll1_ck;
else if (cpu_is_omap44xx())
-   mpu_clk_name = dpll_mpu_ck;
+   mpu_clk_name = mpu_clk;
 
if (!mpu_clk_name) {
pr_err(%s: unsupported Silicon?\n, __func__);
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 3/6] HACK: omap: clk: add mpu_periphclk clk node

2011-12-13 Thread Mike Turquette
From: Mike Turquette mturque...@linaro.org

The ARM periphclk drives various peripherals for the MPU including the
TWD and local timers.  This patch creates the missing clk tree data to
represent this relationship:

 dpll_mpu_ck
  |
dpll_mpu_m2_ck (divide by 1)
  |
   mpu_clk (divide by 1)
  |
 mpu_periphclk (divide by 2)

This patch is based on Santosh Shilimkar's original version:
http://article.gmane.org/gmane.linux.ports.arm.omap/64936

Not-signed-off-by: Mike Turquette mturque...@ti.com
---
 arch/arm/mach-omap2/clock44xx_data.c |   37 +-
 1 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/clock44xx_data.c 
b/arch/arm/mach-omap2/clock44xx_data.c
index 33249b3..6c6d0fb 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -1035,7 +1035,7 @@ static const struct clksel dpll_mpu_m2_div[] = {
 
 static const struct clk_hw_ops dpll_mpu_m2_ck_ops = {
.recalc_rate= omap2_clksel_recalc,
-   .round_rate = omap2_clksel_round_rate,
+   .round_rate = omap2_passthrough_round_rate,
.set_rate   = omap2_clksel_set_rate,
.get_parent = omap2_get_parent_fixed,
 };
@@ -1043,6 +1043,7 @@ static const struct clk_hw_ops dpll_mpu_m2_ck_ops = {
 static struct clk_hw_omap dpll_mpu_m2_ck_hw = {
.clk = {
.name   = dpll_mpu_m2_ck,
+   .flags  = CLK_PARENT_SET_RATE,
.ops= dpll_mpu_m2_ck_ops,
},
.fixed_parent   = dpll_mpu_ck_hw.clk,
@@ -1053,6 +1054,38 @@ static struct clk_hw_omap dpll_mpu_m2_ck_hw = {
.deny_idle  = omap4_dpllmx_deny_gatectrl,
 };
 
+static const struct clk_hw_ops mpu_clk_ops = {
+   .recalc_rate= omap_fixed_divisor_recalc,
+   .round_rate = omap2_passthrough_round_rate,
+   .get_parent = omap2_get_parent_fixed,
+};
+
+static struct clk_hw_omap mpu_clk_hw = {
+   .clk = {
+   .name   = mpu_clk,
+   .flags  = CLK_PARENT_SET_RATE,
+   .ops= mpu_clk_ops,
+   },
+   .fixed_parent   = dpll_mpu_m2_ck_hw.clk,
+   .fixed_div  = 1,
+};
+
+static const struct clk_hw_ops mpu_periphclk_ops = {
+   .recalc_rate= omap_fixed_divisor_recalc,
+   .round_rate = omap2_passthrough_round_rate,
+   .get_parent = omap2_get_parent_fixed,
+};
+
+static struct clk_hw_omap mpu_periphclk_hw = {
+   .clk = {
+   .name   = mpu_periphclk,
+   .flags  = CLK_PARENT_SET_RATE,
+   .ops= mpu_periphclk_ops,
+   },
+   .fixed_parent   = mpu_clk_hw.clk,
+   .fixed_div  = 2,
+};
+
 static const struct clk_hw_ops per_hs_clk_div_ck_ops = {
.recalc_rate= omap_fixed_divisor_recalc,
.get_parent = omap2_get_parent_fixed,
@@ -4071,6 +4104,8 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL,   dpll_iva_m5x2_ck, 
dpll_iva_m5x2_ck_hw.clk,   CK_443X),
CLK(NULL,   dpll_mpu_ck,  dpll_mpu_ck_hw.clk,
CK_443X),
CLK(NULL,   dpll_mpu_m2_ck,   dpll_mpu_m2_ck_hw.clk, 
CK_443X),
+   CLK(NULL,   mpu_clk,  mpu_clk_hw.clk,
CK_443X),
+   CLK(smp_twd,  NULL,   mpu_periphclk_hw.clk,  
CK_443X),
CLK(NULL,   per_hs_clk_div_ck,
per_hs_clk_div_ck_hw.clk,  CK_443X),
CLK(NULL,   per_hsd_byp_clk_mux_ck,   
per_hsd_byp_clk_mux_ck_hw.clk, CK_443X),
CLK(NULL,   dpll_per_ck,  dpll_per_ck_hw.clk,
CK_443X),
-- 
1.7.5.4


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 5/6] smp_twd: Reconfigure clockevents after cpufreq change

2011-12-13 Thread Mike Turquette
From: Linus Walleij (address hidden)

The localtimer's clock changes with the cpu clock. After a
cpufreq transition, update the clockevent's frequency and
reprogram the next clock event.

Adds a clock called smp_twd that is used to determine the
twd frequency, which can also be used at init time to
avoid calibrating the twd frequency.

Clock changes are based on Rob Herring's work. The
necessary changes in the clockevents framework was done by
Thomas Gleixner in kernel v3.0.

Signed-off-by: Colin Cross (address hidden)
Cc: Russell King (address hidden)
Acked-by: Thomas Gleixner (address hidden)
Acked-by: Rob Herring (address hidden)
Acked-by: Santosh Shilimkar (address hidden)
[ifdef:ed CPUfreq stuff for non-cpufreq configs]
Signed-off-by: Linus Walleij (address hidden)
---
 arch/arm/kernel/smp_twd.c |   89 ++---
 1 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index a8a6682..92dbd80 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -10,13 +10,17 @@
  */
 #include linux/init.h
 #include linux/kernel.h
+#include linux/clk.h
+#include linux/cpufreq.h
 #include linux/delay.h
 #include linux/device.h
+#include linux/err.h
 #include linux/smp.h
 #include linux/jiffies.h
 #include linux/clockchips.h
 #include linux/irq.h
 #include linux/io.h
+#include linux/percpu.h
 
 #include asm/smp_twd.h
 #include asm/localtimer.h
@@ -25,7 +29,9 @@
 /* set up by the platform code */
 void __iomem *twd_base;
 
+static struct clk *twd_clk;
 static unsigned long twd_timer_rate;
+static DEFINE_PER_CPU(struct clock_event_device *, twd_ce);
 
 static struct clock_event_device __percpu **twd_evt;
 
@@ -89,6 +95,52 @@ void twd_timer_stop(struct clock_event_device *clk)
disable_percpu_irq(clk-irq);
 }
 
+#ifdef CONFIG_CPU_FREQ
+
+/*
+ * Updates clockevent frequency when the cpu frequency changes.
+ * Called on the cpu that is changing frequency with interrupts disabled.
+ */
+static void twd_update_frequency(void *data)
+{
+   twd_timer_rate = clk_get_rate(twd_clk);
+
+   clockevents_update_freq(__get_cpu_var(twd_ce), twd_timer_rate);
+}
+
+static int twd_cpufreq_transition(struct notifier_block *nb,
+   unsigned long state, void *data)
+{
+   struct cpufreq_freqs *freqs = data;
+
+   /*
+* The twd clock events must be reprogrammed to account for the new
+* frequency.  The timer is local to a cpu, so cross-call to the
+* changing cpu.
+*/
+   if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
+   smp_call_function_single(freqs-cpu, twd_update_frequency,
+   NULL, 1);
+
+   return NOTIFY_OK;
+}
+
+static struct notifier_block twd_cpufreq_nb = {
+   .notifier_call = twd_cpufreq_transition,
+};
+
+static int twd_cpufreq_init(void)
+{
+   if (!IS_ERR_OR_NULL(twd_clk))
+   return cpufreq_register_notifier(twd_cpufreq_nb,
+   CPUFREQ_TRANSITION_NOTIFIER);
+
+   return 0;
+}
+core_initcall(twd_cpufreq_init);
+
+#endif
+
 static void __cpuinit twd_calibrate_rate(void)
 {
unsigned long count;
@@ -140,6 +192,27 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
return IRQ_NONE;
 }
 
+static struct clk *twd_get_clock(void)
+{
+   struct clk *clk;
+   int err;
+
+   clk = clk_get_sys(smp_twd, NULL);
+   if (IS_ERR(clk)) {
+   pr_err(smp_twd: clock not found: %d\n, (int)PTR_ERR(clk));
+   return clk;
+   }
+
+   err = clk_enable(clk);
+   if (err) {
+   pr_err(smp_twd: clock failed to enable: %d\n, err);
+   clk_put(clk);
+   return ERR_PTR(err);
+   }
+
+   return clk;
+}
+
 /*
  * Setup the local clock events for a CPU.
  */
@@ -165,7 +238,13 @@ void __cpuinit twd_timer_setup(struct clock_event_device 
*clk)
}
}
 
-   twd_calibrate_rate();
+   if (!twd_clk)
+   twd_clk = twd_get_clock();
+
+   if (!IS_ERR_OR_NULL(twd_clk))
+   twd_timer_rate = clk_get_rate(twd_clk);
+   else
+   twd_calibrate_rate();
 
clk-name = local_timer;
clk-features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
@@ -173,15 +252,13 @@ void __cpuinit twd_timer_setup(struct clock_event_device 
*clk)
clk-rating = 350;
clk-set_mode = twd_set_mode;
clk-set_next_event = twd_set_next_event;
-   clk-shift = 20;
-   clk-mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk-shift);
-   clk-max_delta_ns = clockevent_delta2ns(0x, clk);
-   clk-min_delta_ns = clockevent_delta2ns(0xf, clk);
 
this_cpu_clk = __this_cpu_ptr(twd_evt);
*this_cpu_clk = clk;
 
-   clockevents_register_device(clk);
+   __get_cpu_var(twd_ce) = clk;
 
+   clockevents_config_and_register(clk, twd_timer_rate,
+

Re: [PATCH v3 0/5] common clk framework

2011-11-22 Thread Mike Turquette
On Tue, Nov 22, 2011 at 9:45 AM, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:
 On Tue, Nov 22, 2011 at 07:42:59AM -0800, Greg KH wrote:
 On Mon, Nov 21, 2011 at 05:40:42PM -0800, Mike Turquette wrote:
    .sysfs support.  Visualize your clk tree at /sys/clk!  Where would be
  a better place to put the clk tree besides the root of /sys/?

 Um, in the proper place for it under /sys/devices like the rest of the
 device tree is?

 I'd suggest that making the clock tree visible in sysfs (and therefore
 part of the kernel ABI) is not a good idea.  Some of the nodes in there
 will be specific to the implementation.  Exposing the clock nodes means
 that if you have to change the clock tree structure, you change the
 visible userspace ABI.

It is true that the ABI will change dynamically.


 So, I'd suggest that we need to see a justification for this, rather
 than exposing this stuff via debugfs as has been done with existing
 implementations.

Userspace tools like powerdebug (and maybe someday powertop) hope to
use a reliable-looking interface to view clk data.  There are obvious
uses for this data in a debug tool, the most obvious of which is
which clk isn't turning off when it should?.

I can migrate this stuff to debugfs, but it adds the burden of having
debugfs enabled for folks that want to view this data.  I would also
argue that sysfs is there to model various aspects of system topology
and a clk tree certainly fits the bill.

If others also agree that it should reside only in debugfs then I'll
move it there for V4.

Thanks,
Mike

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: Bus framework

2011-10-26 Thread Mike Turquette
On Wed, Oct 26, 2011 at 3:36 AM, Richard Zhao richard.z...@linaro.org wrote:
 On 26 October 2011 14:39, Amit Kucheria amit.kuche...@linaro.org wrote:
 On 11 Oct 26, Richard Zhao wrote:
 Hi Amit,

 Is there anyone working on a SoC bus framework?
 The bus framework can manage the bus fabric, ddr, OCRAM clocks. When a
 device driver become working, it tells bus framework, cpu may access
 me (ip bus and related bus fabric on), I'm also a bus master, may
 access ddr (ddr dma access +1 ). For bus framework, if ddr dma access
 request is zero, ddr clk can be disabled in WFI/wait mode. The bus
 framework manage the SoC bus topology.  If a bus switch use count is
 zero, it can be disabled. It may even adjust the bus freq dynamically
 according to bus request.

 Why can't this be handled in the PM runtime framework? Bus runtime drivers
 retain the logic for enabling/disabling the clocks and regulators required
 for the bus.
 Yes, I think it could be part of PM runtime framework. I just need the
 function described above. Can we do that now?

I think we need to gather more requirements first.  PM Runtime makes
good sense for enabling/disabling clocks.  On chips like OMAP there is
lots of hardware auto-clock gating, so that makes less sense for us.

On the other hand I think we all need to control bus speed.  If you
have some performance counters then maybe you can use devfreq for
this, or if you are able to express your needs from drivers then PM
QoS starts to look appropriate.

Paul Walmsley has brought up this issue before and I've CC'd him.  In
the past some ideas have been for two devices and a throughput value
to be used in an API that might look something like:

pm_qos_tput_constraint(struct device *from, struct device *to,
unsigned long tput);

So I think separate needs have been identified:
1) clock enable/disable for a bus
a) pm runtime is probably a good idea for this
2) clock rate change/dvfs for a bus
a) devfreq makes sense if you are relying on performance
counters/governor to change bus rate
i) see 
http://git.infradead.org/users/kmpark/linux-2.6-samsung/commitdiff/eb92dfe7893e23d004baf7758514768c49486d98?hp=5e3396894b50697b84db559c1589b4b7ce893b15
b) pm qos makes sense if you want drivers to express their needs via an API

Just food for thought.

Regards,
Mike

 Regards
 Richard

 /Amit




___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: cpu hotplug test scenarii

2011-09-29 Thread Mike Turquette
On Thu, Sep 29, 2011 at 12:46 AM, Daniel Lezcano
daniel.lezc...@linaro.org wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 On 09/29/2011 09:11 AM, Amit Kucheria wrote:
 On Thu, Sep 29, 2011 at 9:14 AM, Daniel Lezcano
 daniel.lezc...@linaro.org wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 On 09/29/2011 05:41 AM, Paul Larson wrote:
 On Wed, Sep 28, 2011 at 5:18 AM, Daniel Lezcano
 daniel.lezc...@linaro.orgwrote:

 Test 6: do some stress test
 ===

 for each cpu
  * for i in 1 .. 50
   * set cpuX offline
   * set cpuX back online

 Not sure how evil you want to get with this, but several years back I wrote
 a simple, but nasty test that picked a cpu at random, and set the state to
 the opposite of whatever it happened to be at the time.  It was completely
 random, I didn't have anything builtin for record/playback, or doing it in
 the same sequence for reproducibilty, but it didn't really need it.  When 
 it
 broke things, it usually broke them within just a few minutes.

 Ok thanks for the idea, I will add what you suggest.

 With cpu0 being a special case?


 Yes, cpu0 will be a special case for all the tests.

If only we had a patch for that!

;-)

Mike

 - --
  http://www.linaro.org/ Linaro.org ? Open source software for ARM SoCs

 Follow Linaro:  http://www.facebook.com/pages/Linaro Facebook |
 http://twitter.com/#!/linaroorg Twitter |
 http://www.linaro.org/linaro-blog/ Blog

 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.10 (GNU/Linux)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iQEcBAEBAgAGBQJOhCJqAAoJEAKBbMCpUGYAS54H/i3g9v2KcNal7zCvshmXFJcZ
 xX//Np/z+1UCUowTUnV8O80XMgyOT8f0EFR8G+e6niORJk8GIlW2ZlQfIMJOYZyF
 T4NEJXWYpW5G6FFORJLiAFDvC9VXrj/F2bGZa0NjhaePCmdRTdwlyv2GNJvrO6B/
 /3oFpCBRGJ/3P9Pns+hy4ry/7TRkzIHw1OGv4XCbGnS8zQD7hXb1ljkpewReZVdm
 srY6oLRmL9j+k7WIHMIHXyg+nv0DT8WCGrw32Rz074HJJVJwDo0xo1vEHevp76SW
 BW6OtoaaiIbRYQgXM2Qbcf7BH0jxmduIfhrchTzQSHWa7K8uaqyLYTUPv9WA/JE=
 =lL8N
 -END PGP SIGNATURE-


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v2 0/7] Add a generic struct clk

2011-09-22 Thread Mike Turquette
Hi all,

The goal of this series is to provide a cross-platform clock framework
that platforms can use to model their clock trees and perform common
operations on them.  Currently everyone re-invents their own clock tree
inside platform code which makes it impossible for drivers to use the
clock APIs safely across many platforms and for distro's to compile
multi-platform kernels which all redefine struct clk and its operations.

This is the second version of the common clock patches which were
originally posted by Jeremy Kerr and then re-posted with some additional
patches by Mark Brown.  Mark's re-post didn't have any changes done to
the original four patches from Jeremy which is why this series is v2.

The changes in this series are minimal: I've folded in some of Mark's
fixes and most of the comments posted to his series as well as rebasing
on top of v3.1-rc7.  The design and functionality hasn't changed much
since Jeremy posted v1 of this series.  Propagating the rate change up
to the parent has been removed from clk_set_rate since that needs some
more thought.  I also dropped Mark's change to append a device's name to
a clk name since device tree might solve this neatly.  Again more
discussion around that would be good.

v1 of the series can be found at,
http://article.gmane.org/gmane.linux.kernel/1143182

Mark's re-post (v1+) can be found at,
http://article.gmane.org/gmane.linux.ports.arm.kernel/129889

Todo in follow-up patches:
clk_set_parent
Implement a *safe* upstream propagation for parent rate changes
Track tree topology and export to userspace (sysfs or debugfs)
Manage root clocks globally
Device tree support
Per-tree locking instead of framework-wide locking
Device driver rate-change notifiers

Jeremy Kerr (4):
  clk: Add a generic clock infrastructure
  clk: Implement clk_set_rate
  clk: Add fixed-rate clock
  clk: Add simple gated clock

Mark Brown (3):
  clk: Add Kconfig option to build all generic clk drivers
  clk: Add initial WM831x clock driver
  x86: Enable generic clk API on x86

 MAINTAINERS  |1 +
 arch/x86/Kconfig |1 +
 drivers/clk/Kconfig  |   27 +++-
 drivers/clk/Makefile |4 +
 drivers/clk/clk-fixed.c  |   24 +++
 drivers/clk/clk-gate.c   |   78 ++
 drivers/clk/clk-wm831x.c |  386 ++
 drivers/clk/clk.c|  291 ++
 drivers/clk/clkdev.c |7 +
 include/linux/clk.h  |  179 --
 10 files changed, 985 insertions(+), 13 deletions(-)
 create mode 100644 drivers/clk/clk-fixed.c
 create mode 100644 drivers/clk/clk-gate.c
 create mode 100644 drivers/clk/clk-wm831x.c
 create mode 100644 drivers/clk/clk.c

-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v2 3/7] clk: Add fixed-rate clock

2011-09-22 Thread Mike Turquette
From: Jeremy Kerr jeremy.k...@canonical.com

Signed-off-by: Jeremy Kerr jeremy.k...@canonical.com
Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
Signed-off-by: Mike Turquette mturque...@ti.com
---
Changes since v1:
Add copyright header

 drivers/clk/Kconfig |4 
 drivers/clk/Makefile|1 +
 drivers/clk/clk-fixed.c |   24 
 include/linux/clk.h |   14 ++
 4 files changed, 43 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/clk-fixed.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c53ed59..d8313d7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -8,3 +8,7 @@ config HAVE_MACH_CLKDEV
 
 config GENERIC_CLK
bool
+
+config GENERIC_CLK_FIXED
+   bool
+   depends on GENERIC_CLK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 570d5b9..9a3325a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,4 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
 obj-$(CONFIG_GENERIC_CLK)  += clk.o
+obj-$(CONFIG_GENERIC_CLK_FIXED)+= clk-fixed.o
diff --git a/drivers/clk/clk-fixed.c b/drivers/clk/clk-fixed.c
new file mode 100644
index 000..956fb9a
--- /dev/null
+++ b/drivers/clk/clk-fixed.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.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.
+ *
+ * Simple fixed-rate clock implementation
+ */
+
+#include linux/clk.h
+#include linux/module.h
+
+#define to_clk_fixed(c) container_of(c, struct clk_hw_fixed, hw)
+
+static unsigned long clk_fixed_recalc_rate(struct clk_hw *hw)
+{
+   return to_clk_fixed(hw)-rate;
+}
+
+struct clk_hw_ops clk_fixed_ops = {
+   .recalc_rate = clk_fixed_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0d2cd5e..1903dd8 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -110,6 +110,20 @@ int clk_prepare(struct clk *clk);
  */
 void clk_unprepare(struct clk *clk);
 
+/* Base clock implementations. Platform clock implementations can use these
+ * directly, or 'subclass' as approprate */
+
+#ifdef CONFIG_GENERIC_CLK_FIXED
+
+struct clk_hw_fixed {
+   struct clk_hw   hw;
+   unsigned long   rate;
+};
+
+extern struct clk_hw_ops clk_fixed_ops;
+
+#endif /* CONFIG_GENERIC_CLK_FIXED */
+
 /**
  * clk_register - register and initialize a new clock
  *
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v2 4/7] clk: Add simple gated clock

2011-09-22 Thread Mike Turquette
From: Jeremy Kerr jeremy.k...@canonical.com

Signed-off-by: Jeremy Kerr jeremy.k...@canonical.com
Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
Signed-off-by: Jamie Iles ja...@jamieiles.com
Signed-off-by: Mike Turquette mturque...@ti.com
---
Changes since v1:
Add copyright header
Fold in Jamie's patch for set-to-disable clks
Use BIT macro instead of shift

 drivers/clk/Kconfig|4 ++
 drivers/clk/Makefile   |1 +
 drivers/clk/clk-gate.c |   78 
 include/linux/clk.h|   13 
 4 files changed, 96 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/clk-gate.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index d8313d7..a78967c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -12,3 +12,7 @@ config GENERIC_CLK
 config GENERIC_CLK_FIXED
bool
depends on GENERIC_CLK
+
+config GENERIC_CLK_GATE
+   bool
+   depends on GENERIC_CLK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 9a3325a..d186446 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
 obj-$(CONFIG_GENERIC_CLK)  += clk.o
 obj-$(CONFIG_GENERIC_CLK_FIXED)+= clk-fixed.o
+obj-$(CONFIG_GENERIC_CLK_GATE) += clk-gate.o
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
new file mode 100644
index 000..a1d8e79
--- /dev/null
+++ b/drivers/clk/clk-gate.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.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.
+ *
+ * Simple clk gate implementation
+ */
+
+#include linux/clk.h
+#include linux/module.h
+#include asm/io.h
+
+#define to_clk_gate(clk) container_of(clk, struct clk_gate, hw)
+
+static unsigned long clk_gate_get_rate(struct clk_hw *clk)
+{
+   return clk_get_rate(clk_get_parent(clk-clk));
+}
+
+static void clk_gate_set_bit(struct clk_hw *clk)
+{
+   struct clk_gate *gate = to_clk_gate(clk);
+   u32 reg;
+
+   reg = __raw_readl(gate-reg);
+   reg |= BIT(gate-bit_idx);
+   __raw_writel(reg, gate-reg);
+}
+
+static void clk_gate_clear_bit(struct clk_hw *clk)
+{
+   struct clk_gate *gate = to_clk_gate(clk);
+   u32 reg;
+
+   reg = __raw_readl(gate-reg);
+   reg = ~BIT(gate-bit_idx);
+   __raw_writel(reg, gate-reg);
+}
+
+static int clk_gate_enable_set(struct clk_hw *clk)
+{
+   clk_gate_set_bit(clk);
+
+   return 0;
+}
+
+static void clk_gate_disable_clear(struct clk_hw *clk)
+{
+   clk_gate_clear_bit(clk);
+}
+
+struct clk_hw_ops clk_gate_set_enable_ops = {
+   .recalc_rate = clk_gate_get_rate,
+   .enable = clk_gate_enable_set,
+   .disable = clk_gate_disable_clear,
+};
+EXPORT_SYMBOL_GPL(clk_gate_set_enable_ops);
+
+static int clk_gate_enable_clear(struct clk_hw *clk)
+{
+   clk_gate_clear_bit(clk);
+
+   return 0;
+}
+
+static void clk_gate_disable_set(struct clk_hw *clk)
+{
+   clk_gate_set_bit(clk);
+}
+
+struct clk_hw_ops clk_gate_set_disable_ops = {
+   .recalc_rate = clk_gate_get_rate,
+   .enable = clk_gate_enable_clear,
+   .disable = clk_gate_disable_set,
+};
+EXPORT_SYMBOL_GPL(clk_gate_set_disable_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1903dd8..626fd0d 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -124,6 +124,19 @@ extern struct clk_hw_ops clk_fixed_ops;
 
 #endif /* CONFIG_GENERIC_CLK_FIXED */
 
+#ifdef CONFIG_GENERIC_CLK_GATE
+
+struct clk_gate {
+   struct clk_hw   hw;
+   void __iomem*reg;
+   u8  bit_idx;
+};
+
+extern struct clk_hw_ops clk_gate_set_enable_ops;
+extern struct clk_hw_ops clk_gate_set_disable_ops;
+
+#endif /* CONFIG_GENERIC_CLK_GATE */
+
 /**
  * clk_register - register and initialize a new clock
  *
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v2 2/7] clk: Implement clk_set_rate

2011-09-22 Thread Mike Turquette
From: Jeremy Kerr jeremy.k...@canonical.com

Implement clk_set_rate by adding a set_rate callback to clk_hw_ops.
Rates are propagated down the clock tree and recalculated.  Also adds a
flag for signaling that parents must change rates to achieve the desired
frequency (upstream propagation).

TODO:
Upstream propagation is not yet implemented.
Device pre-change and post-change notifications are not implemented, but
are marked up as FIXME comments.

Signed-off-by: Jeremy Kerr jeremy.k...@canonical.com
Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
Signed-off-by: Mike Turquette mturque...@ti.com
---
Changes since v1:
Remove upstream propagation (for now)
Rename CLK_SET_RATE_PROPAGATE to CLK_PARENT_RATE_CHANGE

 drivers/clk/clk.c   |   71 ++
 include/linux/clk.h |   12 
 2 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1cd7315..86636c2 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -21,6 +21,8 @@ struct clk {
unsigned intenable_count;
unsigned intprepare_count;
struct clk  *parent;
+   struct hlist_head   children;
+   struct hlist_node   child_node;
unsigned long   rate;
 };
 
@@ -176,10 +178,57 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
+/*
+ * clk_recalc_rates - Given a clock (with a recently updated clk-rate),
+ * notify its children that the rate may need to be recalculated, using
+ * ops-recalc_rate().
+ */
+static void clk_recalc_rates(struct clk *clk)
+{
+   struct hlist_node *tmp;
+   struct clk *child;
+
+   if (clk-ops-recalc_rate)
+   clk-rate = clk-ops-recalc_rate(clk-hw);
+
+   /* FIXME add post-rate change notification here */
+
+   hlist_for_each_entry(child, tmp, clk-children, child_node)
+   clk_recalc_rates(child);
+}
+
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
-   /* not yet implemented */
-   return -ENOSYS;
+   unsigned long parent_rate, new_rate;
+   int ret = 0;
+
+   if (!clk-ops-set_rate)
+   return -ENOSYS;
+
+   new_rate = rate;
+
+   /* prevent racing with updates to the clock topology */
+   mutex_lock(prepare_lock);
+
+   /* FIXME add pre-rate change notification here */
+
+   ret = clk-ops-set_rate(clk-hw, new_rate, parent_rate);
+
+   /* FIXME ignores CLK_PARENT_RATE_CHANGE */
+   if (ret  0)
+   /* FIXME add rate change abort notification here */
+   goto out;
+
+   /*
+* If successful recalculate the rates of the clock, including
+* children.
+*/
+   clk_recalc_rates(clk);
+
+out:
+   mutex_unlock(prepare_lock);
+
+   return ret;
 }
 EXPORT_SYMBOL_GPL(clk_set_rate);
 
@@ -216,16 +265,26 @@ struct clk *clk_register(const struct clk_hw_ops *ops, 
struct clk_hw *hw,
clk-hw = hw;
hw-clk = clk;
 
-   /* Query the hardware for parent and initial rate */
+   /*
+* Query the hardware for parent and initial rate. We may alter
+* the clock topology, making this clock available from the parent's
+* children list. So, we need to protect against concurrent
+* accesses through set_rate
+*/
+   mutex_lock(prepare_lock);
 
-   if (clk-ops-get_parent)
-   /* We don't to lock against prepare/enable here, as
-* the clock is not yet accessible from anywhere */
+   if (clk-ops-get_parent) {
clk-parent = clk-ops-get_parent(clk-hw);
+   if (clk-parent)
+   hlist_add_head(clk-child_node,
+   clk-parent-children);
+   }
 
if (clk-ops-recalc_rate)
clk-rate = clk-ops-recalc_rate(clk-hw);
 
+   mutex_unlock(prepare_lock);
+
 
return clk;
 }
diff --git a/include/linux/clk.h b/include/linux/clk.h
index d6ae10b..0d2cd5e 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -58,6 +58,12 @@ struct clk_hw {
  * parent. Currently only called when the clock is first
  * registered.
  *
+ * @set_rate   Change the rate of this clock. If this callback returns
+ * CLK_SET_RATE_PROPAGATE, the rate change will be propagated to
+ * the parent clock (which may propagate again). The requested
+ * rate of the parent is passed back from the callback in the
+ * second 'unsigned long *' argument.
+ *
  * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
  * implementations to split any work between atomic (enable) and sleepable
  * (prepare) contexts.  If a clock requires sleeping code to be turned on, this
@@ -76,9 +82,15 @@ struct clk_hw_ops {
void(*disable)(struct clk_hw *);
unsigned long

[PATCH v2 7/7] x86: Enable generic clk API on x86

2011-09-22 Thread Mike Turquette
From: Mark Brown broo...@opensource.wolfsonmicro.com

Enable the generic clk API on x86, enabling use of the API by drivers for
x86 modules and also improving build coverage for clock API using devices.

Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
---
No change since v1

 arch/x86/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 6a47bb2..571b2c5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -73,6 +73,7 @@ config X86
select HAVE_BPF_JIT if (X86_64  NET)
select CLKEVT_I8253
select ARCH_HAVE_NMI_SAFE_CMPXCHG
+   select GENERIC_CLK
 
 config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS)
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v2 5/7] clk: Add Kconfig option to build all generic clk drivers

2011-09-22 Thread Mike Turquette
From: Mark Brown broo...@opensource.wolfsonmicro.com

Currently drivers for the generic clk subsystem must be selected by
platforms using them in order to enable build. When doing development on
the API or generic build time testing it is useful to be able to build
unused drivers in order to improve coverage so supply a Kconfig option
which allows this.

Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
---
No change since v1

 drivers/clk/Kconfig |   11 ++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a78967c..95b42a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -1,4 +1,3 @@
-
 config CLKDEV_LOOKUP
bool
select HAVE_CLK
@@ -9,6 +8,16 @@ config HAVE_MACH_CLKDEV
 config GENERIC_CLK
bool
 
+config GENERIC_CLK_BUILD_TEST
+   bool Build all generic clock drivers
+   depends on EXPERIMENTAL  GENERIC_CLK
+   select GENERIC_CLK_FIXED
+   select GENERIC_CLK_GATE
+   help
+  Enable all possible generic clock drivers.  This is only
+  useful for improving build coverage, it is not useful for
+  production kernel builds.
+
 config GENERIC_CLK_FIXED
bool
depends on GENERIC_CLK
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v2 6/7] clk: Add initial WM831x clock driver

2011-09-22 Thread Mike Turquette
From: Mark Brown broo...@opensource.wolfsonmicro.com

The WM831x and WM832x series of PMICs contain a flexible clocking
subsystem intended to provide always on and system core clocks.  It
features:

- A 32.768kHz crystal oscillator which can optionally be used to pass
  through an externally generated clock.
- A FLL which can be clocked from either the 32.768kHz oscillator or
  the CLKIN pin.
- A CLKOUT pin which can bring out either the oscillator or the FLL
  output.
- The 32.768kHz clock can also optionally be brought out on the GPIO
  pins of the device.

This driver fully supports the 32.768kHz oscillator and CLKOUT.  The FLL
is supported only in AUTO mode, the full flexibility of the FLL cannot
currently be used.  The use of clock references other than the internal
oscillator is not currently supported, and since clk_set_parent() is not
implemented in the generic clock API the clock tree configuration cannot
be changed at runtime.

Due to a lack of access to systems where the core SoC has been converted
to use the generic clock API this driver has been compile tested only.

Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
Signed-off-by: Mike Turquette mturque...@ti.com
---
Changes since v1:
Changed CLK_SET_RATE_PROPAGATE to CLK_PARENT_RATE_CHANGE
Converted to clk_register to the original style, without passing in
struct device *dev.  This is due to Mark's clock name collision
patch being dropped.

 MAINTAINERS  |1 +
 drivers/clk/Kconfig  |5 +
 drivers/clk/Makefile |1 +
 drivers/clk/clk-wm831x.c |  386 ++
 4 files changed, 393 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/clk-wm831x.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ae8820e..a100ea0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7208,6 +7208,7 @@ T:git 
git://opensource.wolfsonmicro.com/linux-2.6-audioplus
 W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
 S: Supported
 F: Documentation/hwmon/wm83??
+F: drivers/clk/clk-wm83*.c
 F: drivers/leds/leds-wm83*.c
 F: drivers/input/misc/wm831x-on.c
 F: drivers/input/touchscreen/wm831x-ts.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 95b42a3..8aca5ab 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -13,6 +13,7 @@ config GENERIC_CLK_BUILD_TEST
depends on EXPERIMENTAL  GENERIC_CLK
select GENERIC_CLK_FIXED
select GENERIC_CLK_GATE
+   select GENERIC_CLK_WM831X if MFD_WM831X=y
help
   Enable all possible generic clock drivers.  This is only
   useful for improving build coverage, it is not useful for
@@ -25,3 +26,7 @@ config GENERIC_CLK_FIXED
 config GENERIC_CLK_GATE
bool
depends on GENERIC_CLK
+
+config GENERIC_CLK_WM831X
+   tristate
+   depends on GENERIC_CLK  MFD_WM831X
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d186446..6628ad5 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
 obj-$(CONFIG_GENERIC_CLK)  += clk.o
 obj-$(CONFIG_GENERIC_CLK_FIXED)+= clk-fixed.o
 obj-$(CONFIG_GENERIC_CLK_GATE) += clk-gate.o
+obj-$(CONFIG_GENERIC_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
new file mode 100644
index 000..bfcbcb5
--- /dev/null
+++ b/drivers/clk/clk-wm831x.c
@@ -0,0 +1,386 @@
+/*
+ * WM831x clock control
+ *
+ * Copyright 2011 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown broo...@opensource.wolfsonmicro.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include linux/clk.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/platform_device.h
+#include linux/mfd/wm831x/core.h
+
+struct wm831x_clk {
+   struct wm831x *wm831x;
+   struct clk_hw xtal_hw;
+   struct clk_hw fll_hw;
+   struct clk_hw clkout_hw;
+   bool xtal_ena;
+};
+
+static int wm831x_xtal_enable(struct clk_hw *hw)
+{
+   struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
+ xtal_hw);
+
+   if (clkdata-xtal_ena)
+   return 0;
+   else
+   return -EPERM;
+}
+
+static unsigned long wm831x_xtal_recalc_rate(struct clk_hw *hw)
+{
+   struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
+ xtal_hw);
+
+   if (clkdata-xtal_ena)
+   return 32768;
+   else
+   return 0;
+}
+
+static long wm831x_xtal_round_rate(struct clk_hw *hw, unsigned long rate)
+{
+   return wm831x_xtal_recalc_rate(hw);
+}
+
+static const struct clk_hw_ops wm831x_xtal_ops

[PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-09-22 Thread Mike Turquette
From: Jeremy Kerr jeremy.k...@canonical.com

We currently have ~21 definitions of struct clk in the ARM architecture,
each defined on a per-platform basis. This makes it difficult to define
platform- (or architecture-) independent clock sources without making
assumptions about struct clk, and impossible to compile two
platforms with different struct clks into a single image.

This change is an effort to unify struct clk where possible, by defining
a common struct clk, and a set of clock operations. Different clock
implementations can set their own operations, and have a standard
interface for generic code. The callback interface is exposed to the
kernel proper, while the clock implementations only need to be seen by
the platform internals.

The interface is split into two halves:

 * struct clk, which is the generic-device-driver interface. This
   provides a set of functions which drivers may use to request
   enable/disable, query or manipulate in a hardware-independent manner.

 * struct clk_hw and struct clk_hw_ops, which is the hardware-specific
   interface. Clock drivers implement the ops, which allow the core
   clock code to implement the generic 'struct clk' API.

This allows us to share clock code among platforms, and makes it
possible to dynamically create clock devices in platform-independent
code.

Platforms can enable the generic struct clock through
CONFIG_GENERIC_CLK. In this case, the clock infrastructure consists of a
common, opaque struct clk, and a set of clock operations (defined per
type of clock):

  struct clk_hw_ops {
int (*prepare)(struct clk_hw *);
void(*unprepare)(struct clk_hw *);
int (*enable)(struct clk_hw *);
void(*disable)(struct clk_hw *);
unsigned long   (*recalc_rate)(struct clk_hw *);
int (*set_rate)(struct clk_hw *,
unsigned long, unsigned long *);
long(*round_rate)(struct clk_hw *, unsigned long);
int (*set_parent)(struct clk_hw *, struct clk *);
struct clk *(*get_parent)(struct clk_hw *);
  };

Platform clock code can register a clock through clk_register, passing a
set of operations, and a pointer to hardware-specific data:

  struct clk_hw_foo {
struct clk_hw clk;
void __iomem *enable_reg;
  };

  #define to_clk_foo(c) offsetof(c, clk_hw_foo, clk)

  static int clk_foo_enable(struct clk_hw *clk)
  {
struct clk_foo *foo = to_clk_foo(clk);
raw_writeb(foo-enable_reg, 1);
return 0;
  }

  struct clk_hw_ops clk_foo_ops = {
.enable = clk_foo_enable,
  };

And in the platform initialisation code:

  struct clk_foo my_clk_foo;

  void init_clocks(void)
  {
my_clk_foo.enable_reg = ioremap(...);

clk_register(clk_foo_ops, my_clk_foo, NULL);
  }

Changes from Thomas Gleixner t...@linutronix.de.

The common clock definitions are based on a development patch from Ben
Herrenschmidt b...@kernel.crashing.org.

TODO:

 * We don't keep any internal reference to the clock topology at present.

Signed-off-by: Jeremy Kerr jeremy.k...@canonical.com
Signed-off-by: Thomas Gleixner t...@linutronix.de
Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
Signed-off-by: Mike Turquette mturque...@ti.com
---
Changes since v1:
Create a dummy clk_unregister and prototype/document it and clk_register
Constify struct clk_hw_ops
Remove spinlock.h header, include kernel.h
Use EOPNOTSUPP instead of ENOTSUPP
Add might_sleep to clk_prepare/clk_unprepare stubs
Properly init children hlist and child_node
Whitespace and typo fixes

 drivers/clk/Kconfig  |3 +
 drivers/clk/Makefile |1 +
 drivers/clk/clk.c|  232 ++
 drivers/clk/clkdev.c |7 ++
 include/linux/clk.h  |  140 +++---
 5 files changed, 371 insertions(+), 12 deletions(-)
 create mode 100644 drivers/clk/clk.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3530927..c53ed59 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -5,3 +5,6 @@ config CLKDEV_LOOKUP
 
 config HAVE_MACH_CLKDEV
bool
+
+config GENERIC_CLK
+   bool
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 07613fa..570d5b9 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)+= clkdev.o
+obj-$(CONFIG_GENERIC_CLK)  += clk.o
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
new file mode 100644
index 000..1cd7315
--- /dev/null
+++ b/drivers/clk/clk.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd jeremy.k...@canonical.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.
+ *
+ * Standard functionality for the common clock API.
+ */
+
+#include linux/clk.h

Re: cpuset configuration and measurements for power management

2011-08-23 Thread Mike Turquette
On Tue, Aug 23, 2011 at 6:07 AM, Vincent Guittot
vincent.guit...@linaro.org wrote:
 On 23 August 2011 14:41, Daniel Lezcano daniel.lezc...@linaro.org wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1


 Hi all,

 I did the following cpuset configuration:

 if [ ! -d /sys/fs/cgroup ]; then
        echo cgroup not supported by the kernel
 else
        mount -t cgroup cgroup /sys/fs/cgroup

        # needed to have the cgroup values inherited from
        # the parent cgroup
        echo 1  /sys/fs/cgroup/cgroup.clone_children

        # create an empty cgroup 'cpu0'
        mkdir /sys/fs/cgroup/cpu0

        # create an empty cgroup 'cpu1'
        mkdir /sys/fs/cgroup/cpu1

        # assign cpu number '0' for cgroup cpu0
        echo 0  /sys/fs/cgroup/cpu0/cpuset.cpus

        # move outself to this new cgroup
        echo $$  /sys/fs/cgroup/cpu0

        # move all the tasks to the cpu0 cgroup
        # kernel threads won't be moved, don't worry about the
        # the errors.
        for i in $(cat /sys/fs/cgroup/tasks); do
                echo $i  /sys/fs/cgroup/cpu0/tasks || echo failed to
 add pid $i/$(cat /proc/$i/comm)
        done

        # assign a cpu for cgroup cpu1
        echo 1  /sys/fs/cgroup/cpu1/cpuset.cpus

        # make cpu1 exclusive so processes belonging
        # to the other cgroups won't be able to use it.
        echo 1  /sys/fs/cgroup/cpu1/cpuset.cpu_exclusive
 fi


 At this point, most of the processes have been moved to the 'cpu0'
 cgroup and will use the cpu0 only. That does not prevent the cpu1 to be
 used by the kernel threads. Any application launched will run on cpu0 only.

 After running 10 infinite loops, the cpu accounting gives:

 cat /sys/fs/cgroup/cpu0/cpuacct.usage_percpu
 418943579549 0

 cat /sys/fs/cgroup/cpu1/cpuacct.usage_percpu
 0 0

 But the system is:

 cat /sys/fs/cgroup/cpuacct.usage_percpu
 456741213041 30734572583


 You should get the values before and after your tests and compute the
 difference. You should also read value of  /sys/fs/cgroup/ level where
 we still have kernel threads if i have understand your comments

 My guess is that reflects the kernel booted with the two cpus before we
 created the cgroup. I am investigation the 'isolcpus' kernel parameter.

 I think it is a good starting point to do some consumption measurements.

 Mike, Vincent, what do you think ? Do you need more informations or
 anything else ?


 Yes it's a good starting point. One key point will be to be sure to
 not use cpu1. In fact, we mainly have 2 power efficient states:  use
 equally the 2 cpus or use only one cpu and put the other one in a low
 power state.

This is true.  I did some rough power measurements last week using an
almost identical method to Daniel's and for a typical MP3 playback
(display off, no UI) I saw very little improvement on current draw
from the battery versus the same test without cpuset trickery.

I think Daniel's stuff is a great start and many many more
measurements must be done to get anywhere conclusive, but reducing
auxillary CPU wake-ups is critical to getting this method to work.

Regards,
Mike

 Vincent

 Thanks
  -- Daniel

 - --
  http://www.linaro.org/ Linaro.org │ Open source software for ARM SoCs

 Follow Linaro:  http://www.facebook.com/pages/Linaro Facebook |
 http://twitter.com/#!/linaroorg Twitter |
 http://www.linaro.org/linaro-blog/ Blog

 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.11 (GNU/Linux)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iQEcBAEBAgAGBQJOU6AVAAoJEAKBbMCpUGYAbQoH/0NeKLecIuMT57B/w1Jid/bn
 yzqD3zwMt0EfUwfsU6H5dAYgumMzKmWWXR9+7FvYhkcckXfzumiMLFKhIybrUSz/
 LW7ymHwxXcHWqBTKwMCasHzo9WhlRTlLA1pGAqo0qtG1IBpalE68ZRwItdY/HSOw
 0mDGoegq4DHQtcF64XwGRZJo2wAsamtlWGejFdqLQU4FONyYI42rLXMNAG6VD3vG
 CJrIudH5hLz3ZBdHYeRB6kWaj1O4skAW6fgySASiqFWoEaZzvT/7UuVBEYawpuyT
 Pm+U9OHAfHUWfnyDASFfx6ZQKRS5Uk40XzThjGgwoo598EN8FXZD3N6UZ1WmL2U=
 =H00Z
 -END PGP SIGNATURE-



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 2/6] cpumask: introduce cpumask for hotpluggable CPUs

2011-08-19 Thread Mike Turquette
On some platforms it is possible to have some CPUs which support CPU
hotplug and some which do not.  Currently the prescence of an 'online'
sysfs entry in userspace is adequate for applications to know that a CPU
supports hotplug, but there is no convenient way to make the same
determination in the kernel.

To better model this relationship this patch introduces a new cpumask to
track CPUs that support CPU hotplug operations.

This new cpumask is populated at boot-time and remains static for the
life of the machine.  Bits set in the mask indicate a CPU which supports
hotplug, but make no guarantees about whether that CPU is currently
online or not.  Likewise a cleared bit in the mask indicates either a
CPU which cannot hotplug or a lack of a populated CPU.

The purpose of this new cpumask is to aid kernel code which uses CPU to
take CPUs online and offline.  Possible uses are as a thermal event
mitigation technique or as a power capping mechanism.

Signed-off-by: Mike Turquette mturque...@ti.com
---
 include/linux/cpumask.h |   27 ++-
 kernel/cpu.c|   18 ++
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 4f7a632..3569cd3 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -39,10 +39,11 @@ extern int nr_cpu_ids;
  * The following particular system cpumasks and operations manage
  * possible, present, active and online cpus.
  *
- * cpu_possible_mask- has bit 'cpu' set iff cpu is populatable
- * cpu_present_mask - has bit 'cpu' set iff cpu is populated
- * cpu_online_mask  - has bit 'cpu' set iff cpu available to scheduler
- * cpu_active_mask  - has bit 'cpu' set iff cpu available to migration
+ * cpu_possible_mask - has bit 'cpu' set iff cpu is populatable
+ * cpu_hotpluggable_mask - has bit 'cpu' set iff cpu is hotpluggable
+ * cpu_present_mask  - has bit 'cpu' set iff cpu is populated
+ * cpu_online_mask   - has bit 'cpu' set iff cpu available to scheduler
+ * cpu_active_mask   - has bit 'cpu' set iff cpu available to migration
  *
  *  If !CONFIG_HOTPLUG_CPU, present == possible, and active == online.
  *
@@ -51,7 +52,11 @@ extern int nr_cpu_ids;
  *  life of that system boot.  The cpu_present_mask is dynamic(*),
  *  representing which CPUs are currently plugged in.  And
  *  cpu_online_mask is the dynamic subset of cpu_present_mask,
- *  indicating those CPUs available for scheduling.
+ *  indicating those CPUs available for scheduling.  The
+ *  cpu_hotpluggable_mask is also fixed at boot time as the set of CPU
+ *  id's which are possible AND can hotplug.  Cleared bits in this mask
+ *  mean that either the CPU is not possible, or it is possible but does
+ *  not support CPU hotplug operations.
  *
  *  If HOTPLUG is enabled, then cpu_possible_mask is forced to have
  *  all NR_CPUS bits set, otherwise it is just the set of CPUs that
@@ -61,6 +66,9 @@ extern int nr_cpu_ids;
  *  depending on what ACPI reports as currently plugged in, otherwise
  *  cpu_present_mask is just a copy of cpu_possible_mask.
  *
+ *  If HOTPLUG is not enabled then cpu_hotpluggable_mask is the empty
+ *  set.
+ *
  *  (*) Well, cpu_present_mask is dynamic in the hotplug case.  If not
  *  hotplug, it's a copy of cpu_possible_mask, hence fixed at boot.
  *
@@ -76,6 +84,7 @@ extern int nr_cpu_ids;
  */
 
 extern const struct cpumask *const cpu_possible_mask;
+extern const struct cpumask *const cpu_hotpluggable_mask;
 extern const struct cpumask *const cpu_online_mask;
 extern const struct cpumask *const cpu_present_mask;
 extern const struct cpumask *const cpu_active_mask;
@@ -85,19 +94,23 @@ extern const struct cpumask *const cpu_active_mask;
 #define num_possible_cpus()cpumask_weight(cpu_possible_mask)
 #define num_present_cpus() cpumask_weight(cpu_present_mask)
 #define num_active_cpus()  cpumask_weight(cpu_active_mask)
+#define num_hotpluggable_cpus()cpumask_weight(cpu_hotpluggable_mask)
 #define cpu_online(cpu)cpumask_test_cpu((cpu), cpu_online_mask)
 #define cpu_possible(cpu)  cpumask_test_cpu((cpu), cpu_possible_mask)
 #define cpu_present(cpu)   cpumask_test_cpu((cpu), cpu_present_mask)
 #define cpu_active(cpu)cpumask_test_cpu((cpu), cpu_active_mask)
+#define cpu_hotpluggable(cpu)  cpumask_test_cpu((cpu), cpu_hotpluggable_mask)
 #else
 #define num_online_cpus()  1U
 #define num_possible_cpus()1U
 #define num_present_cpus() 1U
 #define num_active_cpus()  1U
+#define num_hotpluggable_cpus()0
 #define cpu_online(cpu)((cpu) == 0)
 #define cpu_possible(cpu)  ((cpu) == 0)
 #define cpu_present(cpu)   ((cpu) == 0)
 #define cpu_active(cpu)((cpu) == 0)
+#define cpu_hotpluggable(cpu)  0
 #endif
 
 /* verify cpu argument to cpumask_* operators */
@@ -692,16 +705,20 @@ extern const DECLARE_BITMAP(cpu_all_bits

[PATCH 3/6] cpu: update cpu_hotpluggable_mask in register_cpu

2011-08-19 Thread Mike Turquette
Update the cpu_hotpluggable_mask for each registered CPU which supports
hotplug.  This makes it trivial for kernel code to know which CPUs
support hotplug operations.

Signed-off-by: Mike Turquette mturque...@ti.com
---
 drivers/base/cpu.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 251acea..91ddcf8 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -224,8 +224,10 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
 
error = sysdev_register(cpu-sysdev);
 
-   if (!error  cpu-hotpluggable)
+   if (!error  cpu-hotpluggable) {
register_cpu_control(cpu);
+   set_cpu_hotpluggable(num, true);
+   }
if (!error)
per_cpu(cpu_sys_devices, num) = cpu-sysdev;
if (!error)
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 0/6] CPUoffline framework

2011-08-19 Thread Mike Turquette
This series is posted for posterity.  It has been NAK'd by the community
since CPU hotplug has been deemed an inappropriate mechanism for power
capping.

CPUoffline is a framework for taking CPU's offline via the hotplug
mechanism.  The framework itself is quite straightforward: a driver
arranges the CPUs into partitions.  Each partition is associated to a
governor thread and that thread implements a policy for taking CPUs in
that partition offline or online, based on some heuristic.

The CPUoffline core code includes a default driver that places all
possible CPUs into a single partition, requiring no code to be written
for a new platform.  There is also a single governor named avgload
which looks at the average load of all of the *online* CPUs in a
partition and makes a hotplug decision based on defined thresholds.

This framework owes a lot to CPUfreq and CPUidle, from which CPUoffline
stole^H^H^H^H^H borrowed lots of code.

Note: since development was cut short to community response, there are
some missing infrastructure bits such as module unregistration and
dynamic govenor switching.  The code does work fine as-is for the
curious-minded who want to test on an SMP system that supports hotplug.

Mike Turquette (6):
  ARM: do not mark CPU 0 as hotpluggable
  cpumask: introduce cpumask for hotpluggable CPUs
  cpu: update cpu_hotpluggable_mask in register_cpu
  cpuoffline core
  governors
  arm kconfig

 arch/arm/Kconfig   |2 +
 arch/arm/kernel/setup.c|3 +-
 drivers/Makefile   |1 +
 drivers/base/cpu.c |4 +-
 drivers/cpuoffline/Kconfig |   26 ++
 drivers/cpuoffline/Makefile|2 +
 drivers/cpuoffline/cpuoffline.c|  488 
 drivers/cpuoffline/governors/Kconfig   |9 +
 drivers/cpuoffline/governors/Makefile  |2 +
 drivers/cpuoffline/governors/avgload.c |  255 +
 include/linux/cpumask.h|   27 ++-
 include/linux/cpuoffline.h |   82 ++
 kernel/cpu.c   |   18 ++
 13 files changed, 912 insertions(+), 7 deletions(-)
 create mode 100644 drivers/cpuoffline/Kconfig
 create mode 100644 drivers/cpuoffline/Makefile
 create mode 100644 drivers/cpuoffline/cpuoffline.c
 create mode 100644 drivers/cpuoffline/governors/Kconfig
 create mode 100644 drivers/cpuoffline/governors/Makefile
 create mode 100644 drivers/cpuoffline/governors/avgload.c
 create mode 100644 include/linux/cpuoffline.h

-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 1/6] ARM: do not mark CPU 0 as hotpluggable

2011-08-19 Thread Mike Turquette
A quick poll of the ARM platforms that implement CPU Hotplug support
shows that every platform treats CPU 0 as a special case that cannot be
hotplugged.  In fact every platform has identical code for
platform_cpu_die which returns -EPERM in the case of CPU 0.

The user-facing sysfs interfaces should reflect this by not populating
an 'online' entry for CPU 0 at all.  This better reflects reality by
making it clear to users that CPU 0 cannot be hotplugged.

This patch prevents CPU 0 from being marked as hotpluggable on all ARM
platforms during CPU registration.  This in turn prevents the creation
of an 'online' sysfs interface for that CPU.

Signed-off-by: Mike Turquette mturque...@ti.com
---
 arch/arm/kernel/setup.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 70bca64..5f3f4bb 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -949,7 +949,8 @@ static int __init topology_init(void)
 
for_each_possible_cpu(cpu) {
struct cpuinfo_arm *cpuinfo = per_cpu(cpu_data, cpu);
-   cpuinfo-cpu.hotpluggable = 1;
+   if (cpu)
+   cpuinfo-cpu.hotpluggable = 1;
register_cpu(cpuinfo-cpu, cpu);
}
 
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 6/6] arm kconfig

2011-08-19 Thread Mike Turquette
---
 arch/arm/Kconfig |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2c71a8f..5804b21 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1980,6 +1980,8 @@ endif
 
 source drivers/cpuidle/Kconfig
 
+source drivers/cpuoffline/Kconfig
+
 endmenu
 
 menu Floating point emulation
-- 
1.7.4.1


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


  1   2   >