aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ux500
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2011-02-07 22:54:37 -0500
committerLinus Walleij <linus.walleij@linaro.org>2011-02-17 07:56:12 -0500
commitaa90eb9d9d39d6e312b822cfa1512bb76e0e1df3 (patch)
tree28f3c2130a296be1644980c8d844b72025ff8f89 /arch/arm/mach-ux500
parent0e25a5c98067286fc727cf142fc0dadf95790921 (diff)
mach-ux500: DB8500 PMU support
DB8500 has irqs from two cores ORed into one. Implement a workaround to handle this by bouncing the interrupt by setting the affinity to the other core when the interrupt appears to be spurious on the current core. Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm/mach-ux500')
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 1748fbc5853..5c0fabf5fa0 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -12,22 +12,20 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/amba/bus.h> 14#include <linux/amba/bus.h>
15#include <linux/interrupt.h>
15#include <linux/irq.h> 16#include <linux/irq.h>
16#include <linux/gpio.h> 17#include <linux/gpio.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/io.h> 19#include <linux/io.h>
19 20
20#include <asm/mach/map.h> 21#include <asm/mach/map.h>
22#include <asm/pmu.h>
21#include <mach/hardware.h> 23#include <mach/hardware.h>
22#include <mach/setup.h> 24#include <mach/setup.h>
23#include <mach/devices.h> 25#include <mach/devices.h>
24 26
25#include "devices-db8500.h" 27#include "devices-db8500.h"
26 28
27static struct platform_device *platform_devs[] __initdata = {
28 &u8500_dma40_device,
29};
30
31/* minimum static i/o mapping required to boot U8500 platforms */ 29/* minimum static i/o mapping required to boot U8500 platforms */
32static struct map_desc u8500_uart_io_desc[] __initdata = { 30static struct map_desc u8500_uart_io_desc[] __initdata = {
33 __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), 31 __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K),
@@ -89,6 +87,51 @@ void __init u8500_map_io(void)
89 iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); 87 iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
90} 88}
91 89
90static struct resource db8500_pmu_resources[] = {
91 [0] = {
92 .start = IRQ_DB8500_PMU,
93 .end = IRQ_DB8500_PMU,
94 .flags = IORESOURCE_IRQ,
95 },
96};
97
98/*
99 * The PMU IRQ lines of two cores are wired together into a single interrupt.
100 * Bounce the interrupt to the other core if it's not ours.
101 */
102static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
103{
104 irqreturn_t ret = handler(irq, dev);
105 int other = !smp_processor_id();
106
107 if (ret == IRQ_NONE && cpu_online(other))
108 irq_set_affinity(irq, cpumask_of(other));
109
110 /*
111 * We should be able to get away with the amount of IRQ_NONEs we give,
112 * while still having the spurious IRQ detection code kick in if the
113 * interrupt really starts hitting spuriously.
114 */
115 return ret;
116}
117
118static struct arm_pmu_platdata db8500_pmu_platdata = {
119 .handle_irq = db8500_pmu_handler,
120};
121
122static struct platform_device db8500_pmu_device = {
123 .name = "arm-pmu",
124 .id = ARM_PMU_DEVICE_CPU,
125 .num_resources = ARRAY_SIZE(db8500_pmu_resources),
126 .resource = db8500_pmu_resources,
127 .dev.platform_data = &db8500_pmu_platdata,
128};
129
130static struct platform_device *platform_devs[] __initdata = {
131 &u8500_dma40_device,
132 &db8500_pmu_device,
133};
134
92static resource_size_t __initdata db8500_gpio_base[] = { 135static resource_size_t __initdata db8500_gpio_base[] = {
93 U8500_GPIOBANK0_BASE, 136 U8500_GPIOBANK0_BASE,
94 U8500_GPIOBANK1_BASE, 137 U8500_GPIOBANK1_BASE,