Hi All,
This is V2 Resend of my sched_select_cpu() work. Resend because didn't got much
attention on V2. Including more guys now in cc :)
In order to save power, it would be useful to schedule work onto non-IDLE cpus
instead of waking up an IDLE one.
To achieve this, we need scheduler to guide kernel frameworks (like: timers &
workqueues) on which is the most preferred CPU that must be used for these
tasks.
This patchset is about implementing this concept.
- The first patch adds sched_select_cpu() routine which returns the preferred
cpu which is non-idle.
- Second patch removes idle_cpu() calls from timer & hrtimer.
- Third patch is about adapting this change in workqueue framework.
- Fourth patch add migration capability in running timer
Earlier discussions over v1 can be found here:
http://www.mail-archive.com/linaro-dev@lists.linaro.org/msg13342.html
Earlier discussions over this concept were done at last LPC:
http://summit.linuxplumbersconf.org/lpc-2012/meeting/90/lpc2012-sched-timer…
Module created for testing this behavior is present here:
http://git.linaro.org/gitweb?p=people/vireshk/module.git;a=summary
Following are the steps followed in test module:
1. Run single work on each cpu
2. This work will start a timer after x (tested with 10) jiffies of delay
3. Timer routine queues a work... (This may be called from idle or non-idle cpu)
and starts the same timer again STEP 3 is done for n number of times (i.e.
queuing n works, one after other)
4. All works will call a single routine, which will count following per cpu:
- Total works processed by a CPU
- Total works processed by a CPU, which are queued from it
- Total works processed by a CPU, which aren't queued from it
Setup:
-----
- ARM Vexpress TC2 - big.LITTLE CPU
- Core 0-1: A15, 2-4: A7
- rootfs: linaro-ubuntu-nano
Results:
-------
Without Workqueue Modification, i.e. PATCH 3/3:
[ 2493.022335] Workqueue Analyser: works processsed by CPU0, Total: 1000, Own: 0, migrated: 0
[ 2493.047789] Workqueue Analyser: works processsed by CPU1, Total: 1000, Own: 0, migrated: 0
[ 2493.072918] Workqueue Analyser: works processsed by CPU2, Total: 1000, Own: 0, migrated: 0
[ 2493.098576] Workqueue Analyser: works processsed by CPU3, Total: 1000, Own: 0, migrated: 0
[ 2493.123702] Workqueue Analyser: works processsed by CPU4, Total: 1000, Own: 0, migrated: 0
With Workqueue Modification, i.e. PATCH 3/3:
[ 2493.022335] Workqueue Analyser: works processsed by CPU0, Total: 1002, Own: 999, migrated: 3
[ 2493.047789] Workqueue Analyser: works processsed by CPU1, Total: 998, Own: 997, migrated: 1
[ 2493.072918] Workqueue Analyser: works processsed by CPU2, Total: 1013, Own: 996, migrated: 17
[ 2493.098576] Workqueue Analyser: works processsed by CPU3, Total: 998, Own: 993, migrated: 5
[ 2493.123702] Workqueue Analyser: works processsed by CPU4, Total: 989, Own: 987, migrated: 2
V2->V2-Resend
-------------
- Included timer migration patch in the same thread.
V1->V2
-----
- New SD_* macros removed now and earlier ones used
- sched_select_cpu() rewritten and it includes the check on current cpu's
idleness.
- cpu_idle() calls from timer and hrtimer removed now.
- Patch 2/3 from V1, removed as it doesn't apply to latest workqueue branch from
tejun.
- CONFIG_MIGRATE_WQ removed and so is wq_select_cpu()
- sched_select_cpu() called only from __queue_work()
- got tejun/for-3.7 branch in my tree, before making workqueue changes.
Viresh Kumar (4):
sched: Create sched_select_cpu() to give preferred CPU for power
saving
timer: hrtimer: Don't check idle_cpu() before calling
get_nohz_timer_target()
workqueue: Schedule work on non-idle cpu instead of current one
timer: Migrate running timer
include/linux/sched.h | 16 ++++++++++--
include/linux/timer.h | 2 ++
kernel/hrtimer.c | 2 +-
kernel/sched/core.c | 69 +++++++++++++++++++++++++++++++--------------------
kernel/timer.c | 50 ++++++++++++++++++++++---------------
kernel/workqueue.c | 4 +--
6 files changed, 91 insertions(+), 52 deletions(-)
--
1.7.12.rc2.18.g61b472e
Hi Guys,
I really don't know whom to direct this mail to and hence the wide spread.
Problem: When we send a mail to kernel mailing lists with linaro-dev
or linaro-kernel
in cc, and we get replies to those mails, sometimes the mails from
outside people
doesn't reach us back on linaro mailing lists. And i hope the reason
behind that is
those people aren't subscribed to these lists.
For me it makes some sense to allow anyone to send mails to this list. Can that
request be considered?
I believe the idea behind blocking such use is for protecting against
spam mails, but
these mails/replies are really important and we certainly need them
delivered to us.
One solution (don't know if its possible) would be to monitor mails
from non-subscribers
and few people from Linaro can permit them on daily/hourly basis, so
that we don't get any
spam mails, but that would be a burden.
--
viresh
I am attaching a patch by Thomas Gleixner which adds a kernel
command line parameter to set the defauilt IRQ affinity mask. Could
you please integrate this in your tree for the next Linaro release?
I've been using this patch for sometime now and it doesn't introduce
any regressions. There is a possibility that this patch will make it
upstream via the RT patches in the near future but in the meanwhile,
we'd like to carry this patch as well.
Cheers,
Punit
>From 52a7d44f58a262e166575abc57aa0bd3bfc8cfbb Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx(a)linutronix.de>
Date: Fri, 25 May 2012 16:59:47 +0200
Subject: [PATCH] genirq: Add default affinity mask command line option
If we isolate CPUs, then we don't want random device interrupts on
them. Even w/o the user space irq balancer enabled we can end up with
irqs on non boot cpus.
Allow to restrict the default irq affinity mask.
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
---
Documentation/kernel-parameters.txt | 9 +++++++++
kernel/irq/irqdesc.c | 21 +++++++++++++++++++--
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 7d82468..00fedab 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1164,6 +1164,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
See comment before ip2_setup() in
drivers/char/ip2/ip2base.c.
+ irqaffinity= [SMP] Set the default irq affinity mask
+ Format:
+ <cpu number>,...,<cpu number>
+ or
+ <cpu number>-<cpu number>
+ (must be a positive range in ascending order)
+ or a mixture
+ <cpu number>,...,<cpu number>-<cpu number>
+
irqfixup [HW]
When an interrupt is not handled search all handlers
for it. Intended to get systems with badly broken
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 192a302..473b2b6 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -23,10 +23,27 @@
static struct lock_class_key irq_desc_lock_class;
#if defined(CONFIG_SMP)
+static int __init irq_affinity_setup(char *str)
+{
+ zalloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
+ cpulist_parse(str, irq_default_affinity);
+ /*
+ * Set at least the boot cpu. We don't want to end up with
+ * bugreports caused by random comandline masks
+ */
+ cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
+ return 1;
+}
+__setup("irqaffinity=", irq_affinity_setup);
+
static void __init init_irq_default_affinity(void)
{
- alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
- cpumask_setall(irq_default_affinity);
+#ifdef CONFIG_CPUMASK_OFFSTACK
+ if (!irq_default_affinity)
+ zalloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
+#endif
+ if (cpumask_empty(irq_default_affinity))
+ cpumask_setall(irq_default_affinity);
}
#else
static void __init init_irq_default_affinity(void)
--
1.7.9.5
Hi folks,
As a follow-up to my work in LEG on assembly scanning and optimisation
for AArch64, we're considering applying as a mentoring organisation
for the Google Summer of Code [1] this year. There's quite a lot of
code out there that may benefit from porting (whether for support of
AArch64 or for better performance) and I think we could usefully get
some students involved to help with this. I'm planning on doing the
bureacracy for the SoC application in the next few days.
So, the reason why I'm posting about that here: is anybody else
interested in joining in? Are there any other projects in/around
Linaro where:
a) a student could do some useful work;
b) we have somebody prepared to act as a mentor
? If so, please let me know. The more ideas we can suggest for summer
projects like this, the more likely we are to be accepted as a
mentoring organisation by Google.
[1] http://www.google-melange.com/gsoc/homepage/google/gsoc2013
Cheers,
--
Steve McIntyre steve.mcintyre(a)linaro.org
<http://www.linaro.org/> Linaro.org | Open source software for ARM SoCs
Hi,
I'm trying to cross build some packages for ubuntu quantal following this wiki:
https://wiki.linaro.org/Platform/DevPlatform/CrossCompile/UsingXdeb
we would like to be able to build packages like gstreamer.
today, I'm able to compile busybox and grep but no gstreamer or gstreamer plugins
Here is my HowTo:
sudo su
debootstrap quantal m-xdeb
chmod 777 m-xdeb/etc/apt/sources.list
vi m-xdeb/etc/apt/sources.list
deb [arch=armhf] http://ports.ubuntu.com/ quantal main universe
deb-src http://ports.ubuntu.com/ quantal main universe
deb http://archive.ubuntu.com/ubuntu quantal main universe
sudo chroot m-xdeb
mount -t proc proc /proc
mount -t devpts none /dev/pts
export LC_ALL=C
adduser build
adduser build sudo
apt-get update
apt-get install -y xdeb gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
dpkg --add-architecture armhf
exit
sudo chroot m-xdeb su - build
export LC_ALL=C
here are the results:
xdeb -a armhf --only-explicit --no-lintian --apt-source grep
OK
xdeb -a armhf --no-lintian --apt-source gstreamer1.0
Fails:
Dependency cycle: [u'cairo', u'libxt', u'glib2.0', u'dbus-python', u'dbus-glib']
xdeb -a armhf --only-explicit --no-lintian --apt-source gstreamer1.0
Fails:
/home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0.c:580:3: warning: implicit declaration of function 'gst_init' [-Wimplicit-function-declaration]
g-ir-scanner: link: ../libtool --mode=link --tag=CC arm-linux-gnueabihf-gcc -std=gnu99 -o /home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0 -export-dynamic /home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0.o -L. libgstreamer-1.0.la -Wl,--export-dynamic -pthread -L/usr/arm-linux-gnueabihf/lib -lgio-2.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0
libtool: link: arm-linux-gnueabihf-gcc -std=gnu99 -o /home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/.libs/Gst-1.0 /home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0.o -Wl,--export-dynamic -pthread -Wl,--export-dynamic -L. ./.libs/libgstreamer-1.0.so -L/usr/arm-linux-gnueabihf/lib -lgio-2.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 -pthread -Wl,-rpath -Wl,/usr/lib/arm-linux-gnueabihf
/home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0: line 117: /home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/.libs/lt-Gst-1.0: cannot execute binary file
/home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0: line 117: /home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/.libs/lt-Gst-1.0: Success
Command '['/home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/Gst-1.0', '--introspect-dump=/home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/functions.txt,/home/build/src/gstreamer1.0/gst/tmp-introspecteM6YUf/dump.xml']' returned non-zero exit status 126
make[5]: *** [Gst-1.0.gir] Error 1
( please find full trace attached)
xdeb -a armhf --only-explicit --no-lintian --apt-source gstreamer1.0-plugins-base
Fails:
...
===== Importing keyutils_1.5.5-3 =====
apt-get -oAPT::Architecture=armhf download keyutils:armhf
Get:1 Downloading keyutils 1.5.5-3 [30.3 kB]
Fetched 30.3 kB in 0s (55.9 kB/s)
apt-get -oAPT::Architecture=armhf download keyutils-dbg:armhf
Get:1 Downloading keyutils-dbg 1.5.5-3 [57.2 kB]
Fetched 57.2 kB in 0s (437 kB/s)
apt-get -oAPT::Architecture=armhf download libkeyutils1:armhf
Get:1 Downloading libkeyutils1 1.5.5-3 [6626 B]
Fetched 6626 B in 0s (19.9 kB/s)
apt-get -oAPT::Architecture=armhf download libkeyutils-dev:armhf
Get:1 Downloading libkeyutils-dev 1.5.5-3 [25.8 kB]
Fetched 25.8 kB in 0s (94.9 kB/s)
Traceback (most recent call last):
File "/usr/bin/xdeb", line 988, in <module>
main()
File "/usr/bin/xdeb", line 973, in main
native_import(options, src)
File "/usr/bin/xdeb", line 585, in native_import
crossed_debs = cross_convert(options, debs, options.builddirs[0])
File "/usr/bin/xdeb", line 484, in cross_convert
deb)).debcontrol()
File "/usr/lib/python2.7/dist-packages/debian/debfile.py", line 271, in __init__
compressed_part_name(DATA_PART)))
File "/usr/lib/python2.7/dist-packages/debian/debfile.py", line 256, in compressed_part_name
" (expected one of: %s)" % candidates)
debian.debfile.DebError: missing required part in given .deb (expected one of: ['data.tar.gz', 'data.tar.bz2', 'data.tar.lzma'])
I have tried to use repo quantal-updates with also bad result.
I have tried to use lower level tools, but I did not found a way to install cross build-deps
apt-get build-dep -aarmhf ... always fails like this:
sudo apt-get -oAPT::Architecture=armhf build-dep gstreamer1.0
[sudo] password for build:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages have unmet dependencies:
build-essential : Depends: dpkg-dev (>= 1.13.5) but it is not going to be installed
cdbs : Depends: dh-translations but it is not going to be installed
debhelper : Depends: dpkg-dev (>= 1.16.2) but it is not going to be installed
docbook-utils : Depends: docbook-dsssl but it is not going to be installed
Depends: jadetex but it is not going to be installed
gnome-pkg-tools : Depends: dh-translations but it is not going to be installed
gtk-doc-tools : Depends: docbook-dsssl but it is not going to be installed
Depends: docbook-xml (>= 4.3) but it is not going to be installed
Depends: docbook-xsl (>= 1.64.1.0) but it is not going to be installed
Depends: docbook-to-man but it is not going to be installed
Depends: gnome-common but it is not going to be installed
transfig : Depends: x11-common but it is not going to be installed
xmlto : Depends: docbook-xml (>= 4.2-8) but it is not going to be installed
Depends: docbook-xsl (>= 1.64.1.0) but it is not going to be installed
E: Build-dependencies for gstreamer1.0 could not be satisfied.
I guess I missed something... apt.conf ? sources.list... ?
Can somebody help me ?
best regards,
pascal
> Looks like the ll-20130320.0 kernel failed to boot on Arndale:
> http://validation.linaro.org/lava-server/scheduler/job/49985/log_file
>
> The build log is here:
> https://ci.linaro.org/jenkins/job/linux-linaro-tracking_arndale/62/consoleF…
>
>
> The kernel config has been made by the following command:
> 'ARCH=arm scripts/kconfig/merge_config.sh
> linaro/configs/linaro-base.conf linaro/configs/ubuntu-minimal.conf
> linaro/configs/arndale.conf linaro/configs/kvm-host.conf'
>
> Tushar,
> Have you tried this configuration?
>
> Thanks,
> Andrey
I have been observing this system hang when we enable LPAE on 3.9 based
llct, though the issue is not present with vanilla 3.9-rc kernel. Would
update later after I debug further.
Riku,
How much essential is it to enable LPAE support for KVM?
--
Tushar Behera
Hi Viresh,
(1) Recently I have done a lot of testing for the new RCU functionality
(new RCU FNOHZ implementation, updated RCU no-callback implementation)
which is scheduled for 3.11/3.12 mainline. In my tests it helped to keep
the A15's quiet and showed power savings for some workloads.
During last Linaro Connect people started to ask me if we can bring
these features in already earlier.
Would it be possible for you to merge in 'idlenocb.2013.03.18b' (based
on v3.9-rc2) (or newer) from
'git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git'
into your big.LITTLE MP tree? I talked to Paul McKenney about this and
he would like to have this additional test coverage.
I have performed the following tests: System comes up and pm-qa
(cpufreq, cpuidle, cpuhotplug) on nano and FTS (mpbasic, mpcore,
mpextended, mploadbalance, mpregression, pmump) on Android FS look good.
(2) On top of the merge, we must assure that the TC2 default config file
gets changed:
Change the config file:
* Set CONFIG_RCU_FAST_NO_HZ=y
* Set CONFIG_RCU_NOCB_CPU=y
* Set CONFIG_RCU_NOCB_CPU_ALL=y
diff -Naur config_orig .config
--- config_orig 2013-03-13 14:15:10.574248125 +0000
+++ .config 2013-03-13 14:15:34.334248346 +0000
@@ -93,9 +93,12 @@
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
-# CONFIG_RCU_FAST_NO_HZ is not set
+CONFIG_RCU_FAST_NO_HZ=y
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_RCU_NOCB_CPU=y
+# CONFIG_RCU_NOCB_CPU_NONE is not set
+# CONFIG_RCU_NOCB_CPU_ZERO is not set
+CONFIG_RCU_NOCB_CPU_ALL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
Cheers,
-- Dietmar
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
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-kernel&m=134507429302463&w=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
Hi,
There are many scripts in use that parse the web interface for
snapshots and releases.linaro.org. This is far from ideal because
changes to the web interface can result in the scripts breaking. To
alleviate this problem an API has been introduced. The API is very
simple, just two new URLs and a new header when downloading files.
<server>/api/ls/<path to file> returns a JSON document containing all the
data shown by a file listing on the web interface. It can target
either a directory of a file.
<server>/api/license/<path to file> returns a JSON document containing
the licence information for the file pointed to. Both the license text
and the digest used to accept the license are returned. Including the
digest means that the choice of digest used internally can change without
re-writing clients - to the client this is just a magic string and they
don't need to care how it is generated.
When downloading a file you simply include the header
LICENSE_ACCEPTED, its value being a space separated list of license
digests representing the licenses that you have accepted.
e.g.
(license text and digest removed for brevity)
http://snapshots.linaro.org/api/ls/quantal/hwpacks/snowball/latest
{
"files": [
{
"mtime": "15-Mar-2013 08:29",
"name":
"hwpack_linaro-snowball_20130315-269_armhf_supported.manifest.txt",
"size": "762",
"type": "text",
"url":
"/quantal/hwpacks/snowball/latest/hwpack_linaro-snowball_20130315-269_armhf_supported.manifest.txt"
},
{
"mtime": "15-Mar-2013 08:31",
"name":
"hwpack_linaro-snowball_20130315-269_armhf_supported.tar.gz",
"size": "18.1M",
"type": "other",
"url":
"/quantal/hwpacks/snowball/latest/hwpack_linaro-snowball_20130315-269_armhf_supported.tar.gz"
}
]
}
http://snapshots.linaro.org/api/license/quantal/hwpacks/snowball/latest/hwp…
{
"licenses": [
{
"text": "license text...",
"digest": "license digest..."
}
]
}
wget --header="LICENSE_ACCEPTED: license digest..."
http://snapshots.linaro.org/quantal/hwpacks/snowball/latest/hwpack_linaro-s…
There is a example client script that illustrates how to use the API here:
http://bazaar.launchpad.net/~linaro-automation/linaro-license-protection/tr…
Usage: download.py <URL>
If URL points to a directory all files are downloaded.
If URL points to a file, just that file is downloaded.
It prints the license(s) for each file and waits for the user to
accept each one. It also stores which licenses the user has accepted
so they don't need to be re-accepted if the text hasn't changed.
--
James Tunnicliffe
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 <bilhuang(a)nvidia.com>
---
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;
- 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)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index b3ac22d..41d567d 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -43,6 +43,11 @@ struct clk;
#define PRE_RATE_CHANGE BIT(0)
#define POST_RATE_CHANGE BIT(1)
#define ABORT_RATE_CHANGE BIT(2)
+#define PRE_CLK_PREPARE BIT(3)
+#define POST_CLK_PREPARE BIT(4)
+#define ABORT_CLK_PREPARE BIT(5)
+#define PRE_CLK_UNPREPARE BIT(6)
+#define POST_CLK_UNPREPARE BIT(7)
/**
* struct clk_notifier - associate a clk with a notifier
--
1.7.9.5