aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-18 20:54:09 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-18 20:54:09 -0800
commit796bd6b777e1f721b59411b9842176c62d7f30f7 (patch)
tree7963ef82373fd56fcad7145f0949e98aa7536825
parent48c3c0c752f960363cc5c60488b41c916810c8a6 (diff)
downloadltsi-kernel-796bd6b777e1f721b59411b9842176c62d7f30f7.tar.gz
add power efficient workqueue patches from Linaro
-rw-r--r--patches.renesas/0001-serial-sh-sci-HSCIF-support.patch53
-rw-r--r--patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch152
-rw-r--r--patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch72
-rw-r--r--patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch64
-rw-r--r--patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch85
-rw-r--r--patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch35
-rw-r--r--patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch30
-rw-r--r--patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch32
-rw-r--r--patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch27
-rw-r--r--patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch29
-rw-r--r--patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch30
-rw-r--r--patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch29
-rw-r--r--series15
13 files changed, 622 insertions, 31 deletions
diff --git a/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch b/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch
index a965f5c7119bfe..3e03bd02dea656 100644
--- a/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch
+++ b/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch
@@ -14,16 +14,14 @@ Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
(cherry picked from commit f303b364b41d3fc5bf879799128958400b7859aa)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
- drivers/tty/serial/sh-sci.c | 102 ++++++++++++++++++++++++++++++++++++---
- include/linux/serial_sci.h | 12 +++--
- include/uapi/linux/serial_core.h | 3 ++
+ drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++++++++----
+ include/linux/serial_sci.h | 12 +++-
+ include/uapi/linux/serial_core.h | 3 +
3 files changed, 106 insertions(+), 11 deletions(-)
-diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
-index 15641861..931d6c3a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
-@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
@@ -31,7 +29,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
@@ -39,7 +37,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
@@ -47,7 +45,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = { 0x3c, 16 },
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
@@ -55,7 +53,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = { 0x20, 16 },
[SCLSR] = { 0x24, 16 },
@@ -63,7 +61,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
@@ -71,7 +69,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = { 0x20, 16 },
[SCLSR] = { 0x24, 16 },
@@ -98,7 +96,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid,
[SCLSR] = { 0x24, 16 },
@@ -106,7 +104,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = { 0x20, 16 },
[SCSPTR] = { 0x24, 16 },
[SCLSR] = { 0x28, 16 },
@@ -114,7 +112,7 @@ index 15641861..931d6c3a 100644
},
/*
-@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SC
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
@@ -122,7 +120,7 @@ index 15641861..931d6c3a 100644
},
};
-@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg)
+@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_
*/
cfg->regtype = SCIx_SH4_SCIF_REGTYPE;
break;
@@ -132,7 +130,7 @@ index 15641861..931d6c3a 100644
default:
printk(KERN_ERR "Can't probe register map for given port\n");
return -EINVAL;
-@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
+@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsig
return ((freq + 16 * bps) / (32 * bps) - 1);
}
@@ -175,7 +173,7 @@ index 15641861..931d6c3a 100644
static void sci_reset(struct uart_port *port)
{
struct plat_sci_reg *reg;
-@@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+@@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_
struct plat_sci_reg *reg;
unsigned int baud, smr_val, max_baud, cks;
int t = -1;
@@ -183,7 +181,7 @@ index 15641861..931d6c3a 100644
/*
* earlyprintk comes here early on with port->uartclk set to zero.
-@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_
max_baud = port->uartclk ? port->uartclk / 16 : 115200;
baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
@@ -203,7 +201,7 @@ index 15641861..931d6c3a 100644
sci_port_enable(s);
-@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_
uart_update_timeout(port, termios->c_cflag, baud);
@@ -222,7 +220,7 @@ index 15641861..931d6c3a 100644
udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
} else
serial_port_out(port, SCSMR, smr_val);
-@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port)
+@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_
return "scifa";
case PORT_SCIFB:
return "scifb";
@@ -231,7 +229,7 @@ index 15641861..931d6c3a 100644
}
return NULL;
-@@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port)
+@@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_siz
* from platform resource data at such a time that ports begin to
* behave more erratically.
*/
@@ -243,7 +241,7 @@ index 15641861..931d6c3a 100644
}
static int sci_remap_port(struct uart_port *port)
-@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev,
+@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platfo
case PORT_SCIFB:
port->fifosize = 256;
break;
@@ -253,7 +251,7 @@ index 15641861..931d6c3a 100644
case PORT_SCIFA:
port->fifosize = 64;
break;
-@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev)
+@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(
#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
static char banner[] __initdata =
@@ -268,8 +266,6 @@ index 15641861..931d6c3a 100644
MODULE_AUTHOR("Paul Mundt");
-MODULE_DESCRIPTION("SuperH SCI(F) serial driver");
+MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver");
-diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
-index eb763adf..d3404971 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -5,7 +5,7 @@
@@ -333,8 +329,6 @@ index eb763adf..d3404971 100644
upf_t flags; /* UPF_* flags */
unsigned long capabilities; /* Port features/capabilities */
-diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
-index 74c2bf72..26eee07e 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -226,4 +226,7 @@
@@ -345,6 +339,3 @@ index 74c2bf72..26eee07e 100644
+#define PORT_HSCIF 103
+
#endif /* _UAPILINUX_SERIAL_CORE_H */
---
-1.8.4.3.gca3854a
-
diff --git a/patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch b/patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch
new file mode 100644
index 00000000000000..a9dc1751a07968
--- /dev/null
+++ b/patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch
@@ -0,0 +1,152 @@
+From 61a10f9763d989e6716fe35030951f2ccfca822a Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Mon, 8 Apr 2013 16:45:40 +0530
+Subject: workqueues: Introduce new flag WQ_POWER_EFFICIENT for power oriented
+ workqueues
+
+Workqueues can be performance or power-oriented. Currently, most workqueues are
+bound to the CPU they were created on. This gives good performance (due to cache
+effects) at the cost of potentially waking up otherwise idle cores (Idle from
+scheduler's perspective. Which may or may not be physically idle) just to
+process some work. To save power, we can allow the work to be rescheduled on a
+core that is already awake.
+
+Workqueues created with the WQ_UNBOUND flag will allow some power savings.
+However, we don't change the default behaviour of the system. To enable
+power-saving behaviour, a new config option CONFIG_WQ_POWER_EFFICIENT needs to
+be turned on. This option can also be overridden by the
+workqueue.power_efficient boot parameter.
+
+tj: Updated config description and comments. Renamed
+ CONFIG_WQ_POWER_EFFICIENT to CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit cee22a15052faa817e3ec8985a28154d3fabc7aa)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ Documentation/kernel-parameters.txt | 15 +++++++++++++++
+ include/linux/workqueue.h | 27 +++++++++++++++++++++++++++
+ kernel/power/Kconfig | 20 ++++++++++++++++++++
+ kernel/workqueue.c | 13 +++++++++++++
+ 4 files changed, 75 insertions(+)
+
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -3341,6 +3341,21 @@ bytes respectively. Such letter suffixes
+ that this also can be controlled per-workqueue for
+ workqueues visible under /sys/bus/workqueue/.
+
++ workqueue.power_efficient
++ Per-cpu workqueues are generally preferred because
++ they show better performance thanks to cache
++ locality; unfortunately, per-cpu workqueues tend to
++ be more power hungry than unbound workqueues.
++
++ Enabling this makes the per-cpu workqueues which
++ were observed to contribute significantly to power
++ consumption unbound, leading to measurably lower
++ power usage at the cost of small performance
++ overhead.
++
++ The default value of this parameter is determined by
++ the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
++
+ x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
+ default x2apic cluster mode on platforms
+ supporting x2apic.
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -303,6 +303,33 @@ enum {
+ WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */
+ WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */
+
++ /*
++ * Per-cpu workqueues are generally preferred because they tend to
++ * show better performance thanks to cache locality. Per-cpu
++ * workqueues exclude the scheduler from choosing the CPU to
++ * execute the worker threads, which has an unfortunate side effect
++ * of increasing power consumption.
++ *
++ * The scheduler considers a CPU idle if it doesn't have any task
++ * to execute and tries to keep idle cores idle to conserve power;
++ * however, for example, a per-cpu work item scheduled from an
++ * interrupt handler on an idle CPU will force the scheduler to
++ * excute the work item on that CPU breaking the idleness, which in
++ * turn may lead to more scheduling choices which are sub-optimal
++ * in terms of power consumption.
++ *
++ * Workqueues marked with WQ_POWER_EFFICIENT are per-cpu by default
++ * but become unbound if workqueue.power_efficient kernel param is
++ * specified. Per-cpu workqueues which are identified to
++ * contribute significantly to power-consumption are identified and
++ * marked with this flag and enabling the power_efficient mode
++ * leads to noticeable power saving at the cost of small
++ * performance disadvantage.
++ *
++ * http://thread.gmane.org/gmane.linux.kernel/1480396
++ */
++ WQ_POWER_EFFICIENT = 1 << 7,
++
+ __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */
+ __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */
+
+--- a/kernel/power/Kconfig
++++ b/kernel/power/Kconfig
+@@ -263,6 +263,26 @@ config PM_GENERIC_DOMAINS
+ bool
+ depends on PM
+
++config WQ_POWER_EFFICIENT_DEFAULT
++ bool "Enable workqueue power-efficient mode by default"
++ depends on PM
++ default n
++ help
++ Per-cpu workqueues are generally preferred because they show
++ better performance thanks to cache locality; unfortunately,
++ per-cpu workqueues tend to be more power hungry than unbound
++ workqueues.
++
++ Enabling workqueue.power_efficient kernel parameter makes the
++ per-cpu workqueues which were observed to contribute
++ significantly to power consumption unbound, leading to measurably
++ lower power usage at the cost of small performance overhead.
++
++ This config option determines whether workqueue.power_efficient
++ is enabled by default.
++
++ If in doubt, say N.
++
+ config PM_GENERIC_DOMAINS_SLEEP
+ def_bool y
+ depends on PM_SLEEP && PM_GENERIC_DOMAINS
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -272,6 +272,15 @@ static cpumask_var_t *wq_numa_possible_c
+ static bool wq_disable_numa;
+ module_param_named(disable_numa, wq_disable_numa, bool, 0444);
+
++/* see the comment above the definition of WQ_POWER_EFFICIENT */
++#ifdef CONFIG_WQ_POWER_EFFICIENT_DEFAULT
++static bool wq_power_efficient = true;
++#else
++static bool wq_power_efficient;
++#endif
++
++module_param_named(power_efficient, wq_power_efficient, bool, 0444);
++
+ static bool wq_numa_enabled; /* unbound NUMA affinity enabled */
+
+ /* buf for wq_update_unbound_numa_attrs(), protected by CPU hotplug exclusion */
+@@ -4117,6 +4126,10 @@ struct workqueue_struct *__alloc_workque
+ struct workqueue_struct *wq;
+ struct pool_workqueue *pwq;
+
++ /* see the comment above the definition of WQ_POWER_EFFICIENT */
++ if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
++ flags |= WQ_UNBOUND;
++
+ /* allocate wq and format name */
+ if (flags & WQ_UNBOUND)
+ tbl_size = wq_numa_tbl_len * sizeof(wq->numa_pwq_tbl[0]);
diff --git a/patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch b/patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch
new file mode 100644
index 00000000000000..8af7d85373619b
--- /dev/null
+++ b/patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch
@@ -0,0 +1,72 @@
+From 7399c448c57c930a065e0ab77870ab84dc0dbf61 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:54 +0530
+Subject: workqueue: Add system wide power_efficient workqueues
+
+This patch adds system wide workqueues aligned towards power saving. This is
+done by allocating them with WQ_UNBOUND flag if 'wq_power_efficient' is set to
+'true'.
+
+tj: updated comments a bit.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit 0668106ca3865ba945e155097fb042bf66d364d3)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ include/linux/workqueue.h | 8 ++++++++
+ kernel/workqueue.c | 13 ++++++++++++-
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -360,11 +360,19 @@ enum {
+ *
+ * system_freezable_wq is equivalent to system_wq except that it's
+ * freezable.
++ *
++ * *_power_efficient_wq are inclined towards saving power and converted
++ * into WQ_UNBOUND variants if 'wq_power_efficient' is enabled; otherwise,
++ * they are same as their non-power-efficient counterparts - e.g.
++ * system_power_efficient_wq is identical to system_wq if
++ * 'wq_power_efficient' is disabled. See WQ_POWER_EFFICIENT for more info.
+ */
+ extern struct workqueue_struct *system_wq;
+ extern struct workqueue_struct *system_long_wq;
+ extern struct workqueue_struct *system_unbound_wq;
+ extern struct workqueue_struct *system_freezable_wq;
++extern struct workqueue_struct *system_power_efficient_wq;
++extern struct workqueue_struct *system_freezable_power_efficient_wq;
+
+ static inline struct workqueue_struct * __deprecated __system_nrt_wq(void)
+ {
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -317,6 +317,10 @@ struct workqueue_struct *system_unbound_
+ EXPORT_SYMBOL_GPL(system_unbound_wq);
+ struct workqueue_struct *system_freezable_wq __read_mostly;
+ EXPORT_SYMBOL_GPL(system_freezable_wq);
++struct workqueue_struct *system_power_efficient_wq __read_mostly;
++EXPORT_SYMBOL_GPL(system_power_efficient_wq);
++struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly;
++EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq);
+
+ static int worker_thread(void *__worker);
+ static void copy_workqueue_attrs(struct workqueue_attrs *to,
+@@ -5039,8 +5043,15 @@ static int __init init_workqueues(void)
+ WQ_UNBOUND_MAX_ACTIVE);
+ system_freezable_wq = alloc_workqueue("events_freezable",
+ WQ_FREEZABLE, 0);
++ system_power_efficient_wq = alloc_workqueue("events_power_efficient",
++ WQ_POWER_EFFICIENT, 0);
++ system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient",
++ WQ_FREEZABLE | WQ_POWER_EFFICIENT,
++ 0);
+ BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||
+- !system_unbound_wq || !system_freezable_wq);
++ !system_unbound_wq || !system_freezable_wq ||
++ !system_power_efficient_wq ||
++ !system_freezable_power_efficient_wq);
+ return 0;
+ }
+ early_initcall(init_workqueues);
diff --git a/patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch b/patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch
new file mode 100644
index 00000000000000..0db668bce346f2
--- /dev/null
+++ b/patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch
@@ -0,0 +1,64 @@
+From bbe9f36ad93d3404e4c99509f6d13aed67fce02e Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:55 +0530
+Subject: PHYLIB: queue work on system_power_efficient_wq
+
+Phylib uses workqueues for multiple purposes. There is no real dependency of
+scheduling these on the cpu which scheduled them.
+
+On a idle system, it is observed that and idle cpu wakes up many times just to
+service this work. It would be better if we can schedule it on a cpu which the
+scheduler believes to be the most appropriate one.
+
+This patch replaces system_wq with system_power_efficient_wq for PHYLIB.
+
+Cc: David S. Miller <davem@davemloft.net>
+Cc: netdev@vger.kernel.org
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit bbb47bdeae756f04b896b55b51f230f3eb21f207)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ drivers/net/phy/phy.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -439,7 +439,7 @@ void phy_start_machine(struct phy_device
+ {
+ phydev->adjust_state = handler;
+
+- schedule_delayed_work(&phydev->state_queue, HZ);
++ queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ);
+ }
+
+ /**
+@@ -500,7 +500,7 @@ static irqreturn_t phy_interrupt(int irq
+ disable_irq_nosync(irq);
+ atomic_inc(&phydev->irq_disable);
+
+- schedule_work(&phydev->phy_queue);
++ queue_work(system_power_efficient_wq, &phydev->phy_queue);
+
+ return IRQ_HANDLED;
+ }
+@@ -655,7 +655,7 @@ static void phy_change(struct work_struc
+
+ /* reschedule state queue work to run as soon as possible */
+ cancel_delayed_work_sync(&phydev->state_queue);
+- schedule_delayed_work(&phydev->state_queue, 0);
++ queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
+
+ return;
+
+@@ -918,7 +918,8 @@ void phy_state_machine(struct work_struc
+ if (err < 0)
+ phy_error(phydev);
+
+- schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
++ queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
++ PHY_STATE_TIME * HZ);
+ }
+
+ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
diff --git a/patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch b/patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch
new file mode 100644
index 00000000000000..4fa9c4ea1fb698
--- /dev/null
+++ b/patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch
@@ -0,0 +1,85 @@
+From 4d5c9ea3313e410686855496f556d90e589ed2e2 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:56 +0530
+Subject: block: queue work on power efficient wq
+
+Block layer uses workqueues for multiple purposes. There is no real dependency
+of scheduling these on the cpu which scheduled them.
+
+On a idle system, it is observed that and idle cpu wakes up many times just to
+service this work. It would be better if we can schedule it on a cpu which the
+scheduler believes to be the most appropriate one.
+
+This patch replaces normal workqueues with power efficient versions.
+
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit 695588f9454bdbc7c1a2fbb8a6bfdcfba6183348)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ block/blk-core.c | 3 ++-
+ block/blk-ioc.c | 3 ++-
+ block/genhd.c | 12 ++++++++----
+ 3 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -3191,7 +3191,8 @@ int __init blk_dev_init(void)
+
+ /* used for unplugging and affects IO latency/throughput - HIGHPRI */
+ kblockd_workqueue = alloc_workqueue("kblockd",
+- WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
++ WQ_MEM_RECLAIM | WQ_HIGHPRI |
++ WQ_POWER_EFFICIENT, 0);
+ if (!kblockd_workqueue)
+ panic("Failed to create kblockd\n");
+
+--- a/block/blk-ioc.c
++++ b/block/blk-ioc.c
+@@ -144,7 +144,8 @@ void put_io_context(struct io_context *i
+ if (atomic_long_dec_and_test(&ioc->refcount)) {
+ spin_lock_irqsave(&ioc->lock, flags);
+ if (!hlist_empty(&ioc->icq_list))
+- schedule_work(&ioc->release_work);
++ queue_work(system_power_efficient_wq,
++ &ioc->release_work);
+ else
+ free_ioc = true;
+ spin_unlock_irqrestore(&ioc->lock, flags);
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -1489,9 +1489,11 @@ static void __disk_unblock_events(struct
+ intv = disk_events_poll_jiffies(disk);
+ set_timer_slack(&ev->dwork.timer, intv / 4);
+ if (check_now)
+- queue_delayed_work(system_freezable_wq, &ev->dwork, 0);
++ queue_delayed_work(system_freezable_power_efficient_wq,
++ &ev->dwork, 0);
+ else if (intv)
+- queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
++ queue_delayed_work(system_freezable_power_efficient_wq,
++ &ev->dwork, intv);
+ out_unlock:
+ spin_unlock_irqrestore(&ev->lock, flags);
+ }
+@@ -1534,7 +1536,8 @@ void disk_flush_events(struct gendisk *d
+ spin_lock_irq(&ev->lock);
+ ev->clearing |= mask;
+ if (!ev->block)
+- mod_delayed_work(system_freezable_wq, &ev->dwork, 0);
++ mod_delayed_work(system_freezable_power_efficient_wq,
++ &ev->dwork, 0);
+ spin_unlock_irq(&ev->lock);
+ }
+
+@@ -1627,7 +1630,8 @@ static void disk_check_events(struct dis
+
+ intv = disk_events_poll_jiffies(disk);
+ if (!ev->block && intv)
+- queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
++ queue_delayed_work(system_freezable_power_efficient_wq,
++ &ev->dwork, intv);
+
+ spin_unlock_irq(&ev->lock);
+
diff --git a/patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch b/patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch
new file mode 100644
index 00000000000000..17f469e80f7de7
--- /dev/null
+++ b/patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch
@@ -0,0 +1,35 @@
+From 3e9dc2afddfc1d76719f84ab5ea6b37e0fff5c46 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:57 +0530
+Subject: fbcon: queue work on power efficient wq
+
+fbcon uses workqueues and it has no real dependency of scheduling these on the
+cpu which scheduled them.
+
+On a idle system, it is observed that and idle cpu wakes up many times just to
+service this work. It would be better if we can schedule it on a cpu which the
+scheduler believes to be the most appropriate one.
+
+This patch replaces system_wq with system_power_efficient_wq.
+
+Cc: Dave Airlie <airlied@redhat.com>
+Cc: linux-fbdev@vger.kernel.org
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit a85f1a41f020bc2c97611060bcfae6f48a1db28d)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ drivers/video/console/fbcon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -404,7 +404,7 @@ static void cursor_timer_handler(unsigne
+ struct fb_info *info = (struct fb_info *) dev_addr;
+ struct fbcon_ops *ops = info->fbcon_par;
+
+- schedule_work(&info->queue);
++ queue_work(system_power_efficient_wq, &info->queue);
+ mod_timer(&ops->cursor_timer, jiffies + HZ/5);
+ }
+
diff --git a/patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch b/patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch
new file mode 100644
index 00000000000000..07e0a7664de534
--- /dev/null
+++ b/patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch
@@ -0,0 +1,30 @@
+From 605791a1741b2a9055e60b9fb59e3d3e679e40d2 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Thu, 18 Jul 2013 11:52:17 +0100
+Subject: ASoC: pcm: Use the power efficient workqueue for delayed powerdown
+
+There is no need to use a normal per-CPU workqueue for delayed power downs
+as they're not timing or performance critical and waking up a core for them
+would defeat some of the point.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
+(cherry picked from commit d4e1a73acd4e894f8332f2093bceaef585cfab67)
+---
+ sound/soc/soc-pcm.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -408,8 +408,9 @@ static int soc_pcm_close(struct snd_pcm_
+ } else {
+ /* start delayed pop wq here for playback streams */
+ rtd->pop_wait = 1;
+- schedule_delayed_work(&rtd->delayed_work,
+- msecs_to_jiffies(rtd->pmdown_time));
++ queue_delayed_work(system_power_efficient_wq,
++ &rtd->delayed_work,
++ msecs_to_jiffies(rtd->pmdown_time));
+ }
+ } else {
+ /* capture streams can be powered down now */
diff --git a/patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch b/patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch
new file mode 100644
index 00000000000000..3774c99d2c60c1
--- /dev/null
+++ b/patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch
@@ -0,0 +1,32 @@
+From fbcfea7d98897a48ac8cc6b6cf7eb597a6946669 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Thu, 18 Jul 2013 11:52:04 +0100
+Subject: regulator: core: Use the power efficient workqueue for delayed
+ powerdown
+
+There is no need to use a normal per-CPU workqueue for delayed power downs
+as they're not timing or performance critical and waking up a core for them
+would defeat some of the point.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Liam Girdwood <liam.r.girdwood@intel.com>
+(cherry picked from commit 070260f07c7daec311f2466eb9d1df475d5a46f8)
+---
+ drivers/regulator/core.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1890,8 +1890,9 @@ int regulator_disable_deferred(struct re
+ rdev->deferred_disables++;
+ mutex_unlock(&rdev->mutex);
+
+- ret = schedule_delayed_work(&rdev->disable_work,
+- msecs_to_jiffies(ms));
++ ret = queue_delayed_work(system_power_efficient_wq,
++ &rdev->disable_work,
++ msecs_to_jiffies(ms));
+ if (ret < 0)
+ return ret;
+ else
diff --git a/patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch b/patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch
new file mode 100644
index 00000000000000..2b826274ab3628
--- /dev/null
+++ b/patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch
@@ -0,0 +1,27 @@
+From 98fe237d868087d7108fde3da27fcbb531d25ca9 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Thu, 18 Jul 2013 22:47:10 +0100
+Subject: ASoC: jack: Use power efficient workqueue
+
+The accessory detect debounce work is not performance sensitive so let
+the scheduler run it wherever is most efficient rather than in a per CPU
+workqueue by using the system power efficient workqueue.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+(cherry picked from commit e6058aaadcd473e5827720dc143af56aabbeecc7)
+---
+ sound/soc/soc-jack.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/soc-jack.c
++++ b/sound/soc/soc-jack.c
+@@ -263,7 +263,7 @@ static irqreturn_t gpio_handler(int irq,
+ if (device_may_wakeup(dev))
+ pm_wakeup_event(dev, gpio->debounce_time + 50);
+
+- schedule_delayed_work(&gpio->work,
++ queue_delayed_work(system_power_efficient_wq, &gpio->work,
+ msecs_to_jiffies(gpio->debounce_time));
+
+ return IRQ_HANDLED;
diff --git a/patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch b/patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch
new file mode 100644
index 00000000000000..49b59b6c4d4ca3
--- /dev/null
+++ b/patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch
@@ -0,0 +1,29 @@
+From d3a177c71852d2eac42c74a6b2cb7af242061d21 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 19 Jul 2013 18:47:34 +0100
+Subject: extcon: gpio: Use power efficient workqueue for debounce
+
+The debounce timeout is generally quite long and the work not performance
+critical so allow the scheduler to run the work anywhere rather than in
+the normal per-CPU workqueue.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+(cherry picked from commit d0db2e7ae788d84ff6d0a1cd4dc935282db29073)
+---
+ drivers/extcon/extcon-gpio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/extcon/extcon-gpio.c
++++ b/drivers/extcon/extcon-gpio.c
+@@ -56,7 +56,7 @@ static irqreturn_t gpio_irq_handler(int
+ {
+ struct gpio_extcon_data *extcon_data = dev_id;
+
+- schedule_delayed_work(&extcon_data->work,
++ queue_delayed_work(system_power_efficient_wq, &extcon_data->work,
+ extcon_data->debounce_jiffies);
+ return IRQ_HANDLED;
+ }
diff --git a/patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch b/patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch
new file mode 100644
index 00000000000000..f2d34b39778130
--- /dev/null
+++ b/patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch
@@ -0,0 +1,30 @@
+From df08b04c9a3f2925e34f778bf20d37623635c306 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 19 Jul 2013 18:47:35 +0100
+Subject: extcon: adc-jack: Use power efficient workqueue
+
+The debounce timeout is generally quite long and the work not performance
+critical so allow the scheduler to run the work anywhere rather than in
+the normal per-CPU workqueue.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+(cherry picked from commit 1a82e81e0ede6955684397ffbc0964191ef13cba)
+---
+ drivers/extcon/extcon-adc-jack.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/extcon/extcon-adc-jack.c
++++ b/drivers/extcon/extcon-adc-jack.c
+@@ -87,7 +87,8 @@ static irqreturn_t adc_jack_irq_thread(i
+ {
+ struct adc_jack_data *data = _data;
+
+- schedule_delayed_work(&data->handler, data->handling_delay);
++ queue_delayed_work(system_power_efficient_wq,
++ &data->handler, data->handling_delay);
+ return IRQ_HANDLED;
+ }
+
diff --git a/patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch b/patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch
new file mode 100644
index 00000000000000..0d678f6f20062b
--- /dev/null
+++ b/patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch
@@ -0,0 +1,29 @@
+From 03bc67f592760de5b16a48cb07ca02ecedf5fa11 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 18:12:29 +0100
+Subject: ASoC: compress: Use power efficient workqueue
+
+There is no need for the power down work to be done on a per CPU workqueue
+especially considering the fairly long delay before powerdown.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Vinod Koul <vinod.koul@intel.com>
+(cherry picked from commit 3d24cfe485e2750cc209a77dd62fa1fe004fc6c7)
+---
+ sound/soc/soc-compress.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/soc-compress.c
++++ b/sound/soc/soc-compress.c
+@@ -149,8 +149,9 @@ static int soc_compr_free(struct snd_com
+ SND_SOC_DAPM_STREAM_STOP);
+ } else {
+ rtd->pop_wait = 1;
+- schedule_delayed_work(&rtd->delayed_work,
+- msecs_to_jiffies(rtd->pmdown_time));
++ queue_delayed_work(system_power_efficient_wq,
++ &rtd->delayed_work,
++ msecs_to_jiffies(rtd->pmdown_time));
+ }
+ } else {
+ /* capture streams can be powered down now */
diff --git a/series b/series
index af418c9e61f91d..eab24b7e3f54c0 100644
--- a/series
+++ b/series
@@ -29,6 +29,21 @@ patches.ltsi/ltsi-makefile-addition.patch
patches.lttng/lttng-2.3.4.patch
+#############################################################################
+# Power efficient workqueues
+#
+patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch
+patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch
+patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch
+patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch
+patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch
+patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch
+patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch
+patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch
+patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch
+patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch
+patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch
+
#############################################################################
# Renesas SOC patches