Re: [PATCH PM-QA] cputopology: add scheduler domain flag test
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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
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
+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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- 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