* [PATCH V2 1/2] ARM: remove unnecessary flush of anon pages in flush_dcache_page()
From: Simon Baatz @ 2012-10-07 11:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349609352-6408-1-git-send-email-gmbnomis@gmail.com>
On non-aliasing VIPT D-caches, there is no need to flush the kernel
mapping of anon pages in flush_dcache_page() directly. If the page is
mapped as executable later, the necessary D/I-cache flush will be done
in __sync_icache_dcache().
Signed-off-by: Simon Baatz <gmbnomis@gmail.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
---
Changes:
in V2:
- Followed Catalin's suggestion to reverse the order of the patches
- Clarified comment for flush_dcache_page()
arch/arm/mm/flush.c | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 40ca11e..5c474a1 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -257,16 +257,20 @@ void __sync_icache_dcache(pte_t pteval)
* of this page.
*
* We have three cases to consider:
- * - VIPT non-aliasing cache: fully coherent so nothing required.
- * - VIVT: fully aliasing, so we need to handle every alias in our
- * current VM view.
- * - VIPT aliasing: need to handle one alias in our current VM view.
+ * - VIPT non-aliasing D-cache:
+ * D-cache: fully coherent so nothing required.
+ * I-cache: Ensure I/D coherency in case of an already mapped page;
+ * __sync_icache_dcache() will handle the other cases.
+ * - VIPT aliasing D-cache:
+ * D-cache: need to handle one alias in our current VM view.
+ * I-cache: same as VIPT non-aliasing cache.
+ * - VIVT D-cache: fully aliasing, so we need to handle every alias in our
+ * current VM view.
*
- * If we need to handle aliasing:
- * If the page only exists in the page cache and there are no user
- * space mappings, we can be lazy and remember that we may have dirty
- * kernel cache lines for later. Otherwise, we assume we have
- * aliasing mappings.
+ * If the page only exists in the page cache and there are no user
+ * space mappings, we can be lazy and remember that we may have dirty
+ * kernel cache lines for later. Otherwise, we assume we have
+ * aliasing mappings.
*
* Note that we disable the lazy flush for SMP configurations where
* the cache maintenance operations are not automatically broadcasted.
@@ -284,17 +288,20 @@ void flush_dcache_page(struct page *page)
mapping = page_mapping(page);
- if (!cache_ops_need_broadcast() &&
- mapping && !mapping_mapped(mapping))
- clear_bit(PG_dcache_clean, &page->flags);
- else {
- __flush_dcache_page(mapping, page);
- if (mapping && cache_is_vivt())
- __flush_dcache_aliases(mapping, page);
- else if (mapping)
- __flush_icache_all();
- set_bit(PG_dcache_clean, &page->flags);
+ if (!cache_ops_need_broadcast()) {
+ if ((mapping && !mapping_mapped(mapping)) ||
+ (!mapping && cache_is_vipt_nonaliasing())) {
+ clear_bit(PG_dcache_clean, &page->flags);
+ return;
+ }
}
+
+ __flush_dcache_page(mapping, page);
+ if (mapping && cache_is_vivt())
+ __flush_dcache_aliases(mapping, page);
+ else if (mapping)
+ __flush_icache_all();
+ set_bit(PG_dcache_clean, &page->flags);
}
EXPORT_SYMBOL(flush_dcache_page);
--
1.7.9.5
^ permalink raw reply related
* [PATCH V2 0/2] fix and improvement of flush(_kernel)_dcache_page()
From: Simon Baatz @ 2012-10-07 11:29 UTC (permalink / raw)
To: linux-arm-kernel
The first patch optimizes flush_dcache_page() for non-aliasing VIPT
caches. On these the flush of the kernel mapping for the anon case is
actually not needed. It may be needed to ensure I/D coherency, but
this can be handled by __sync_icache_dcache() later and more
effectively (similar to arm64, see [3]). Thus, we should be lazy as
well here and just clear the PG_dcache_clean bit.
The second patch is another attempt to fix the regression caused by
patch f8b63c1 "ARM: 6382/1" in 2.6.37 (see [2]). The problem occurs
on VIVT (and probably VIPT aliasing) cache architectures for drivers
that use flush_kernel_dcache_page(). For example, 3.6 (as any
kernel beginning with 2.6.37) on kirkwood using mv_cesa produces data
corruption when using direct I/O:
~# cryptsetup luksOpen /dev/sda2 c_sda2
Enter passphrase for /dev/sda2:
~# dd if=/dev/mapper/c_sda2 iflag=direct bs=4k count=16 2>/dev/null | sha1sum
9ae4997ec85ad9b7ab4b10341e42ace80f0ea5d6 -
~# dd if=/dev/mapper/c_sda2 bs=4k count=16 2>/dev/null | sha1sum
ca39c5d4950b3704eff952c48e383bf1db20532e -
(The mv_cesa driver uses the scatterlist memory iterator, which uses
flush_kernel_dcache_page() before kunmap()).
As described in [1], both flush_dcache_page() and
flush_kernel_dcache_page() need to handle the following cases:
- page cache pages with no user space mapping
- page cache pages with user space mapping(s)
- flush the kernel mapping of anonymous pages
The last one is contradictory to documentation for flush_dcache_page(),
but many uses in the kernel require it (drivers use it to flush
modifications via the kernel mapping).
In the proposed patch the implementation of flush_kernel_dcache_page()
follows the one of flush_dcache_page(), but only flushes the kernel
mapping, not the alias user mapping(s).
I could only test this on kirkwood (ARMv5, VIVT) and raspberry pi
BCM2835 (ARMv6, PIPT / VIPT nonaliasing data cache). More testing
would probably be a good thing... Especially, I could not test the
non-aliasing cache case with a real driver using
flush_kernel_dcache_page() (mv_cesa on dove could be a test case for
this).
Changes:
in V2:
- Followed Catalin's suggestion to reverse the order of the patches
- Clarified comment for flush_dcache_page()
- Simon
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2012-August/113908.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2012-May/101795.html
[3] https://lkml.org/lkml/2012/9/12/121
Simon Baatz (2):
ARM: remove unnecessary flush of anon pages in flush_dcache_page()
ARM: Handle user space mapped pages in flush_kernel_dcache_page
arch/arm/include/asm/cacheflush.h | 4 ++
arch/arm/mm/flush.c | 87 +++++++++++++++++++++++++++++--------
2 files changed, 72 insertions(+), 19 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH 0/4] arm-soc: vt8500: Cleanup patches for 3.7
From: Arnd Bergmann @ 2012-10-07 11:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349571734-26233-1-git-send-email-linux@prisktech.co.nz>
On Sunday 07 October 2012, Tony Prisk wrote:
> Minor cleanup patches for 3.7.
>
> Tony Prisk (4):
> vt8500: Remove unused headers from include/mach/
> vt8500: Remove arm/boot/compressed/head-vt8500.S
> vt8500: Fix header in mach-vt8500/timer.c
> vt8500: Fix build warning when no framebuffer selected
Hi Tony,
The patches all look good, but they are late for 3.7 now. I would
still take the last one since that fixes a build warning, and the
separate patch that adds the .dtb files to the Makefile, but leave
the other ones for 3.8, unless there is a strong reason to
still include them.
Arnd
^ permalink raw reply
* [PATCH v3] GPIO: Add support for GPIO on CLPS711X-target platform
From: Russell King - ARM Linux @ 2012-10-07 10:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121007135334.3ed2b9a5.shc_work@mail.ru>
On Sun, Oct 07, 2012 at 01:53:34PM +0400, Alexander Shiyan wrote:
> On Fri, 5 Oct 2012 10:02:04 +0100
> Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:
>
> > On Mon, Oct 01, 2012 at 07:42:33PM +0400, Alexander Shiyan wrote:
> > > The CLPS711X CPUs provide some GPIOs for use in the system. This
> > > driver provides support for these via gpiolib. Due to platform
> > > limitations, driver does not support interrupts, only inputs and
> > > outputs.
> ...
> > > +++ b/arch/arm/mach-clps711x/include/mach/gpio.h
> > > @@ -0,0 +1,27 @@
> > > +/*
> > > + * This file contains the CLPS711X GPIO definitions.
> > > + *
> > > + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
> > > + *
> > > + * 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.
> > > + */
> > > +
> > > +/* Simple helper for convert port & pin to GPIO number */
> > > +#define CLPS711X_GPIO(port, bit) ((port) * 8 + (bit))
> > > +
> > > +/* Temporaty definitions for GPIO-ports */
> > > +/* Will be removed after remove clps_read(write) macros */
> > > +#include <mach/hardware.h>
> > > +#define _PADR (CLPS711X_VIRT_BASE + PADR)
> > > +#define _PBDR (CLPS711X_VIRT_BASE + PBDR)
> > > +#define _PCDR (CLPS711X_VIRT_BASE + PCDR)
> > > +#define _PDDR (CLPS711X_VIRT_BASE + PDDR)
> > > +#define _PADDR (CLPS711X_VIRT_BASE + PADDR)
> > > +#define _PBDDR (CLPS711X_VIRT_BASE + PBDDR)
> > > +#define _PCDDR (CLPS711X_VIRT_BASE + PCDDR)
> > > +#define _PDDDR (CLPS711X_VIRT_BASE + PDDDR)
> > > +#define _PEDR (CLPS711X_VIRT_BASE + PEDR)
> > > +#define _PEDDR (CLPS711X_VIRT_BASE + PEDDR)
> >
> > Why can't this file (or the bulk of it) live in drivers/gpio ?
> We should have access for macros in gpio.h from board support files
> and other drivers. From drivers/gpio it not possible.
> If you ask about port definitions, as I say before, it will be
> removed later after rework on platform hardware definitions.
No other drivers should be directly accessing the GPIO registers -
doing so is likely a bug because of the inherent lack of locking,
which will cause race conditions.
All accesses to GPIOs should be done via gpiolib, even from board
support files.
^ permalink raw reply
* [PATCH 0/6] ARM: Add support for Broadcom BCM476x SoCs
From: Domenico Andreoli @ 2012-10-07 10:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5071118A.6040508@wwwdotorg.org>
On Sat, Oct 06, 2012 at 11:22:18PM -0600, Stephen Warren wrote:
> On 10/06/2012 07:53 PM, Domenico Andreoli wrote:
> >
> > Additional support is being worked on.... and usb (DWC OTG) only
> > attemped reusing s3c-hsotg.
>
> Hmmm. I believe the bcm2835 uses DWC OTG. I wonder if the same driver
> will work there; USB in particular is a major pain point on the bcm2835...
I don't know any more how many versions of this driver are circulating,
we may have some options.
> > It's based on a random pre v3.7-rc1 commit (eb0ad9c) with mainlined
> > multi-platform support and Stephen's patch to add DEBUG_LL to it.
>
> ...
> about uncompress.h now. Unless anyone really pipes up and says they'd
> still like me to pursue uncompress.h in multi-platform, I'm inclined to
> drop it.
I think it is valuable, multi-platform doesn't have any DEBUG_LL or
earlyprintk support and your patch solves the problem though it won't
work transparently on multiple boards at the same time, which is not
a requirement.
To my understanding Nico was complaining for the specific Tegra (and TI)
abuse, not the general approach.
> > Special thanks go to Stephen Warren who, with the recently mainlined
> > BCM2835, showed how to do things cleanly since the beginning and
> > involuntarily spurred me to act.
>
> Thanks! Do note that much of the code I upstreamed was originally
> written by others, although I did make quite a few changes during
> upstream submission.
Yes, of course :)
Regards,
Domenico
^ permalink raw reply
* [PATCH v2] ARM: OMAP: Fix dependency for OMAP_DEBUG_LEDS
From: Axel Lin @ 2012-10-07 10:13 UTC (permalink / raw)
To: linux-arm-kernel
This fixes below build error when CONFIG_LEDS_CLASS is not set.
LD init/built-in.o
arch/arm/plat-omap/built-in.o: In function `fpga_probe':
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/built-in.o:arch/arm/plat-omap/debug-leds.c:113: more undefined references to `led_classdev_register' follow
make: *** [vmlinux] Error 1
Signed-off-by: Axel Lin <axel.lin@ingics.com>
---
arch/arm/plat-omap/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index ca83a76..c262781 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -43,6 +43,7 @@ config OMAP_DEBUG_DEVICES
config OMAP_DEBUG_LEDS
def_bool y if NEW_LEDS
+ select LEDS_CLASS
depends on OMAP_DEBUG_DEVICES
config POWER_AVS_OMAP
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3] GPIO: Add support for GPIO on CLPS711X-target platform
From: Alexander Shiyan @ 2012-10-07 9:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121005090204.GL4625@n2100.arm.linux.org.uk>
On Fri, 5 Oct 2012 10:02:04 +0100
Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:
> On Mon, Oct 01, 2012 at 07:42:33PM +0400, Alexander Shiyan wrote:
> > The CLPS711X CPUs provide some GPIOs for use in the system. This
> > driver provides support for these via gpiolib. Due to platform
> > limitations, driver does not support interrupts, only inputs and
> > outputs.
...
> > +++ b/arch/arm/mach-clps711x/include/mach/gpio.h
> > @@ -0,0 +1,27 @@
> > +/*
> > + * This file contains the CLPS711X GPIO definitions.
> > + *
> > + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
> > + *
> > + * 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.
> > + */
> > +
> > +/* Simple helper for convert port & pin to GPIO number */
> > +#define CLPS711X_GPIO(port, bit) ((port) * 8 + (bit))
> > +
> > +/* Temporaty definitions for GPIO-ports */
> > +/* Will be removed after remove clps_read(write) macros */
> > +#include <mach/hardware.h>
> > +#define _PADR (CLPS711X_VIRT_BASE + PADR)
> > +#define _PBDR (CLPS711X_VIRT_BASE + PBDR)
> > +#define _PCDR (CLPS711X_VIRT_BASE + PCDR)
> > +#define _PDDR (CLPS711X_VIRT_BASE + PDDR)
> > +#define _PADDR (CLPS711X_VIRT_BASE + PADDR)
> > +#define _PBDDR (CLPS711X_VIRT_BASE + PBDDR)
> > +#define _PCDDR (CLPS711X_VIRT_BASE + PCDDR)
> > +#define _PDDDR (CLPS711X_VIRT_BASE + PDDDR)
> > +#define _PEDR (CLPS711X_VIRT_BASE + PEDR)
> > +#define _PEDDR (CLPS711X_VIRT_BASE + PEDDR)
>
> Why can't this file (or the bulk of it) live in drivers/gpio ?
We should have access for macros in gpio.h from board support files
and other drivers. From drivers/gpio it not possible.
If you ask about port definitions, as I say before, it will be
removed later after rework on platform hardware definitions.
--
Alexander Shiyan <shc_work@mail.ru>
^ permalink raw reply
* [PATCH] ARM: OMAP: Fix dependency for OMAP_DEBUG_LEDS
From: Russell King - ARM Linux @ 2012-10-07 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349596837.15349.2.camel@phoenix>
On Sun, Oct 07, 2012 at 04:00:37PM +0800, Axel Lin wrote:
> config OMAP_DEBUG_LEDS
> - def_bool y if NEW_LEDS
> + default y if LEDS_CLASS
> depends on OMAP_DEBUG_DEVICES
This change is wrong. You're making this config entry untyped.
^ permalink raw reply
* [PATCH] ARM: OMAP: Fix dependency for OMAP_DEBUG_LEDS
From: Axel Lin @ 2012-10-07 8:00 UTC (permalink / raw)
To: linux-arm-kernel
This fixes below build error:
LD init/built-in.o
arch/arm/plat-omap/built-in.o: In function `fpga_probe':
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/debug-leds.c:113: undefined reference to `led_classdev_register'
arch/arm/plat-omap/built-in.o:arch/arm/plat-omap/debug-leds.c:113: more undefined references to `led_classdev_register' follow
make: *** [vmlinux] Error 1
Signed-off-by: Axel Lin <axel.lin@ingics.com>
---
Hi Bryan,
I think this issue is introduced by commit dafbead
"ARM: mach-omap1: retire custom LED code".
Regards,
Axel
arch/arm/plat-omap/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index ca83a76..3281377 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -42,7 +42,7 @@ config OMAP_DEBUG_DEVICES
For debug cards on TI reference boards.
config OMAP_DEBUG_LEDS
- def_bool y if NEW_LEDS
+ default y if LEDS_CLASS
depends on OMAP_DEBUG_DEVICES
config POWER_AVS_OMAP
--
1.7.9.5
^ permalink raw reply related
* [RFC 6/6] ARM: sched: clear SD_SHARE_POWERLINE
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349595838-31274-1-git-send-email-vincent.guittot@linaro.org>
The ARM platforms take advantage of packing small tasks on few cores.
This is true even when the cores of a cluster can't be powergated
independantly.
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
arch/arm/kernel/topology.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 26c12c6..00511d0 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -226,6 +226,11 @@ static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
*/
struct cputopo_arm cpu_topology[NR_CPUS];
+int arch_sd_share_power_line(void)
+{
+ return 0*SD_SHARE_POWERLINE;
+}
+
const struct cpumask *cpu_coregroup_mask(int cpu)
{
return &cpu_topology[cpu].core_sibling;
--
1.7.9.5
^ permalink raw reply related
* [RFC 5/6] sched: pack the idle load balance
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349595838-31274-1-git-send-email-vincent.guittot@linaro.org>
Look for an idle CPU close the pack buddy CPU whenever possible.
The goal is to prevent the wake up of a CPU which doesn't share the power
line of the pack CPU
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
kernel/sched/fair.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6df53b5..f76acdc 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5158,7 +5158,25 @@ static struct {
static inline int find_new_ilb(int call_cpu)
{
+ struct sched_domain *sd;
int ilb = cpumask_first(nohz.idle_cpus_mask);
+ int buddy = per_cpu(sd_pack_buddy, call_cpu);
+
+ /*
+ * If we have a pack buddy CPU, we try to run load balance on a CPU
+ * that is close to the buddy.
+ */
+ if (buddy != -1)
+ for_each_domain(buddy, sd) {
+ if (sd->flags & SD_SHARE_CPUPOWER)
+ continue;
+
+ ilb = cpumask_first_and(sched_domain_span(sd),
+ nohz.idle_cpus_mask);
+
+ if (ilb < nr_cpu_ids)
+ break;
+ }
if (ilb < nr_cpu_ids && idle_cpu(ilb))
return ilb;
--
1.7.9.5
^ permalink raw reply related
* [RFC 4/6] sched: secure access to other CPU statistics
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349595838-31274-1-git-send-email-vincent.guittot@linaro.org>
The atomic update of runnable_avg_sum and runnable_avg_period are ensured
by their size and the toolchain. But we must ensure to not read an old value
for one field and a newly updated value for the other field. As we don't
want to lock other CPU while reading these fields, we read twice each fields
and check that no change have occured in the middle.
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
kernel/sched/fair.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8c9d3ed..6df53b5 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3133,13 +3133,28 @@ static int select_idle_sibling(struct task_struct *p, int target)
static inline bool is_buddy_busy(int cpu)
{
struct rq *rq = cpu_rq(cpu);
+ volatile u32 *psum = &rq->avg.runnable_avg_sum;
+ volatile u32 *pperiod = &rq->avg.runnable_avg_period;
+ u32 sum, new_sum, period, new_period;
+ int timeout = 10;
+
+ while (timeout) {
+ sum = *psum;
+ period = *pperiod;
+ new_sum = *psum;
+ new_period = *pperiod;
+
+ if ((sum == new_sum) && (period == new_period))
+ break;
+
+ timeout--;
+ }
/*
* A busy buddy is a CPU with a high load or a small load with a lot of
* running tasks.
*/
- return ((rq->avg.usage_avg_sum << rq->nr_running) >
- rq->avg.runnable_avg_period);
+ return ((new_sum << rq->nr_running) > new_period);
}
static inline bool is_light_task(struct task_struct *p)
--
1.7.9.5
^ permalink raw reply related
* [RFC 3/6] sched: pack small tasks
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349595838-31274-1-git-send-email-vincent.guittot@linaro.org>
During sched_domain creation, we define a pack buddy CPU if available.
On a system that share the powerline at all level, the buddy is set to -1
On a dual clusters / dual cores system which can powergate each core and
cluster independantly, the buddy configuration will be :
| CPU0 | CPU1 | CPU2 | CPU3 |
-----------------------------------
buddy | CPU0 | CPU0 | CPU0 | CPU2 |
Small tasks tend to slip out of the periodic load balance.
The best place to choose to migrate them is at their wake up.
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
kernel/sched/core.c | 1 +
kernel/sched/fair.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/sched/sched.h | 1 +
3 files changed, 111 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index dab7908..70cadbe 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6131,6 +6131,7 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
rcu_assign_pointer(rq->sd, sd);
destroy_sched_domains(tmp, cpu);
+ update_packing_domain(cpu);
update_top_cache_domain(cpu);
}
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 4f4a4f6..8c9d3ed 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -157,6 +157,63 @@ void sched_init_granularity(void)
update_sysctl();
}
+
+/*
+ * Save the id of the optimal CPU that should be used to pack small tasks
+ * The value -1 is used when no buddy has been found
+ */
+DEFINE_PER_CPU(int, sd_pack_buddy);
+
+/* Look for the best buddy CPU that can be used to pack small tasks
+ * We make the assumption that it doesn't wort to pack on CPU that share the
+ * same powerline. We looks for the 1st sched_domain without the
+ * SD_SHARE_POWERLINE flag. Then We look for the sched_group witht the lowest
+ * power per core based on the assumption that their power efficiency is
+ * better */
+void update_packing_domain(int cpu)
+{
+ struct sched_domain *sd;
+ int id = -1;
+
+ sd = highest_flag_domain(cpu, SD_SHARE_POWERLINE);
+ if (!sd)
+ sd = rcu_dereference_check_sched_domain(cpu_rq(cpu)->sd);
+ else
+ sd = sd->parent;
+
+ while (sd) {
+ struct sched_group *sg = sd->groups;
+ struct sched_group *pack = sg;
+ struct sched_group *tmp = sg->next;
+
+ /* 1st CPU of the sched domain is a good candidate */
+ if (id == -1)
+ id = cpumask_first(sched_domain_span(sd));
+
+ /* loop the sched groups to find the best one */
+ while (tmp != sg) {
+ if (tmp->sgp->power * sg->group_weight <
+ sg->sgp->power * tmp->group_weight)
+ pack = tmp;
+ tmp = tmp->next;
+ }
+
+ /* we have found a better group */
+ if (pack != sg)
+ id = cpumask_first(sched_group_cpus(pack));
+
+ /* Look for another CPU than itself */
+ if ((id != cpu)
+ || ((sd->parent) && !(sd->parent->flags && SD_LOAD_BALANCE)))
+ break;
+
+ sd = sd->parent;
+ }
+
+ pr_info(KERN_INFO "CPU%d packing on CPU%d\n", cpu, id);
+ per_cpu(sd_pack_buddy, cpu) = id;
+}
+
#if BITS_PER_LONG == 32
# define WMULT_CONST (~0UL)
#else
@@ -3073,6 +3130,55 @@ static int select_idle_sibling(struct task_struct *p, int target)
return target;
}
+static inline bool is_buddy_busy(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+
+ /*
+ * A busy buddy is a CPU with a high load or a small load with a lot of
+ * running tasks.
+ */
+ return ((rq->avg.usage_avg_sum << rq->nr_running) >
+ rq->avg.runnable_avg_period);
+}
+
+static inline bool is_light_task(struct task_struct *p)
+{
+ /* A light task runs less than 25% in average */
+ return ((p->se.avg.usage_avg_sum << 2) < p->se.avg.runnable_avg_period);
+}
+
+static int check_pack_buddy(int cpu, struct task_struct *p)
+{
+ int buddy = per_cpu(sd_pack_buddy, cpu);
+
+ /* No pack buddy for this CPU */
+ if (buddy == -1)
+ return false;
+
+ /*
+ * If a task is waiting for running on the CPU which is its own buddy,
+ * let the default behavior to look for a better CPU if available
+ * The threshold has been set to 37.5%
+ */
+ if ((buddy == cpu)
+ && ((p->se.avg.usage_avg_sum << 3) < (p->se.avg.runnable_avg_sum * 5)))
+ return false;
+
+ /* buddy is not an allowed CPU */
+ if (!cpumask_test_cpu(buddy, tsk_cpus_allowed(p)))
+ return false;
+
+ /*
+ * If the task is a small one and the buddy is not overloaded,
+ * we use buddy cpu
+ */
+ if (!is_light_task(p) || is_buddy_busy(buddy))
+ return false;
+
+ return true;
+}
+
/*
* sched_balance_self: balance the current task (running on cpu) in domains
* that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
@@ -3098,6 +3204,9 @@ select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
if (p->nr_cpus_allowed == 1)
return prev_cpu;
+ if (check_pack_buddy(cpu, p))
+ return per_cpu(sd_pack_buddy, cpu);
+
if (sd_flag & SD_BALANCE_WAKE) {
if (cpumask_test_cpu(cpu, tsk_cpus_allowed(p)))
want_affine = 1;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index a95d5c1..086d8bf 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -875,6 +875,7 @@ static inline void idle_balance(int cpu, struct rq *rq)
extern void sysrq_sched_debug_show(void);
extern void sched_init_granularity(void);
+extern void update_packing_domain(int cpu);
extern void update_max_interval(void);
extern void update_group_power(struct sched_domain *sd, int cpu);
extern int update_runtime(struct notifier_block *nfb, unsigned long action, void *hcpu);
--
1.7.9.5
^ permalink raw reply related
* [RFC 2/6] sched: add a new SD SHARE_POWERLINE flag for sched_domain
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349595838-31274-1-git-send-email-vincent.guittot@linaro.org>
This new flag SD SHARE_POWERLINE reflects the sharing of the power rail
between the members of a domain. As this is the current assumption of the
scheduler, the flag is added to all sched_domain
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
arch/ia64/include/asm/topology.h | 1 +
arch/tile/include/asm/topology.h | 1 +
include/linux/sched.h | 1 +
include/linux/topology.h | 3 +++
kernel/sched/core.c | 5 +++++
5 files changed, 11 insertions(+)
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h
index a2496e4..065c720 100644
--- a/arch/ia64/include/asm/topology.h
+++ b/arch/ia64/include/asm/topology.h
@@ -65,6 +65,7 @@ void build_cpu_to_node_map(void);
| SD_BALANCE_EXEC \
| SD_BALANCE_FORK \
| SD_WAKE_AFFINE, \
+ | arch_sd_share_power_line() \
.last_balance = jiffies, \
.balance_interval = 1, \
.nr_balance_failed = 0, \
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h
index 7a7ce39..d39ed0b 100644
--- a/arch/tile/include/asm/topology.h
+++ b/arch/tile/include/asm/topology.h
@@ -72,6 +72,7 @@ static inline const struct cpumask *cpumask_of_node(int node)
| 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 0*SD_SHARE_PKG_RESOURCES \
+ | arch_sd_share_power_line() \
| 0*SD_SERIALIZE \
, \
.last_balance = jiffies, \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4786b20..74f2daf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -862,6 +862,7 @@ enum cpu_idle_type {
#define SD_WAKE_AFFINE 0x0020 /* Wake task to waking CPU */
#define SD_PREFER_LOCAL 0x0040 /* Prefer to keep tasks local to this domain */
#define SD_SHARE_CPUPOWER 0x0080 /* Domain members share cpu power */
+#define SD_SHARE_POWERLINE 0x0100 /* Domain members share power domain */
#define SD_SHARE_PKG_RESOURCES 0x0200 /* Domain members share cpu pkg resources */
#define SD_SERIALIZE 0x0400 /* Only a single load balancing instance */
#define SD_ASYM_PACKING 0x0800 /* Place busy groups earlier in the domain */
diff --git a/include/linux/topology.h b/include/linux/topology.h
index fec12d6..20964ab 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -99,6 +99,7 @@ int arch_update_cpu_topology(void);
| 1*SD_WAKE_AFFINE \
| 1*SD_SHARE_CPUPOWER \
| 1*SD_SHARE_PKG_RESOURCES \
+ | arch_sd_share_power_line() \
| 0*SD_SERIALIZE \
| 0*SD_PREFER_SIBLING \
| arch_sd_sibling_asym_packing() \
@@ -132,6 +133,7 @@ int arch_update_cpu_topology(void);
| 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 1*SD_SHARE_PKG_RESOURCES \
+ | arch_sd_share_power_line() \
| 0*SD_SERIALIZE \
, \
.last_balance = jiffies, \
@@ -163,6 +165,7 @@ int arch_update_cpu_topology(void);
| 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 0*SD_SHARE_PKG_RESOURCES \
+ | arch_sd_share_power_line() \
| 0*SD_SERIALIZE \
| 1*SD_PREFER_SIBLING \
, \
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d50fbac..dab7908 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6407,6 +6407,11 @@ int __weak arch_sd_sibling_asym_packing(void)
return 0*SD_ASYM_PACKING;
}
+int __weak arch_sd_share_power_line(void)
+{
+ return 1*SD_SHARE_POWERLINE;
+}
+
/*
* Initializers for schedule domains
* Non-inlined to reduce accumulated stack pressure in build_sched_domains()
--
1.7.9.5
^ permalink raw reply related
* [RFC 1/6] Revert "sched: introduce temporary FAIR_GROUP_SCHED dependency for load-tracking"
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349595838-31274-1-git-send-email-vincent.guittot@linaro.org>
This reverts commit f0494c69d387db9496b6f9aa71b3bc49f1dcf474.
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
include/linux/sched.h | 8 +-------
kernel/sched/core.c | 7 +------
kernel/sched/fair.c | 13 ++-----------
kernel/sched/sched.h | 9 +--------
4 files changed, 5 insertions(+), 32 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f45da5f..4786b20 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1214,13 +1214,7 @@ struct sched_entity {
/* rq "owned" by this entity/group: */
struct cfs_rq *my_q;
#endif
-/*
- * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
- * removed when useful for applications beyond shares distribution (e.g.
- * load-balance).
- */
-#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
- /* Per-entity load-tracking */
+#ifdef CONFIG_SMP
struct sched_avg avg;
#endif
};
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b81915c..d50fbac 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1715,12 +1715,7 @@ static void __sched_fork(struct task_struct *p)
p->se.vruntime = 0;
INIT_LIST_HEAD(&p->se.group_node);
-/*
- * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
- * removed when useful for applications beyond shares distribution (e.g.
- * load-balance).
- */
-#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
+#ifdef CONFIG_SMP
p->se.avg.runnable_avg_period = 0;
p->se.avg.runnable_avg_sum = 0;
#endif
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 095d86c..4f4a4f6 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -877,8 +877,7 @@ static inline void update_cfs_shares(struct cfs_rq *cfs_rq)
}
#endif /* CONFIG_FAIR_GROUP_SCHED */
-/* Only depends on SMP, FAIR_GROUP_SCHED may be removed when useful in lb */
-#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
+#ifdef CONFIG_SMP
/*
* We choose a half-life close to 1 scheduling period.
* Note: The tables below are dependent on this value.
@@ -3204,12 +3203,6 @@ unlock:
}
/*
- * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
- * removed when useful for applications beyond shares distribution (e.g.
- * load-balance).
- */
-#ifdef CONFIG_FAIR_GROUP_SCHED
-/*
* Called immediately before a task is migrated to a new cpu; task_cpu(p) and
* cfs_rq_of(p) references at time of call are still valid and identify the
* previous cpu. However, the caller only guarantees p->pi_lock is held; no
@@ -3232,7 +3225,6 @@ migrate_task_rq_fair(struct task_struct *p, int next_cpu)
atomic64_add(se->avg.load_avg_contrib, &cfs_rq->removed_load);
}
}
-#endif
#endif /* CONFIG_SMP */
static unsigned long
@@ -5812,9 +5804,8 @@ const struct sched_class fair_sched_class = {
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_fair,
-#ifdef CONFIG_FAIR_GROUP_SCHED
.migrate_task_rq = migrate_task_rq_fair,
-#endif
+
.rq_online = rq_online_fair,
.rq_offline = rq_offline_fair,
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 81135f9..a95d5c1 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -225,12 +225,6 @@ struct cfs_rq {
#endif
#ifdef CONFIG_SMP
-/*
- * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
- * removed when useful for applications beyond shares distribution (e.g.
- * load-balance).
- */
-#ifdef CONFIG_FAIR_GROUP_SCHED
/*
* CFS Load tracking
* Under CFS, load is tracked on a per-entity basis and aggregated up.
@@ -240,8 +234,7 @@ struct cfs_rq {
u64 runnable_load_avg, blocked_load_avg;
atomic64_t decay_counter, removed_load;
u64 last_decay;
-#endif /* CONFIG_FAIR_GROUP_SCHED */
-/* These always depend on CONFIG_FAIR_GROUP_SCHED */
+
#ifdef CONFIG_FAIR_GROUP_SCHED
u32 tg_runnable_contrib, tg_usage_contrib;
u64 tg_load_contrib;
--
1.7.9.5
^ permalink raw reply related
* [RFC 0/6] sched: packing small tasks
From: Vincent Guittot @ 2012-10-07 7:43 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patch-set takes advantage of the new statistics that are going to be available in the kernel thanks to the per-entity load-tracking: http://thread.gmane.org/gmane.linux.kernel/1348522. It packs the small tasks in as few as possible CPU/Cluster/Core. The main goal of packing small tasks is to reduce the power consumption by minimizing the number of power domain that are used. The packing is done in 2 steps:
The 1st step looks for the best place to pack tasks on a system according to its topology and it defines a pack buddy CPU for each CPU if there is one available. The policy for setting a pack buddy CPU is that we pack at all levels where the power line is not shared by groups of CPUs. For describing this capability, a new flag has been introduced SD_SHARE_POWERLINE that is used to describe where CPUs of a scheduling domain are sharing their power rails. This flag has been set in all sched_domain in order to keep unchanged the default behaviour of the scheduler.
In a 2nd step, the scheduler checks the load level of the task which wakes up and the business of the buddy CPU. Then, It can decide to migrate the task on the buddy.
The patch-set has been tested on ARM platforms: quad CA-9 SMP and TC2 HMP (dual CA-15 and 3xCA-7 cluster). For ARM platform, the results have demonstrated that it's worth packing small tasks at all topology levels.
The performance tests have been done on both platforms with sysbench. The results don't show any performance regressions. These results are aligned with the policy which uses the normal behavior with heavy use cases.
test: sysbench --test=cpu --num-threads=N --max-requests=R run
Results below is the average duration of 3 tests on the quad CA-9.
default is the current scheduler behavior (pack buddy CPU is -1)
pack is the scheduler with the pack mecanism
| default | pack |
-----------------------------------
N=8; R=200 | 3.1999 | 3.1921 |
N=8; R=2000 | 31.4939 | 31.4844 |
N=12; R=200 | 3.2043 | 3.2084 |
N=12; R=2000 | 31.4897 | 31.4831 |
N=16; R=200 | 3.1774 | 3.1824 |
N=16; R=2000 | 31.4899 | 31.4897 |
-----------------------------------
The power consumption tests have been done only on TC2 platform which has got accessible power lines and I have used cyclictest to simulate small tasks. The tests show some power consumption improvements.
test: cyclictest -t 8 -q -e 1000000 -D 20 & cyclictest -t 8 -q -e 1000000 -D 20
The measurements have been done during 16 seconds and the result has been normalized to 100
| CA15 | CA7 | total |
-------------------------------------
default | 100 | 40 | 140 |
pack | <1 | 45 | <46 |
-------------------------------------
The A15 cluster is less power efficient than the A7 cluster but if we assume that the tasks is well spread on both clusters, we can guest estimate that the power consumption on a dual cluster of CA7 would have been for a default kernel:
| CA7 | CA7 | total |
-------------------------------------
default | 40 | 40 | 80 |
-------------------------------------
Vincent Guittot (6):
Revert "sched: introduce temporary FAIR_GROUP_SCHED dependency for
load-tracking"
sched: add a new SD SHARE_POWERLINE flag for sched_domain
sched: pack small task@wakeup
sched: secure access to other CPU statistics
sched: pack the idle load balance
ARM: sched: clear SD_SHARE_POWERLINE
arch/arm/kernel/topology.c | 5 ++
arch/ia64/include/asm/topology.h | 1 +
arch/tile/include/asm/topology.h | 1 +
include/linux/sched.h | 9 +--
include/linux/topology.h | 3 +
kernel/sched/core.c | 13 ++--
kernel/sched/fair.c | 155 +++++++++++++++++++++++++++++++++++---
kernel/sched/sched.h | 10 +--
8 files changed, 165 insertions(+), 32 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH 6/6] arm: at91: drop at91_suspend_entering_slow_clock
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-07 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349594840-11374-1-git-send-email-plagnioj@jcrosoft.com>
as the driver needing to knwon if we enter in slow_clock mode (SUSPEND_MEM)
have been swtich to pm ops
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: linux-pm at vger.kernel.org
---
arch/arm/mach-at91/include/mach/board.h | 3 ---
arch/arm/mach-at91/pm.c | 24 ------------------------
2 files changed, 27 deletions(-)
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index c55a436..e3ca86a 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -190,7 +190,4 @@ extern void __init at91_add_device_can(struct at91_can_data *data);
extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
-/* FIXME: this needs a better location, but gets stuff building again */
-extern int at91_suspend_entering_slow_clock(void);
-
#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 2c2d865..5e8d770 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -116,15 +116,11 @@ static int at91_pm_valid_state(suspend_state_t state)
}
}
-
-static suspend_state_t target_state;
-
/*
* Called after processes are frozen, but before we shutdown devices.
*/
static int at91_pm_begin(suspend_state_t state)
{
- target_state = state;
return 0;
}
@@ -172,23 +168,6 @@ static int at91_pm_verify_clocks(void)
return 1;
}
-/*
- * Call this from platform driver suspend() to see how deeply to suspend.
- * For example, some controllers (like OHCI) need one of the PLL clocks
- * in order to act as a wakeup source, and those are not available when
- * going into slow clock mode.
- *
- * REVISIT: generalize as clk_will_be_available(clk)? Other platforms have
- * the very same problem (but not using at91 main_clk), and it'd be better
- * to add one generic API rather than lots of platform-specific ones.
- */
-int at91_suspend_entering_slow_clock(void)
-{
- return (target_state == PM_SUSPEND_MEM);
-}
-EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
-
-
static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl);
@@ -283,7 +262,6 @@ static int at91_pm_enter(suspend_state_t state)
at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR));
error:
- target_state = PM_SUSPEND_ON;
at91_irq_resume();
at91_gpio_resume();
return 0;
@@ -294,10 +272,8 @@ error:
*/
static void at91_pm_end(void)
{
- target_state = PM_SUSPEND_ON;
}
-
static const struct platform_suspend_ops at91_pm_ops = {
.valid = at91_pm_valid_state,
.begin = at91_pm_begin,
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/6] usb: at91_ude: switch pm ops
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-07 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349594840-11374-1-git-send-email-plagnioj@jcrosoft.com>
so we can detect when we enter in slow_clock mode and drop
at91_suspend_entering_slow_clock
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: linux-pm at vger.kernel.org
Cc: linux-usb at vger.kernel.org
---
drivers/usb/gadget/at91_udc.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 89d90b5..ba5b0af 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1910,10 +1910,10 @@ static int __exit at91udc_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
+static int at91udc_suspend(struct device *dev, int slow_clock)
{
- struct at91_udc *udc = platform_get_drvdata(pdev);
- int wake = udc->driver && device_may_wakeup(&pdev->dev);
+ struct at91_udc *udc = dev_get_drvdata(dev);
+ int wake = udc->driver && device_may_wakeup(dev);
unsigned long flags;
/* Unless we can act normally to the host (letting it wake us up
@@ -1923,7 +1923,7 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
*/
if ((!udc->suspended && udc->addr)
|| !wake
- || at91_suspend_entering_slow_clock()) {
+ || slow_clock) {
spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 0);
wake = 0;
@@ -1937,9 +1937,19 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
return 0;
}
-static int at91udc_resume(struct platform_device *pdev)
+static int at91udc_suspend_standby(struct device *dev)
{
- struct at91_udc *udc = platform_get_drvdata(pdev);
+ return at91udc_suspend(dev, 0);
+}
+
+static int at91udc_suspend_mem(struct device *dev)
+{
+ return at91udc_suspend(dev, 1);
+}
+
+static int at91udc_resume(struct device *dev)
+{
+ struct at91_udc *udc = dev_get_drvdata(dev);
unsigned long flags;
if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled &&
@@ -1956,11 +1966,14 @@ static int at91udc_resume(struct platform_device *pdev)
}
return 0;
}
-#else
-#define at91udc_suspend NULL
-#define at91udc_resume NULL
#endif
+static struct dev_pm_ops at91_udc_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(at91udc_suspend_standby, at91udc_resume)
+ SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(at91udc_suspend_standby,
+ at91udc_suspend_mem)
+};
+
#if defined(CONFIG_OF)
static const struct of_device_id at91_udc_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-udc" },
@@ -1973,11 +1986,10 @@ MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
static struct platform_driver at91_udc_driver = {
.remove = __exit_p(at91udc_remove),
.shutdown = at91udc_shutdown,
- .suspend = at91udc_suspend,
- .resume = at91udc_resume,
.driver = {
.name = (char *) driver_name,
.owner = THIS_MODULE,
+ .pm = &at91_udc_pm_ops,
.of_match_table = of_match_ptr(at91_udc_dt_ids),
},
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/6] usb: ohci-at91: switch pm ops
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-07 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349594840-11374-1-git-send-email-plagnioj@jcrosoft.com>
so we can detect when we enter in slow_clock mode and drop
at91_suspend_entering_slow_clock
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: linux-pm at vger.kernel.org
Cc: linux-usb at vger.kernel.org
---
drivers/usb/host/ohci-at91.c | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 0bf72f9..316897d 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -668,14 +668,12 @@ static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-
-static int
-ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
+static int ohci_hcd_at91_drv_suspend(struct device *dev, int slow_clock)
{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- if (device_may_wakeup(&pdev->dev))
+ if (device_may_wakeup(dev))
enable_irq_wake(hcd->irq);
/*
@@ -685,7 +683,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
*
* REVISIT: some boards will be able to turn VBUS off...
*/
- if (at91_suspend_entering_slow_clock()) {
+ if (slow_clock) {
ohci_usb_reset (ohci);
/* flush the writes */
(void) ohci_readl (ohci, &ohci->regs->control);
@@ -695,11 +693,21 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
return 0;
}
-static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
+static int ohci_hcd_at91_drv_suspend_standby(struct device *dev)
+{
+ return ohci_hcd_at91_drv_suspend(dev, 0);
+}
+
+static int ohci_hcd_at91_drv_suspend_mem(struct device *dev)
+{
+ return ohci_hcd_at91_drv_suspend(dev, 1);
+}
+
+static int ohci_hcd_at91_drv_resume(struct device *dev)
{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
- if (device_may_wakeup(&pdev->dev))
+ if (device_may_wakeup(dev))
disable_irq_wake(hcd->irq);
if (!clocked)
@@ -708,22 +716,24 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
ohci_finish_controller_resume(hcd);
return 0;
}
-#else
-#define ohci_hcd_at91_drv_suspend NULL
-#define ohci_hcd_at91_drv_resume NULL
#endif
+static struct dev_pm_ops ohci_hcd_at91_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ohci_hcd_at91_drv_suspend_standby, ohci_hcd_at91_drv_resume)
+ SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(ohci_hcd_at91_drv_suspend_standby,
+ ohci_hcd_at91_drv_suspend_mem)
+};
+
MODULE_ALIAS("platform:at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
.remove = __devexit_p(ohci_hcd_at91_drv_remove),
.shutdown = usb_hcd_platform_shutdown,
- .suspend = ohci_hcd_at91_drv_suspend,
- .resume = ohci_hcd_at91_drv_resume,
.driver = {
.name = "at91_ohci",
.owner = THIS_MODULE,
+ .pm = &ohci_hcd_at91_pm_ops,
.of_match_table = of_match_ptr(at91_ohci_dt_ids),
},
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/6] tty: atmel_serial: switch pm ops
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-07 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349594840-11374-1-git-send-email-plagnioj@jcrosoft.com>
so we can detect when we enter in slow_clock mode and drop
at91_suspend_entering_slow_clock
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: linux-pm at vger.kernel.org
Cc: linux-serial at vger.kernel.org
---
drivers/tty/serial/atmel_serial.c | 52 +++++++++++++++++++------------------
1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 3d7e1ee..7a51a0c 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1720,20 +1720,10 @@ static struct uart_driver atmel_uart = {
};
#ifdef CONFIG_PM
-static bool atmel_serial_clk_will_stop(void)
+static int atmel_serial_suspend(struct device *dev, int slow_clock)
{
-#ifdef CONFIG_ARCH_AT91
- return at91_suspend_entering_slow_clock();
-#else
- return false;
-#endif
-}
-
-static int atmel_serial_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct uart_port *port = platform_get_drvdata(pdev);
- struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ struct atmel_uart_port *atmel_port = dev_get_drvdata(dev);
+ struct uart_port *port = &atmel_port->uart;
if (atmel_is_console_port(port) && console_suspend_enabled) {
/* Drain the TX shifter */
@@ -1742,30 +1732,43 @@ static int atmel_serial_suspend(struct platform_device *pdev,
}
/* we can not wake up if we're running on slow clock */
- atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
- if (atmel_serial_clk_will_stop())
- device_set_wakeup_enable(&pdev->dev, 0);
+ atmel_port->may_wakeup = device_may_wakeup(dev);
+ if (slow_clock)
+ device_set_wakeup_enable(dev, 0);
uart_suspend_port(&atmel_uart, port);
return 0;
}
-static int atmel_serial_resume(struct platform_device *pdev)
+static int atmel_serial_suspend_standby(struct device *dev)
{
- struct uart_port *port = platform_get_drvdata(pdev);
- struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ return atmel_serial_suspend(dev, 0);
+}
+
+static int atmel_serial_suspend_mem(struct device *dev)
+{
+ return atmel_serial_suspend(dev, 1);
+}
+
+static int atmel_serial_resume(struct device *dev)
+{
+ struct atmel_uart_port *atmel_port = dev_get_drvdata(dev);
+ struct uart_port *port = &atmel_port->uart;
uart_resume_port(&atmel_uart, port);
- device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup);
+ device_set_wakeup_enable(dev, atmel_port->may_wakeup);
return 0;
}
-#else
-#define atmel_serial_suspend NULL
-#define atmel_serial_resume NULL
#endif
+static struct dev_pm_ops atmel_serial_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(atmel_serial_suspend_standby, atmel_serial_resume)
+ SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(atmel_serial_suspend_standby,
+ atmel_serial_suspend_mem)
+};
+
static int __devinit atmel_serial_probe(struct platform_device *pdev)
{
struct atmel_uart_port *port;
@@ -1877,11 +1880,10 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
static struct platform_driver atmel_serial_driver = {
.probe = atmel_serial_probe,
.remove = __devexit_p(atmel_serial_remove),
- .suspend = atmel_serial_suspend,
- .resume = atmel_serial_resume,
.driver = {
.name = "atmel_usart",
.owner = THIS_MODULE,
+ .pm = &atmel_serial_pm_ops,
.of_match_table = of_match_ptr(atmel_serial_dt_ids),
},
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/6] platform: pm: add suspend_mem and suspend_standby support
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-07 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349594840-11374-1-git-send-email-plagnioj@jcrosoft.com>
If a drivers does not need to care about this distinction we fallback to
suspend. This will allow to do not update the current drivers.
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: linux-pm at vger.kernel.org
---
drivers/base/platform.c | 40 +++++++++++++++++++++++++++++++++++++++
include/linux/platform_device.h | 6 ++++++
2 files changed, 46 insertions(+)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8727e9c..f4822e2 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -740,6 +740,46 @@ static int platform_legacy_resume(struct device *dev)
#ifdef CONFIG_SUSPEND
+int platform_pm_suspend_mem(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->suspend_mem)
+ ret = drv->pm->suspend_mem(dev);
+ else if (drv->pm->suspend)
+ ret = drv->pm->suspend(dev);
+ } else {
+ ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
+ }
+
+ return ret;
+}
+
+int platform_pm_suspend_standby(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->suspend_standby)
+ ret = drv->pm->suspend_standby(dev);
+ else if (drv->pm->suspend)
+ ret = drv->pm->suspend(dev);
+ } else {
+ ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
+ }
+
+ return ret;
+}
+
int platform_pm_suspend(struct device *dev)
{
struct device_driver *drv = dev->driver;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 5711e95..a7c2275 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -262,9 +262,13 @@ static inline char *early_platform_driver_setup_func(void) \
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);
+extern int platform_pm_suspend_mem(struct device *dev);
+extern int platform_pm_suspend_standby(struct device *dev);
extern int platform_pm_resume(struct device *dev);
#else
#define platform_pm_suspend NULL
+#define platform_pm_suspend_mem NULL
+#define platform_pm_suspend_standby NULL
#define platform_pm_resume NULL
#endif
@@ -283,6 +287,8 @@ extern int platform_pm_restore(struct device *dev);
#ifdef CONFIG_PM_SLEEP
#define USE_PLATFORM_PM_SLEEP_OPS \
.suspend = platform_pm_suspend, \
+ .suspend_standby = platform_pm_suspend_standby, \
+ .suspend_mem = platform_pm_suspend_mem, \
.resume = platform_pm_resume, \
.freeze = platform_pm_freeze, \
.thaw = platform_pm_thaw, \
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/6] pm: add suspend_mem and suspend_standby support
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-10-07 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121006161429.GD12462@game.jcrosoft.org>
Today when we go to suspend we can not knwon at drivers level if we go in
STANDBY or MEM. Fix this by introducing two new callback suspend_mem and
suspend_standby.
If a bus does not need to care about this distinction we fallback to
suspend. This will allow to do not update the current bus or drivers.
This is needed as example by at91 OHCI and atmel serial
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: linux-pm at vger.kernel.org
---
drivers/base/power/main.c | 12 ++++++++++++
include/linux/pm.h | 9 +++++++++
kernel/power/suspend.c | 16 ++++++++++++++--
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index a3c1404..581e135 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -218,9 +218,21 @@ static void dpm_wait_for_children(struct device *dev, bool async)
*/
static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state)
{
+ pm_callback_t callback = NULL;
+
switch (state.event) {
#ifdef CONFIG_SUSPEND
case PM_EVENT_SUSPEND:
+ switch (state.param) {
+ case PM_SUSPEND_MEM:
+ callback = ops->suspend_mem;
+ break;
+ case PM_SUSPEND_STANDBY:
+ callback = ops->suspend_standby;
+ break;
+ }
+ if (callback)
+ return callback;
return ops->suspend;
case PM_EVENT_RESUME:
return ops->resume;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 007e687..aff344b 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -49,6 +49,7 @@ extern const char power_group_name[]; /* = "power" */
typedef struct pm_message {
int event;
+ int param;
} pm_message_t;
/**
@@ -265,6 +266,8 @@ struct dev_pm_ops {
int (*prepare)(struct device *dev);
void (*complete)(struct device *dev);
int (*suspend)(struct device *dev);
+ int (*suspend_mem)(struct device *dev);
+ int (*suspend_standby)(struct device *dev);
int (*resume)(struct device *dev);
int (*freeze)(struct device *dev);
int (*thaw)(struct device *dev);
@@ -295,8 +298,12 @@ struct dev_pm_ops {
.thaw = resume_fn, \
.poweroff = suspend_fn, \
.restore = resume_fn,
+#define SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(suspend_standby_fn, suspend_mem_fn) \
+ .suspend_standby = suspend_standby_fn, \
+ .suspend_mem = suspend_mem_fn,
#else
#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
+#define SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(suspend_standby_fn, suspend_mem_fn)
#endif
#ifdef CONFIG_PM_RUNTIME
@@ -414,6 +421,8 @@ const struct dev_pm_ops name = { \
#define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, })
#define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, })
#define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, })
+#define PMSG_SUSPEND_MEM ((struct pm_message){ .event = PM_EVENT_SUSPEND, .param = PM_SUSPEND_MEM, })
+#define PMSG_SUSPEND_STANDBY ((struct pm_message){ .event = PM_EVENT_SUSPEND, .param = PM_SUSPEND_STANDBY, })
#define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, })
#define PMSG_RESUME ((struct pm_message){ .event = PM_EVENT_RESUME, })
#define PMSG_THAW ((struct pm_message){ .event = PM_EVENT_THAW, })
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index c8b7446..9505b55 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -126,6 +126,18 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void)
local_irq_enable();
}
+static pm_message_t suspend_state_to_pm_state(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ return PMSG_SUSPEND_STANDBY;
+ case PM_SUSPEND_MEM:
+ return PMSG_SUSPEND_MEM;
+ default:
+ return PMSG_SUSPEND;
+ }
+}
+
/**
* suspend_enter - Make the system enter the given sleep state.
* @state: System sleep state to enter.
@@ -143,7 +155,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
goto Platform_finish;
}
- error = dpm_suspend_end(PMSG_SUSPEND);
+ error = dpm_suspend_end(suspend_state_to_pm_state(state));
if (error) {
printk(KERN_ERR "PM: Some devices failed to power down\n");
goto Platform_finish;
@@ -215,7 +227,7 @@ int suspend_devices_and_enter(suspend_state_t state)
suspend_console();
ftrace_stop();
suspend_test_start();
- error = dpm_suspend_start(PMSG_SUSPEND);
+ error = dpm_suspend_start(suspend_state_to_pm_state(state));
if (error) {
printk(KERN_ERR "PM: Some devices failed to suspend\n");
goto Recover_platform;
--
1.7.10.4
^ permalink raw reply related
* Mismatched aliases with DMA mappings?
From: Marek Szyprowski @ 2012-10-07 7:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120924095242.GA2122@linaro.org>
Hello,
I'm sorry for very late response but I was busy with other urgent items
after getting back from holidays.
On 9/24/2012 11:52 AM, Dave Martin wrote:
> On Sat, Sep 22, 2012 at 02:22:07PM +0900, Kyungmin Park wrote:
>> I just show how CMA addresses mismatched aliases codes.
>>
>> In reserve function, it declares the require memory size with base
>> address. At that time it calles 'dma_contiguous_early_fixup()'. it
>> just registered address and size.
>>
>> void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long
>> size)
>> {
>> dma_mmu_remap[dma_mmu_remap_num].base = base;
>> dma_mmu_remap[dma_mmu_remap_num].size = size;
>> dma_mmu_remap_num++;
>> }
>>
>> These registerd base and size will be remap at dma_contiguous_remap
>> function at paging_init.
>>
>> void __init dma_contiguous_remap(void)
>> {
>> int i;
>> for (i = 0; i < dma_mmu_remap_num; i++) {
>> phys_addr_t start = dma_mmu_remap[i].base;
>> phys_addr_t end = start + dma_mmu_remap[i].size;
>> struct map_desc map;
>> unsigned long addr;
>>
>> if (end > arm_lowmem_limit)
>> end = arm_lowmem_limit;
>> if (start >= end)
>> continue;
>>
>> map.pfn = __phys_to_pfn(start);
>> map.virtual = __phys_to_virt(start);
>> map.length = end - start;
>> map.type = MT_MEMORY_DMA_READY;
>>
>> /*
>> * Clear previous low-memory mapping
>> */
>> for (addr = __phys_to_virt(start); addr <
>> __phys_to_virt(end);
>> addr += PMD_SIZE)
>> pmd_clear(pmd_off_k(addr));
>>
>> iotable_init(&map, 1);
>> }
>> }
>
> OK, so it looks like this is done early and can't happen after the
> kernel has booted (?)
Right, the changes in the linear mapping for CMA areas are done very
early to make sure that the proper mapping will be available for all
processes in the system (CMA changes the size of the pages used for
holding low memory linear mappings from 1MiB/2MiB 1-level sections to
4KiB pages which require 2 levels of pte). Once the kernel has fully
started it is not (easily) possible to alter the linear mappings.
> Do you know whether the linear alias for DMA memory is removed when
> not using CMA?
Nope, when standard page_alloc() implementation of dma mapping is used
there exist 2 mappings for each allocated buffer: one in linear low
memory kernel mapping (cache'able) and the second created by the
dma-mapping subsystem (non-cache'able or writecombined). Right now no
one observed any issues caused by such situation assuming that no
process is accessing linear cache'able lowmem mappings when dma
non-cache'able mapping exist.
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
^ permalink raw reply
* [PATCH 0/6] ARM: Add support for Broadcom BCM476x SoCs
From: Stephen Warren @ 2012-10-07 5:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121007015300.828366635@gmail.com>
On 10/06/2012 07:53 PM, Domenico Andreoli wrote:
> Howdy,
>
> this patchset adds (minimal) support for the Broadcom BCM476x ARM based
> SoCs to the kernel, not to be confused with the already supported MIPS
> based BCM47xx SoC and other BCM47xx WiFi and GPS produced by Broadcom.
>
> This BCM476x is a DT-only multi-platform ARM platform and, at this spin,
Nice. I was planning on converting bcm2835 to multi-platform in 3.8; I
assume it'll be pretty simple.
...
> Additional support is being worked on.... and usb (DWC OTG) only
> attemped reusing s3c-hsotg.
Hmmm. I believe the bcm2835 uses DWC OTG. I wonder if the same driver
will work there; USB in particular is a major pain point on the bcm2835...
...
> It's based on a random pre v3.7-rc1 commit (eb0ad9c) with mainlined
> multi-platform support and Stephen's patch to add DEBUG_LL to it.
There are two chunks of code related to that; uncompress.h and
debug-macro.S. Rob/Arnd's multi-platform patches already allowed
debug-macro.S to exist after multi-platform conversion, and my patches
were about adding back support for uncompress.h. Given that the only
reason I cared about uncompress was that Tegra's uncompress.h and
debug-macro.s were closely coupled, and Nicolas Pitre indicated he
thought that was a hack, I've re-written the Tegra code so they aren't
coupled any more (this will be included in 3.8) and so I care much less
about uncompress.h now. Unless anyone really pipes up and says they'd
still like me to pursue uncompress.h in multi-platform, I'm inclined to
drop it.
> Special thanks go to Stephen Warren who, with the recently mainlined
> BCM2835, showed how to do things cleanly since the beginning and
> involuntarily spurred me to act.
Thanks! Do note that much of the code I upstreamed was originally
written by others, although I did make quite a few changes during
upstream submission.
^ permalink raw reply
* [PATCH] pwm: Get rid of HAVE_PWM
From: Shawn Guo @ 2012-10-07 4:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349330819-11924-1-git-send-email-thierry.reding@avionic-design.de>
On Thu, Oct 04, 2012 at 08:06:59AM +0200, Thierry Reding wrote:
> Now that all drivers have been moved to the PWM subsystem, remove the
> legacy HAVE_PWM symbol and replace it with the new PWM symbol. While at
> it, select the PWM subsystem and corresponding PWM driver on boards that
> require PWM functionality.
>
> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Shawn Guo <shawn.guo@linaro.org>
> Cc: Eric Miao <eric.y.miao@gmail.com>
> Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Bryan Wu <bryan.wu@canonical.com>
> Cc: Richard Purdie <rpurdie@rpsys.net>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Ashish Jangam <ashish.jangam@kpitcummins.com>
> Cc: Andrew Jones <drjones@redhat.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-mips at linux-mips.org
> Cc: linux-input at vger.kernel.org
> Cc: linux-leds at vger.kernel.org
> ---
> arch/arm/Kconfig | 6 ++----
> arch/arm/mach-mxs/Kconfig | 6 ++++--
Shawn Guo <shawn.guo@linaro.org>
> arch/arm/mach-pxa/Kconfig | 42 ++++++++++++++++++++++++++++--------------
> arch/mips/Kconfig | 3 ++-
> drivers/input/misc/Kconfig | 4 ++--
> drivers/leds/Kconfig | 2 +-
> include/linux/pwm.h | 2 +-
> 7 files changed, 40 insertions(+), 25 deletions(-)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox