aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/pmu.txt4
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/configs/kzm9d_defconfig1
-rw-r--r--arch/arm/configs/kzm9g_defconfig1
-rw-r--r--arch/arm/include/asm/perf_event.h9
-rw-r--r--arch/arm/include/asm/pmu.h77
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/perf_event.c347
-rw-r--r--arch/arm/kernel/perf_event_cpu.c295
-rw-r--r--arch/arm/kernel/perf_event_v6.c12
-rw-r--r--arch/arm/kernel/perf_event_v7.c32
-rw-r--r--arch/arm/kernel/perf_event_xscale.c10
-rw-r--r--arch/arm/kernel/pmu.c36
-rw-r--r--arch/arm/mach-bcmring/arch.c3
-rw-r--r--arch/arm/mach-imx/clk-imx35.c11
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c14
-rw-r--r--arch/arm/mach-lpc32xx/irq.c7
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c20
-rw-r--r--arch/arm/mach-omap2/devices.c3
-rw-r--r--arch/arm/mach-pxa/devices.c3
-rw-r--r--arch/arm/mach-realview/realview_eb.c3
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c3
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c3
-rw-r--r--arch/arm/mach-realview/realview_pba8.c3
-rw-r--r--arch/arm/mach-realview/realview_pbx.c3
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c8
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c11
-rw-r--r--arch/arm/mach-shmobile/setup-emev2.c21
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c21
-rw-r--r--arch/arm/mach-tegra/devices.c3
-rw-r--r--arch/arm/mach-ux500/cache-l2x0.c2
-rw-r--r--arch/arm/mach-ux500/clock.c2
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c5
-rw-r--r--arch/arm/mach-ux500/cpu.c2
-rw-r--r--arch/arm/mach-ux500/include/mach/id.h44
-rw-r--r--arch/arm/mach-ux500/platsmp.c4
-rw-r--r--arch/arm/mach-ux500/timer.c2
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c3
-rw-r--r--arch/arm/plat-iop/pmu.c3
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h5
-rw-r--r--arch/arm/plat-mxc/ssi-fiq.S89
-rw-r--r--arch/arm/plat-samsung/devs.c3
43 files changed, 601 insertions, 539 deletions
diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt
index 1c044eb320cc..343781b9f246 100644
--- a/Documentation/devicetree/bindings/arm/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/pmu.txt
@@ -7,8 +7,12 @@ representation in the device tree should be done as under:-
7Required properties: 7Required properties:
8 8
9- compatible : should be one of 9- compatible : should be one of
10 "arm,cortex-a15-pmu"
10 "arm,cortex-a9-pmu" 11 "arm,cortex-a9-pmu"
11 "arm,cortex-a8-pmu" 12 "arm,cortex-a8-pmu"
13 "arm,cortex-a7-pmu"
14 "arm,cortex-a5-pmu"
15 "arm,arm11mpcore-pmu"
12 "arm,arm1176-pmu" 16 "arm,arm1176-pmu"
13 "arm,arm1136-pmu" 17 "arm,arm1136-pmu"
14- interrupts : 1 combined interrupt or 1 per core. 18- interrupts : 1 combined interrupt or 1 per core.
diff --git a/MAINTAINERS b/MAINTAINERS
index fdc0119963e7..437a7dd36843 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -595,7 +595,6 @@ M: Will Deacon <will.deacon@arm.com>
595S: Maintained 595S: Maintained
596F: arch/arm/kernel/perf_event* 596F: arch/arm/kernel/perf_event*
597F: arch/arm/oprofile/common.c 597F: arch/arm/oprofile/common.c
598F: arch/arm/kernel/pmu.c
599F: arch/arm/include/asm/pmu.h 598F: arch/arm/include/asm/pmu.h
600F: arch/arm/kernel/hw_breakpoint.c 599F: arch/arm/kernel/hw_breakpoint.c
601F: arch/arm/include/asm/hw_breakpoint.h 600F: arch/arm/include/asm/hw_breakpoint.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b23213d2764e..60355f1cc4b4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1180,12 +1180,6 @@ config XSCALE_PMU
1180 depends on CPU_XSCALE 1180 depends on CPU_XSCALE
1181 default y 1181 default y
1182 1182
1183config CPU_HAS_PMU
1184 depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
1185 (!ARCH_OMAP3 || OMAP3_EMU)
1186 default y
1187 bool
1188
1189config MULTI_IRQ_HANDLER 1183config MULTI_IRQ_HANDLER
1190 bool 1184 bool
1191 help 1185 help
@@ -1758,7 +1752,7 @@ config HIGHPTE
1758 1752
1759config HW_PERF_EVENTS 1753config HW_PERF_EVENTS
1760 bool "Enable hardware performance counter support for perf events" 1754 bool "Enable hardware performance counter support for perf events"
1761 depends on PERF_EVENTS && CPU_HAS_PMU 1755 depends on PERF_EVENTS
1762 default y 1756 default y
1763 help 1757 help
1764 Enable hardware performance counter support for perf events. If 1758 Enable hardware performance counter support for perf events. If
diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig
index 26146ffea1a5..8c49df66cac3 100644
--- a/arch/arm/configs/kzm9d_defconfig
+++ b/arch/arm/configs/kzm9d_defconfig
@@ -8,6 +8,7 @@ CONFIG_LOG_BUF_SHIFT=16
8CONFIG_CC_OPTIMIZE_FOR_SIZE=y 8CONFIG_CC_OPTIMIZE_FOR_SIZE=y
9CONFIG_SYSCTL_SYSCALL=y 9CONFIG_SYSCTL_SYSCALL=y
10CONFIG_EMBEDDED=y 10CONFIG_EMBEDDED=y
11CONFIG_PERF_EVENTS=y
11CONFIG_SLAB=y 12CONFIG_SLAB=y
12# CONFIG_BLK_DEV_BSG is not set 13# CONFIG_BLK_DEV_BSG is not set
13# CONFIG_IOSCHED_DEADLINE is not set 14# CONFIG_IOSCHED_DEADLINE is not set
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
index 2388c8610627..5d0c66708960 100644
--- a/arch/arm/configs/kzm9g_defconfig
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -14,6 +14,7 @@ CONFIG_NAMESPACES=y
14CONFIG_CC_OPTIMIZE_FOR_SIZE=y 14CONFIG_CC_OPTIMIZE_FOR_SIZE=y
15CONFIG_SYSCTL_SYSCALL=y 15CONFIG_SYSCTL_SYSCALL=y
16CONFIG_EMBEDDED=y 16CONFIG_EMBEDDED=y
17CONFIG_PERF_EVENTS=y
17CONFIG_SLAB=y 18CONFIG_SLAB=y
18CONFIG_MODULES=y 19CONFIG_MODULES=y
19CONFIG_MODULE_FORCE_LOAD=y 20CONFIG_MODULE_FORCE_LOAD=y
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index e074948d8143..625cd621a436 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -12,6 +12,13 @@
12#ifndef __ARM_PERF_EVENT_H__ 12#ifndef __ARM_PERF_EVENT_H__
13#define __ARM_PERF_EVENT_H__ 13#define __ARM_PERF_EVENT_H__
14 14
15/* Nothing to see here... */ 15/*
16 * The ARMv7 CPU PMU supports up to 32 event counters.
17 */
18#define ARMPMU_MAX_HWEVENTS 32
19
20#define HW_OP_UNSUPPORTED 0xFFFF
21#define C(_x) PERF_COUNT_HW_CACHE_##_x
22#define CACHE_OP_UNSUPPORTED 0xFFFF
16 23
17#endif /* __ARM_PERF_EVENT_H__ */ 24#endif /* __ARM_PERF_EVENT_H__ */
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 4432305f4a2a..a26170dce02e 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -16,69 +16,30 @@
16#include <linux/perf_event.h> 16#include <linux/perf_event.h>
17 17
18/* 18/*
19 * Types of PMUs that can be accessed directly and require mutual
20 * exclusion between profiling tools.
21 */
22enum arm_pmu_type {
23 ARM_PMU_DEVICE_CPU = 0,
24 ARM_NUM_PMU_DEVICES,
25};
26
27/*
28 * struct arm_pmu_platdata - ARM PMU platform data 19 * struct arm_pmu_platdata - ARM PMU platform data
29 * 20 *
30 * @handle_irq: an optional handler which will be called from the 21 * @handle_irq: an optional handler which will be called from the
31 * interrupt and passed the address of the low level handler, 22 * interrupt and passed the address of the low level handler,
32 * and can be used to implement any platform specific handling 23 * and can be used to implement any platform specific handling
33 * before or after calling it. 24 * before or after calling it.
34 * @enable_irq: an optional handler which will be called after 25 * @runtime_resume: an optional handler which will be called by the
35 * request_irq and be used to handle some platform specific 26 * runtime PM framework following a call to pm_runtime_get().
36 * irq enablement 27 * Note that if pm_runtime_get() is called more than once in
37 * @disable_irq: an optional handler which will be called before 28 * succession this handler will only be called once.
38 * free_irq and be used to handle some platform specific 29 * @runtime_suspend: an optional handler which will be called by the
39 * irq disablement 30 * runtime PM framework following a call to pm_runtime_put().
31 * Note that if pm_runtime_get() is called more than once in
32 * succession this handler will only be called following the
33 * final call to pm_runtime_put() that actually disables the
34 * hardware.
40 */ 35 */
41struct arm_pmu_platdata { 36struct arm_pmu_platdata {
42 irqreturn_t (*handle_irq)(int irq, void *dev, 37 irqreturn_t (*handle_irq)(int irq, void *dev,
43 irq_handler_t pmu_handler); 38 irq_handler_t pmu_handler);
44 void (*enable_irq)(int irq); 39 int (*runtime_resume)(struct device *dev);
45 void (*disable_irq)(int irq); 40 int (*runtime_suspend)(struct device *dev);
46}; 41};
47 42
48#ifdef CONFIG_CPU_HAS_PMU
49
50/**
51 * reserve_pmu() - reserve the hardware performance counters
52 *
53 * Reserve the hardware performance counters in the system for exclusive use.
54 * Returns 0 on success or -EBUSY if the lock is already held.
55 */
56extern int
57reserve_pmu(enum arm_pmu_type type);
58
59/**
60 * release_pmu() - Relinquish control of the performance counters
61 *
62 * Release the performance counters and allow someone else to use them.
63 */
64extern void
65release_pmu(enum arm_pmu_type type);
66
67#else /* CONFIG_CPU_HAS_PMU */
68
69#include <linux/err.h>
70
71static inline int
72reserve_pmu(enum arm_pmu_type type)
73{
74 return -ENODEV;
75}
76
77static inline void
78release_pmu(enum arm_pmu_type type) { }
79
80#endif /* CONFIG_CPU_HAS_PMU */
81
82#ifdef CONFIG_HW_PERF_EVENTS 43#ifdef CONFIG_HW_PERF_EVENTS
83 44
84/* The events for a given PMU register set. */ 45/* The events for a given PMU register set. */
@@ -103,7 +64,6 @@ struct pmu_hw_events {
103 64
104struct arm_pmu { 65struct arm_pmu {
105 struct pmu pmu; 66 struct pmu pmu;
106 enum arm_pmu_type type;
107 cpumask_t active_irqs; 67 cpumask_t active_irqs;
108 char *name; 68 char *name;
109 irqreturn_t (*handle_irq)(int irq_num, void *dev); 69 irqreturn_t (*handle_irq)(int irq_num, void *dev);
@@ -118,6 +78,8 @@ struct arm_pmu {
118 void (*start)(void); 78 void (*start)(void);
119 void (*stop)(void); 79 void (*stop)(void);
120 void (*reset)(void *); 80 void (*reset)(void *);
81 int (*request_irq)(irq_handler_t handler);
82 void (*free_irq)(void);
121 int (*map_event)(struct perf_event *event); 83 int (*map_event)(struct perf_event *event);
122 int num_events; 84 int num_events;
123 atomic_t active_events; 85 atomic_t active_events;
@@ -129,7 +91,9 @@ struct arm_pmu {
129 91
130#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) 92#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
131 93
132int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type); 94extern const struct dev_pm_ops armpmu_dev_pm_ops;
95
96int armpmu_register(struct arm_pmu *armpmu, char *name, int type);
133 97
134u64 armpmu_event_update(struct perf_event *event, 98u64 armpmu_event_update(struct perf_event *event,
135 struct hw_perf_event *hwc, 99 struct hw_perf_event *hwc,
@@ -139,6 +103,13 @@ int armpmu_event_set_period(struct perf_event *event,
139 struct hw_perf_event *hwc, 103 struct hw_perf_event *hwc,
140 int idx); 104 int idx);
141 105
106int armpmu_map_event(struct perf_event *event,
107 const unsigned (*event_map)[PERF_COUNT_HW_MAX],
108 const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
109 [PERF_COUNT_HW_CACHE_OP_MAX]
110 [PERF_COUNT_HW_CACHE_RESULT_MAX],
111 u32 raw_event_mask);
112
142#endif /* CONFIG_HW_PERF_EVENTS */ 113#endif /* CONFIG_HW_PERF_EVENTS */
143 114
144#endif /* __ARM_PMU_H__ */ 115#endif /* __ARM_PMU_H__ */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 7ad2d5cf7008..1c4321430737 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -69,8 +69,7 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
69obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o 69obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
70obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o 70obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
71obj-$(CONFIG_IWMMXT) += iwmmxt.o 71obj-$(CONFIG_IWMMXT) += iwmmxt.o
72obj-$(CONFIG_CPU_HAS_PMU) += pmu.o 72obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o
73obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
74AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt 73AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
75obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o 74obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
76 75
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index ab243b87118d..93971b1a4f0b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -12,68 +12,15 @@
12 */ 12 */
13#define pr_fmt(fmt) "hw perfevents: " fmt 13#define pr_fmt(fmt) "hw perfevents: " fmt
14 14
15#include <linux/bitmap.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h> 15#include <linux/kernel.h>
18#include <linux/export.h>
19#include <linux/perf_event.h>
20#include <linux/platform_device.h> 16#include <linux/platform_device.h>
21#include <linux/spinlock.h> 17#include <linux/pm_runtime.h>
22#include <linux/uaccess.h> 18#include <linux/uaccess.h>
23 19
24#include <asm/cputype.h>
25#include <asm/irq.h>
26#include <asm/irq_regs.h> 20#include <asm/irq_regs.h>
27#include <asm/pmu.h> 21#include <asm/pmu.h>
28#include <asm/stacktrace.h> 22#include <asm/stacktrace.h>
29 23
30/*
31 * ARMv6 supports a maximum of 3 events, starting from index 0. If we add
32 * another platform that supports more, we need to increase this to be the
33 * largest of all platforms.
34 *
35 * ARMv7 supports up to 32 events:
36 * cycle counter CCNT + 31 events counters CNT0..30.
37 * Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters.
38 */
39#define ARMPMU_MAX_HWEVENTS 32
40
41static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
42static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
43static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
44
45#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
46
47/* Set at runtime when we know what CPU type we are. */
48static struct arm_pmu *cpu_pmu;
49
50const char *perf_pmu_name(void)
51{
52 if (!cpu_pmu)
53 return NULL;
54
55 return cpu_pmu->pmu.name;
56}
57EXPORT_SYMBOL_GPL(perf_pmu_name);
58
59int perf_num_counters(void)
60{
61 int max_events = 0;
62
63 if (cpu_pmu != NULL)
64 max_events = cpu_pmu->num_events;
65
66 return max_events;
67}
68EXPORT_SYMBOL_GPL(perf_num_counters);
69
70#define HW_OP_UNSUPPORTED 0xFFFF
71
72#define C(_x) \
73 PERF_COUNT_HW_CACHE_##_x
74
75#define CACHE_OP_UNSUPPORTED 0xFFFF
76
77static int 24static int
78armpmu_map_cache_event(const unsigned (*cache_map) 25armpmu_map_cache_event(const unsigned (*cache_map)
79 [PERF_COUNT_HW_CACHE_MAX] 26 [PERF_COUNT_HW_CACHE_MAX]
@@ -104,7 +51,7 @@ armpmu_map_cache_event(const unsigned (*cache_map)
104} 51}
105 52
106static int 53static int
107armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) 54armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
108{ 55{
109 int mapping = (*event_map)[config]; 56 int mapping = (*event_map)[config];
110 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; 57 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
@@ -116,19 +63,20 @@ armpmu_map_raw_event(u32 raw_event_mask, u64 config)
116 return (int)(config & raw_event_mask); 63 return (int)(config & raw_event_mask);
117} 64}
118 65
119static int map_cpu_event(struct perf_event *event, 66int
120 const unsigned (*event_map)[PERF_COUNT_HW_MAX], 67armpmu_map_event(struct perf_event *event,
121 const unsigned (*cache_map) 68 const unsigned (*event_map)[PERF_COUNT_HW_MAX],
122 [PERF_COUNT_HW_CACHE_MAX] 69 const unsigned (*cache_map)
123 [PERF_COUNT_HW_CACHE_OP_MAX] 70 [PERF_COUNT_HW_CACHE_MAX]
124 [PERF_COUNT_HW_CACHE_RESULT_MAX], 71 [PERF_COUNT_HW_CACHE_OP_MAX]
125 u32 raw_event_mask) 72 [PERF_COUNT_HW_CACHE_RESULT_MAX],
73 u32 raw_event_mask)
126{ 74{
127 u64 config = event->attr.config; 75 u64 config = event->attr.config;
128 76
129 switch (event->attr.type) { 77 switch (event->attr.type) {
130 case PERF_TYPE_HARDWARE: 78 case PERF_TYPE_HARDWARE:
131 return armpmu_map_event(event_map, config); 79 return armpmu_map_hw_event(event_map, config);
132 case PERF_TYPE_HW_CACHE: 80 case PERF_TYPE_HW_CACHE:
133 return armpmu_map_cache_event(cache_map, config); 81 return armpmu_map_cache_event(cache_map, config);
134 case PERF_TYPE_RAW: 82 case PERF_TYPE_RAW:
@@ -222,7 +170,6 @@ armpmu_stop(struct perf_event *event, int flags)
222 */ 170 */
223 if (!(hwc->state & PERF_HES_STOPPED)) { 171 if (!(hwc->state & PERF_HES_STOPPED)) {
224 armpmu->disable(hwc, hwc->idx); 172 armpmu->disable(hwc, hwc->idx);
225 barrier(); /* why? */
226 armpmu_event_update(event, hwc, hwc->idx); 173 armpmu_event_update(event, hwc, hwc->idx);
227 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; 174 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
228 } 175 }
@@ -350,99 +297,41 @@ validate_group(struct perf_event *event)
350 return 0; 297 return 0;
351} 298}
352 299
353static irqreturn_t armpmu_platform_irq(int irq, void *dev) 300static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
354{ 301{
355 struct arm_pmu *armpmu = (struct arm_pmu *) dev; 302 struct arm_pmu *armpmu = (struct arm_pmu *) dev;
356 struct platform_device *plat_device = armpmu->plat_device; 303 struct platform_device *plat_device = armpmu->plat_device;
357 struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev); 304 struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev);
358 305
359 return plat->handle_irq(irq, dev, armpmu->handle_irq); 306 if (plat && plat->handle_irq)
307 return plat->handle_irq(irq, dev, armpmu->handle_irq);
308 else
309 return armpmu->handle_irq(irq, dev);
360} 310}
361 311
362static void 312static void
363armpmu_release_hardware(struct arm_pmu *armpmu) 313armpmu_release_hardware(struct arm_pmu *armpmu)
364{ 314{
365 int i, irq, irqs; 315 armpmu->free_irq();
366 struct platform_device *pmu_device = armpmu->plat_device; 316 pm_runtime_put_sync(&armpmu->plat_device->dev);
367 struct arm_pmu_platdata *plat =
368 dev_get_platdata(&pmu_device->dev);
369
370 irqs = min(pmu_device->num_resources, num_possible_cpus());
371
372 for (i = 0; i < irqs; ++i) {
373 if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
374 continue;
375 irq = platform_get_irq(pmu_device, i);
376 if (irq >= 0) {
377 if (plat && plat->disable_irq)
378 plat->disable_irq(irq);
379 free_irq(irq, armpmu);
380 }
381 }
382
383 release_pmu(armpmu->type);
384} 317}
385 318
386static int 319static int
387armpmu_reserve_hardware(struct arm_pmu *armpmu) 320armpmu_reserve_hardware(struct arm_pmu *armpmu)
388{ 321{
389 struct arm_pmu_platdata *plat; 322 int err;
390 irq_handler_t handle_irq;
391 int i, err, irq, irqs;
392 struct platform_device *pmu_device = armpmu->plat_device; 323 struct platform_device *pmu_device = armpmu->plat_device;
393 324
394 if (!pmu_device) 325 if (!pmu_device)
395 return -ENODEV; 326 return -ENODEV;
396 327
397 err = reserve_pmu(armpmu->type); 328 pm_runtime_get_sync(&pmu_device->dev);
329 err = armpmu->request_irq(armpmu_dispatch_irq);
398 if (err) { 330 if (err) {
399 pr_warning("unable to reserve pmu\n"); 331 armpmu_release_hardware(armpmu);
400 return err; 332 return err;
401 } 333 }
402 334
403 plat = dev_get_platdata(&pmu_device->dev);
404 if (plat && plat->handle_irq)
405 handle_irq = armpmu_platform_irq;
406 else
407 handle_irq = armpmu->handle_irq;
408
409 irqs = min(pmu_device->num_resources, num_possible_cpus());
410 if (irqs < 1) {
411 pr_err("no irqs for PMUs defined\n");
412 return -ENODEV;
413 }
414
415 for (i = 0; i < irqs; ++i) {
416 err = 0;
417 irq = platform_get_irq(pmu_device, i);
418 if (irq < 0)
419 continue;
420
421 /*
422 * If we have a single PMU interrupt that we can't shift,
423 * assume that we're running on a uniprocessor machine and
424 * continue. Otherwise, continue without this interrupt.
425 */
426 if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
427 pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
428 irq, i);
429 continue;
430 }
431
432 err = request_irq(irq, handle_irq,
433 IRQF_DISABLED | IRQF_NOBALANCING,
434 "arm-pmu", armpmu);
435 if (err) {
436 pr_err("unable to request IRQ%d for ARM PMU counters\n",
437 irq);
438 armpmu_release_hardware(armpmu);
439 return err;
440 } else if (plat && plat->enable_irq)
441 plat->enable_irq(irq);
442
443 cpumask_set_cpu(i, &armpmu->active_irqs);
444 }
445
446 return 0; 335 return 0;
447} 336}
448 337
@@ -581,6 +470,32 @@ static void armpmu_disable(struct pmu *pmu)
581 armpmu->stop(); 470 armpmu->stop();
582} 471}
583 472
473#ifdef CONFIG_PM_RUNTIME
474static int armpmu_runtime_resume(struct device *dev)
475{
476 struct arm_pmu_platdata *plat = dev_get_platdata(dev);
477
478 if (plat && plat->runtime_resume)
479 return plat->runtime_resume(dev);
480
481 return 0;
482}
483
484static int armpmu_runtime_suspend(struct device *dev)
485{
486 struct arm_pmu_platdata *plat = dev_get_platdata(dev);
487
488 if (plat && plat->runtime_suspend)
489 return plat->runtime_suspend(dev);
490
491 return 0;
492}
493#endif
494
495const struct dev_pm_ops armpmu_dev_pm_ops = {
496 SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
497};
498
584static void __init armpmu_init(struct arm_pmu *armpmu) 499static void __init armpmu_init(struct arm_pmu *armpmu)
585{ 500{
586 atomic_set(&armpmu->active_events, 0); 501 atomic_set(&armpmu->active_events, 0);
@@ -598,174 +513,14 @@ static void __init armpmu_init(struct arm_pmu *armpmu)
598 }; 513 };
599} 514}
600 515
601int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) 516int armpmu_register(struct arm_pmu *armpmu, char *name, int type)
602{ 517{
603 armpmu_init(armpmu); 518 armpmu_init(armpmu);
519 pr_info("enabled with %s PMU driver, %d counters available\n",
520 armpmu->name, armpmu->num_events);
604 return perf_pmu_register(&armpmu->pmu, name, type); 521 return perf_pmu_register(&armpmu->pmu, name, type);
605} 522}
606 523
607/* Include the PMU-specific implementations. */
608#include "perf_event_xscale.c"
609#include "perf_event_v6.c"
610#include "perf_event_v7.c"
611
612/*
613 * Ensure the PMU has sane values out of reset.
614 * This requires SMP to be available, so exists as a separate initcall.
615 */
616static int __init
617cpu_pmu_reset(void)
618{
619 if (cpu_pmu && cpu_pmu->reset)
620 return on_each_cpu(cpu_pmu->reset, NULL, 1);
621 return 0;
622}
623arch_initcall(cpu_pmu_reset);
624
625/*
626 * PMU platform driver and devicetree bindings.
627 */
628static struct of_device_id armpmu_of_device_ids[] = {
629 {.compatible = "arm,cortex-a9-pmu"},
630 {.compatible = "arm,cortex-a8-pmu"},
631 {.compatible = "arm,arm1136-pmu"},
632 {.compatible = "arm,arm1176-pmu"},
633 {},
634};
635
636static struct platform_device_id armpmu_plat_device_ids[] = {
637 {.name = "arm-pmu"},
638 {},
639};
640
641static int __devinit armpmu_device_probe(struct platform_device *pdev)
642{
643 if (!cpu_pmu)
644 return -ENODEV;
645
646 cpu_pmu->plat_device = pdev;
647 return 0;
648}
649
650static struct platform_driver armpmu_driver = {
651 .driver = {
652 .name = "arm-pmu",
653 .of_match_table = armpmu_of_device_ids,
654 },
655 .probe = armpmu_device_probe,
656 .id_table = armpmu_plat_device_ids,
657};
658
659static int __init register_pmu_driver(void)
660{
661 return platform_driver_register(&armpmu_driver);
662}
663device_initcall(register_pmu_driver);
664
665static struct pmu_hw_events *armpmu_get_cpu_events(void)
666{
667 return &__get_cpu_var(cpu_hw_events);
668}
669
670static void __init cpu_pmu_init(struct arm_pmu *armpmu)
671{
672 int cpu;
673 for_each_possible_cpu(cpu) {
674 struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
675 events->events = per_cpu(hw_events, cpu);
676 events->used_mask = per_cpu(used_mask, cpu);
677 raw_spin_lock_init(&events->pmu_lock);
678 }
679 armpmu->get_hw_events = armpmu_get_cpu_events;
680 armpmu->type = ARM_PMU_DEVICE_CPU;
681}
682
683/*
684 * PMU hardware loses all context when a CPU goes offline.
685 * When a CPU is hotplugged back in, since some hardware registers are
686 * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
687 * junk values out of them.
688 */
689static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
690 unsigned long action, void *hcpu)
691{
692 if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
693 return NOTIFY_DONE;
694
695 if (cpu_pmu && cpu_pmu->reset)
696 cpu_pmu->reset(NULL);
697
698 return NOTIFY_OK;
699}
700
701static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
702 .notifier_call = pmu_cpu_notify,
703};
704
705/*
706 * CPU PMU identification and registration.
707 */
708static int __init
709init_hw_perf_events(void)
710{
711 unsigned long cpuid = read_cpuid_id();
712 unsigned long implementor = (cpuid & 0xFF000000) >> 24;
713 unsigned long part_number = (cpuid & 0xFFF0);
714
715 /* ARM Ltd CPUs. */
716 if (0x41 == implementor) {
717 switch (part_number) {
718 case 0xB360: /* ARM1136 */
719 case 0xB560: /* ARM1156 */
720 case 0xB760: /* ARM1176 */
721 cpu_pmu = armv6pmu_init();
722 break;
723 case 0xB020: /* ARM11mpcore */
724 cpu_pmu = armv6mpcore_pmu_init();
725 break;
726 case 0xC080: /* Cortex-A8 */
727 cpu_pmu = armv7_a8_pmu_init();
728 break;
729 case 0xC090: /* Cortex-A9 */
730 cpu_pmu = armv7_a9_pmu_init();
731 break;
732 case 0xC050: /* Cortex-A5 */
733 cpu_pmu = armv7_a5_pmu_init();
734 break;
735 case 0xC0F0: /* Cortex-A15 */
736 cpu_pmu = armv7_a15_pmu_init();
737 break;
738 case 0xC070: /* Cortex-A7 */
739 cpu_pmu = armv7_a7_pmu_init();
740 break;
741 }
742 /* Intel CPUs [xscale]. */
743 } else if (0x69 == implementor) {
744 part_number = (cpuid >> 13) & 0x7;
745 switch (part_number) {
746 case 1:
747 cpu_pmu = xscale1pmu_init();
748 break;
749 case 2:
750 cpu_pmu = xscale2pmu_init();
751 break;
752 }
753 }
754
755 if (cpu_pmu) {
756 pr_info("enabled with %s PMU driver, %d counters available\n",
757 cpu_pmu->name, cpu_pmu->num_events);
758 cpu_pmu_init(cpu_pmu);
759 register_cpu_notifier(&pmu_cpu_notifier);
760 armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
761 } else {
762 pr_info("no hardware support available\n");
763 }
764
765 return 0;
766}
767early_initcall(init_hw_perf_events);
768
769/* 524/*
770 * Callchain handling code. 525 * Callchain handling code.
771 */ 526 */
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
new file mode 100644
index 000000000000..8d7d8d4de9d6
--- /dev/null
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -0,0 +1,295 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14 *
15 * Copyright (C) 2012 ARM Limited
16 *
17 * Author: Will Deacon <will.deacon@arm.com>
18 */
19#define pr_fmt(fmt) "CPU PMU: " fmt
20
21#include <linux/bitmap.h>
22#include <linux/export.h>
23#include <linux/kernel.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <linux/spinlock.h>
27
28#include <asm/cputype.h>
29#include <asm/irq_regs.h>
30#include <asm/pmu.h>
31
32/* Set at runtime when we know what CPU type we are. */
33static struct arm_pmu *cpu_pmu;
34
35static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
36static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
37static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
38
39/*
40 * Despite the names, these two functions are CPU-specific and are used
41 * by the OProfile/perf code.
42 */
43const char *perf_pmu_name(void)
44{
45 if (!cpu_pmu)
46 return NULL;
47
48 return cpu_pmu->pmu.name;
49}
50EXPORT_SYMBOL_GPL(perf_pmu_name);
51
52int perf_num_counters(void)
53{
54 int max_events = 0;
55
56 if (cpu_pmu != NULL)
57 max_events = cpu_pmu->num_events;
58
59 return max_events;
60}
61EXPORT_SYMBOL_GPL(perf_num_counters);
62
63/* Include the PMU-specific implementations. */
64#include "perf_event_xscale.c"
65#include "perf_event_v6.c"
66#include "perf_event_v7.c"
67
68static struct pmu_hw_events *cpu_pmu_get_cpu_events(void)
69{
70 return &__get_cpu_var(cpu_hw_events);
71}
72
73static void cpu_pmu_free_irq(void)
74{
75 int i, irq, irqs;
76 struct platform_device *pmu_device = cpu_pmu->plat_device;
77
78 irqs = min(pmu_device->num_resources, num_possible_cpus());
79
80 for (i = 0; i < irqs; ++i) {
81 if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
82 continue;
83 irq = platform_get_irq(pmu_device, i);
84 if (irq >= 0)
85 free_irq(irq, cpu_pmu);
86 }
87}
88
89static int cpu_pmu_request_irq(irq_handler_t handler)
90{
91 int i, err, irq, irqs;
92 struct platform_device *pmu_device = cpu_pmu->plat_device;
93
94 if (!pmu_device)
95 return -ENODEV;
96
97 irqs = min(pmu_device->num_resources, num_possible_cpus());
98 if (irqs < 1) {
99 pr_err("no irqs for PMUs defined\n");
100 return -ENODEV;
101 }
102
103 for (i = 0; i < irqs; ++i) {
104 err = 0;
105 irq = platform_get_irq(pmu_device, i);
106 if (irq < 0)
107 continue;
108
109 /*
110 * If we have a single PMU interrupt that we can't shift,
111 * assume that we're running on a uniprocessor machine and
112 * continue. Otherwise, continue without this interrupt.
113 */
114 if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
115 pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
116 irq, i);
117 continue;
118 }
119
120 err = request_irq(irq, handler, IRQF_NOBALANCING, "arm-pmu",
121 cpu_pmu);
122 if (err) {
123 pr_err("unable to request IRQ%d for ARM PMU counters\n",
124 irq);
125 return err;
126 }
127
128 cpumask_set_cpu(i, &cpu_pmu->active_irqs);
129 }
130
131 return 0;
132}
133
134static void __devinit cpu_pmu_init(struct arm_pmu *cpu_pmu)
135{
136 int cpu;
137 for_each_possible_cpu(cpu) {
138 struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
139 events->events = per_cpu(hw_events, cpu);
140 events->used_mask = per_cpu(used_mask, cpu);
141 raw_spin_lock_init(&events->pmu_lock);
142 }
143
144 cpu_pmu->get_hw_events = cpu_pmu_get_cpu_events;
145 cpu_pmu->request_irq = cpu_pmu_request_irq;
146 cpu_pmu->free_irq = cpu_pmu_free_irq;
147
148 /* Ensure the PMU has sane values out of reset. */
149 if (cpu_pmu && cpu_pmu->reset)
150 on_each_cpu(cpu_pmu->reset, NULL, 1);
151}
152
153/*
154 * PMU hardware loses all context when a CPU goes offline.
155 * When a CPU is hotplugged back in, since some hardware registers are
156 * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
157 * junk values out of them.
158 */
159static int __cpuinit cpu_pmu_notify(struct notifier_block *b,
160 unsigned long action, void *hcpu)
161{
162 if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
163 return NOTIFY_DONE;
164
165 if (cpu_pmu && cpu_pmu->reset)
166 cpu_pmu->reset(NULL);
167
168 return NOTIFY_OK;
169}
170
171static struct notifier_block __cpuinitdata cpu_pmu_hotplug_notifier = {
172 .notifier_call = cpu_pmu_notify,
173};
174
175/*
176 * PMU platform driver and devicetree bindings.
177 */
178static struct of_device_id __devinitdata cpu_pmu_of_device_ids[] = {
179 {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
180 {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
181 {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
182 {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
183 {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init},
184 {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init},
185 {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init},
186 {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init},
187 {},
188};
189
190static struct platform_device_id __devinitdata cpu_pmu_plat_device_ids[] = {
191 {.name = "arm-pmu"},
192 {},
193};
194
195/*
196 * CPU PMU identification and probing.
197 */
198static struct arm_pmu *__devinit probe_current_pmu(void)
199{
200 struct arm_pmu *pmu = NULL;
201 int cpu = get_cpu();
202 unsigned long cpuid = read_cpuid_id();
203 unsigned long implementor = (cpuid & 0xFF000000) >> 24;
204 unsigned long part_number = (cpuid & 0xFFF0);
205
206 pr_info("probing PMU on CPU %d\n", cpu);
207
208 /* ARM Ltd CPUs. */
209 if (0x41 == implementor) {
210 switch (part_number) {
211 case 0xB360: /* ARM1136 */
212 case 0xB560: /* ARM1156 */
213 case 0xB760: /* ARM1176 */
214 pmu = armv6pmu_init();
215 break;
216 case 0xB020: /* ARM11mpcore */
217 pmu = armv6mpcore_pmu_init();
218 break;
219 case 0xC080: /* Cortex-A8 */
220 pmu = armv7_a8_pmu_init();
221 break;
222 case 0xC090: /* Cortex-A9 */
223 pmu = armv7_a9_pmu_init();
224 break;
225 case 0xC050: /* Cortex-A5 */
226 pmu = armv7_a5_pmu_init();
227 break;
228 case 0xC0F0: /* Cortex-A15 */
229 pmu = armv7_a15_pmu_init();
230 break;
231 case 0xC070: /* Cortex-A7 */
232 pmu = armv7_a7_pmu_init();
233 break;
234 }
235 /* Intel CPUs [xscale]. */
236 } else if (0x69 == implementor) {
237 part_number = (cpuid >> 13) & 0x7;
238 switch (part_number) {
239 case 1:
240 pmu = xscale1pmu_init();
241 break;
242 case 2:
243 pmu = xscale2pmu_init();
244 break;
245 }
246 }
247
248 put_cpu();
249 return pmu;
250}
251
252static int __devinit cpu_pmu_device_probe(struct platform_device *pdev)
253{
254 const struct of_device_id *of_id;
255 struct arm_pmu *(*init_fn)(void);
256 struct device_node *node = pdev->dev.of_node;
257
258 if (cpu_pmu) {
259 pr_info("attempt to register multiple PMU devices!");
260 return -ENOSPC;
261 }
262
263 if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
264 init_fn = of_id->data;
265 cpu_pmu = init_fn();
266 } else {
267 cpu_pmu = probe_current_pmu();
268 }
269
270 if (!cpu_pmu)
271 return -ENODEV;
272
273 cpu_pmu->plat_device = pdev;
274 cpu_pmu_init(cpu_pmu);
275 register_cpu_notifier(&cpu_pmu_hotplug_notifier);
276 armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
277
278 return 0;
279}
280
281static struct platform_driver cpu_pmu_driver = {
282 .driver = {
283 .name = "arm-pmu",
284 .pm = &armpmu_dev_pm_ops,
285 .of_match_table = cpu_pmu_of_device_ids,
286 },
287 .probe = cpu_pmu_device_probe,
288 .id_table = cpu_pmu_plat_device_ids,
289};
290
291static int __init register_pmu_driver(void)
292{
293 return platform_driver_register(&cpu_pmu_driver);
294}
295device_initcall(register_pmu_driver);
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index c90fcb2b6967..6ccc07971745 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -645,7 +645,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
645 645
646static int armv6_map_event(struct perf_event *event) 646static int armv6_map_event(struct perf_event *event)
647{ 647{
648 return map_cpu_event(event, &armv6_perf_map, 648 return armpmu_map_event(event, &armv6_perf_map,
649 &armv6_perf_cache_map, 0xFF); 649 &armv6_perf_cache_map, 0xFF);
650} 650}
651 651
@@ -664,7 +664,7 @@ static struct arm_pmu armv6pmu = {
664 .max_period = (1LLU << 32) - 1, 664 .max_period = (1LLU << 32) - 1,
665}; 665};
666 666
667static struct arm_pmu *__init armv6pmu_init(void) 667static struct arm_pmu *__devinit armv6pmu_init(void)
668{ 668{
669 return &armv6pmu; 669 return &armv6pmu;
670} 670}
@@ -679,7 +679,7 @@ static struct arm_pmu *__init armv6pmu_init(void)
679 679
680static int armv6mpcore_map_event(struct perf_event *event) 680static int armv6mpcore_map_event(struct perf_event *event)
681{ 681{
682 return map_cpu_event(event, &armv6mpcore_perf_map, 682 return armpmu_map_event(event, &armv6mpcore_perf_map,
683 &armv6mpcore_perf_cache_map, 0xFF); 683 &armv6mpcore_perf_cache_map, 0xFF);
684} 684}
685 685
@@ -698,17 +698,17 @@ static struct arm_pmu armv6mpcore_pmu = {
698 .max_period = (1LLU << 32) - 1, 698 .max_period = (1LLU << 32) - 1,
699}; 699};
700 700
701static struct arm_pmu *__init armv6mpcore_pmu_init(void) 701static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
702{ 702{
703 return &armv6mpcore_pmu; 703 return &armv6mpcore_pmu;
704} 704}
705#else 705#else
706static struct arm_pmu *__init armv6pmu_init(void) 706static struct arm_pmu *__devinit armv6pmu_init(void)
707{ 707{
708 return NULL; 708 return NULL;
709} 709}
710 710
711static struct arm_pmu *__init armv6mpcore_pmu_init(void) 711static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
712{ 712{
713 return NULL; 713 return NULL;
714} 714}
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index f04070bd2183..bd4b090ebcfd 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -1204,31 +1204,31 @@ static void armv7pmu_reset(void *info)
1204 1204
1205static int armv7_a8_map_event(struct perf_event *event) 1205static int armv7_a8_map_event(struct perf_event *event)
1206{ 1206{
1207 return map_cpu_event(event, &armv7_a8_perf_map, 1207 return armpmu_map_event(event, &armv7_a8_perf_map,
1208 &armv7_a8_perf_cache_map, 0xFF); 1208 &armv7_a8_perf_cache_map, 0xFF);
1209} 1209}
1210 1210
1211static int armv7_a9_map_event(struct perf_event *event) 1211static int armv7_a9_map_event(struct perf_event *event)
1212{ 1212{
1213 return map_cpu_event(event, &armv7_a9_perf_map, 1213 return armpmu_map_event(event, &armv7_a9_perf_map,
1214 &armv7_a9_perf_cache_map, 0xFF); 1214 &armv7_a9_perf_cache_map, 0xFF);
1215} 1215}
1216 1216
1217static int armv7_a5_map_event(struct perf_event *event) 1217static int armv7_a5_map_event(struct perf_event *event)
1218{ 1218{
1219 return map_cpu_event(event, &armv7_a5_perf_map, 1219 return armpmu_map_event(event, &armv7_a5_perf_map,
1220 &armv7_a5_perf_cache_map, 0xFF); 1220 &armv7_a5_perf_cache_map, 0xFF);
1221} 1221}
1222 1222
1223static int armv7_a15_map_event(struct perf_event *event) 1223static int armv7_a15_map_event(struct perf_event *event)
1224{ 1224{
1225 return map_cpu_event(event, &armv7_a15_perf_map, 1225 return armpmu_map_event(event, &armv7_a15_perf_map,
1226 &armv7_a15_perf_cache_map, 0xFF); 1226 &armv7_a15_perf_cache_map, 0xFF);
1227} 1227}
1228 1228
1229static int armv7_a7_map_event(struct perf_event *event) 1229static int armv7_a7_map_event(struct perf_event *event)
1230{ 1230{
1231 return map_cpu_event(event, &armv7_a7_perf_map, 1231 return armpmu_map_event(event, &armv7_a7_perf_map,
1232 &armv7_a7_perf_cache_map, 0xFF); 1232 &armv7_a7_perf_cache_map, 0xFF);
1233} 1233}
1234 1234
@@ -1245,7 +1245,7 @@ static struct arm_pmu armv7pmu = {
1245 .max_period = (1LLU << 32) - 1, 1245 .max_period = (1LLU << 32) - 1,
1246}; 1246};
1247 1247
1248static u32 __init armv7_read_num_pmnc_events(void) 1248static u32 __devinit armv7_read_num_pmnc_events(void)
1249{ 1249{
1250 u32 nb_cnt; 1250 u32 nb_cnt;
1251 1251
@@ -1256,7 +1256,7 @@ static u32 __init armv7_read_num_pmnc_events(void)
1256 return nb_cnt + 1; 1256 return nb_cnt + 1;
1257} 1257}
1258 1258
1259static struct arm_pmu *__init armv7_a8_pmu_init(void) 1259static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
1260{ 1260{
1261 armv7pmu.name = "ARMv7 Cortex-A8"; 1261 armv7pmu.name = "ARMv7 Cortex-A8";
1262 armv7pmu.map_event = armv7_a8_map_event; 1262 armv7pmu.map_event = armv7_a8_map_event;
@@ -1264,7 +1264,7 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void)
1264 return &armv7pmu; 1264 return &armv7pmu;
1265} 1265}
1266 1266
1267static struct arm_pmu *__init armv7_a9_pmu_init(void) 1267static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
1268{ 1268{
1269 armv7pmu.name = "ARMv7 Cortex-A9"; 1269 armv7pmu.name = "ARMv7 Cortex-A9";
1270 armv7pmu.map_event = armv7_a9_map_event; 1270 armv7pmu.map_event = armv7_a9_map_event;
@@ -1272,7 +1272,7 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void)
1272 return &armv7pmu; 1272 return &armv7pmu;
1273} 1273}
1274 1274
1275static struct arm_pmu *__init armv7_a5_pmu_init(void) 1275static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
1276{ 1276{
1277 armv7pmu.name = "ARMv7 Cortex-A5"; 1277 armv7pmu.name = "ARMv7 Cortex-A5";
1278 armv7pmu.map_event = armv7_a5_map_event; 1278 armv7pmu.map_event = armv7_a5_map_event;
@@ -1280,7 +1280,7 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void)
1280 return &armv7pmu; 1280 return &armv7pmu;
1281} 1281}
1282 1282
1283static struct arm_pmu *__init armv7_a15_pmu_init(void) 1283static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
1284{ 1284{
1285 armv7pmu.name = "ARMv7 Cortex-A15"; 1285 armv7pmu.name = "ARMv7 Cortex-A15";
1286 armv7pmu.map_event = armv7_a15_map_event; 1286 armv7pmu.map_event = armv7_a15_map_event;
@@ -1289,7 +1289,7 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
1289 return &armv7pmu; 1289 return &armv7pmu;
1290} 1290}
1291 1291
1292static struct arm_pmu *__init armv7_a7_pmu_init(void) 1292static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
1293{ 1293{
1294 armv7pmu.name = "ARMv7 Cortex-A7"; 1294 armv7pmu.name = "ARMv7 Cortex-A7";
1295 armv7pmu.map_event = armv7_a7_map_event; 1295 armv7pmu.map_event = armv7_a7_map_event;
@@ -1298,27 +1298,27 @@ static struct arm_pmu *__init armv7_a7_pmu_init(void)
1298 return &armv7pmu; 1298 return &armv7pmu;
1299} 1299}
1300#else 1300#else
1301static struct arm_pmu *__init armv7_a8_pmu_init(void) 1301static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
1302{ 1302{
1303 return NULL; 1303 return NULL;
1304} 1304}
1305 1305
1306static struct arm_pmu *__init armv7_a9_pmu_init(void) 1306static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
1307{ 1307{
1308 return NULL; 1308 return NULL;
1309} 1309}
1310 1310
1311static struct arm_pmu *__init armv7_a5_pmu_init(void) 1311static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
1312{ 1312{
1313 return NULL; 1313 return NULL;
1314} 1314}
1315 1315
1316static struct arm_pmu *__init armv7_a15_pmu_init(void) 1316static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
1317{ 1317{
1318 return NULL; 1318 return NULL;
1319} 1319}
1320 1320
1321static struct arm_pmu *__init armv7_a7_pmu_init(void) 1321static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
1322{ 1322{
1323 return NULL; 1323 return NULL;
1324} 1324}
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index f759fe0bab63..426e19f380a2 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -430,7 +430,7 @@ xscale1pmu_write_counter(int counter, u32 val)
430 430
431static int xscale_map_event(struct perf_event *event) 431static int xscale_map_event(struct perf_event *event)
432{ 432{
433 return map_cpu_event(event, &xscale_perf_map, 433 return armpmu_map_event(event, &xscale_perf_map,
434 &xscale_perf_cache_map, 0xFF); 434 &xscale_perf_cache_map, 0xFF);
435} 435}
436 436
@@ -449,7 +449,7 @@ static struct arm_pmu xscale1pmu = {
449 .max_period = (1LLU << 32) - 1, 449 .max_period = (1LLU << 32) - 1,
450}; 450};
451 451
452static struct arm_pmu *__init xscale1pmu_init(void) 452static struct arm_pmu *__devinit xscale1pmu_init(void)
453{ 453{
454 return &xscale1pmu; 454 return &xscale1pmu;
455} 455}
@@ -816,17 +816,17 @@ static struct arm_pmu xscale2pmu = {
816 .max_period = (1LLU << 32) - 1, 816 .max_period = (1LLU << 32) - 1,
817}; 817};
818 818
819static struct arm_pmu *__init xscale2pmu_init(void) 819static struct arm_pmu *__devinit xscale2pmu_init(void)
820{ 820{
821 return &xscale2pmu; 821 return &xscale2pmu;
822} 822}
823#else 823#else
824static struct arm_pmu *__init xscale1pmu_init(void) 824static struct arm_pmu *__devinit xscale1pmu_init(void)
825{ 825{
826 return NULL; 826 return NULL;
827} 827}
828 828
829static struct arm_pmu *__init xscale2pmu_init(void) 829static struct arm_pmu *__devinit xscale2pmu_init(void)
830{ 830{
831 return NULL; 831 return NULL;
832} 832}
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
deleted file mode 100644
index 2334bf8a650a..000000000000
--- a/arch/arm/kernel/pmu.c
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * linux/arch/arm/kernel/pmu.c
3 *
4 * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
5 * Copyright (C) 2010 ARM Ltd, Will Deacon
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/err.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16
17#include <asm/pmu.h>
18
19/*
20 * PMU locking to ensure mutual exclusion between different subsystems.
21 */
22static unsigned long pmu_lock[BITS_TO_LONGS(ARM_NUM_PMU_DEVICES)];
23
24int
25reserve_pmu(enum arm_pmu_type type)
26{
27 return test_and_set_bit_lock(type, pmu_lock) ? -EBUSY : 0;
28}
29EXPORT_SYMBOL_GPL(reserve_pmu);
30
31void
32release_pmu(enum arm_pmu_type type)
33{
34 clear_bit_unlock(type, pmu_lock);
35}
36EXPORT_SYMBOL_GPL(release_pmu);
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
index 45c97b1ee9b1..76e795323569 100644
--- a/arch/arm/mach-bcmring/arch.c
+++ b/arch/arm/mach-bcmring/arch.c
@@ -29,7 +29,6 @@
29#include <asm/setup.h> 29#include <asm/setup.h>
30#include <asm/mach-types.h> 30#include <asm/mach-types.h>
31#include <asm/mach/time.h> 31#include <asm/mach/time.h>
32#include <asm/pmu.h>
33 32
34#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
35#include <mach/dma.h> 34#include <mach/dma.h>
@@ -116,7 +115,7 @@ static struct resource pmu_resource = {
116 115
117static struct platform_device pmu_device = { 116static struct platform_device pmu_device = {
118 .name = "arm-pmu", 117 .name = "arm-pmu",
119 .id = ARM_PMU_DEVICE_CPU, 118 .id = -1,
120 .resource = &pmu_resource, 119 .resource = &pmu_resource,
121 .num_resources = 1, 120 .num_resources = 1,
122}; 121};
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index c6422fb10bae..cebc71d5a5af 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -62,8 +62,8 @@ enum mx35_clks {
62 kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate, 62 kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
63 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, 63 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
64 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, 64 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
65 wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate, 65 wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
66 clk_max 66 gpu2d_gate, clk_max
67}; 67};
68 68
69static struct clk *clk[clk_max]; 69static struct clk *clk[clk_max];
@@ -142,6 +142,9 @@ int __init mx35_clocks_init()
142 142
143 clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4); 143 clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
144 144
145 clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel));
146 clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6);
147
145 clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0); 148 clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0);
146 clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2); 149 clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2);
147 clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4); 150 clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4);
@@ -192,7 +195,7 @@ int __init mx35_clocks_init()
192 clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26); 195 clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
193 clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30); 196 clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30);
194 197
195 clk[csi_gate] = imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3, 0); 198 clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MX35_CCM_CGR3, 0);
196 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2); 199 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2);
197 clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4); 200 clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4);
198 201
@@ -228,6 +231,7 @@ int __init mx35_clocks_init()
228 clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2"); 231 clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
229 clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); 232 clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
230 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); 233 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
234 clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
231 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); 235 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
232 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); 236 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
233 clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); 237 clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0");
@@ -255,6 +259,7 @@ int __init mx35_clocks_init()
255 clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc"); 259 clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
256 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); 260 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
257 clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0"); 261 clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0");
262 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
258 263
259 clk_prepare_enable(clk[spba_gate]); 264 clk_prepare_enable(clk[spba_gate]);
260 clk_prepare_enable(clk[gpio1_gate]); 265 clk_prepare_enable(clk[gpio1_gate]);
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 4bdcaa97bd98..db70d23f95fa 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -49,6 +49,7 @@ static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
49static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; 49static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", };
50static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; 50static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
51static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; 51static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
52static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
52 53
53enum imx5_clks { 54enum imx5_clks {
54 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, 55 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
@@ -82,6 +83,7 @@ enum imx5_clks {
82 ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate, 83 ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate,
83 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, 84 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
84 epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, 85 epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate,
86 can_sel, can1_serial_gate, can1_ipg_gate,
85 clk_max 87 clk_max
86}; 88};
87 89
@@ -421,8 +423,12 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
421 clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); 423 clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
422 clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); 424 clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
423 clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); 425 clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
424 clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "ipg", MXC_CCM_CCGR4, 6); 426 clk[can_sel] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2,
425 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 8); 427 mx53_can_sel, ARRAY_SIZE(mx53_can_sel));
428 clk[can1_serial_gate] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22);
429 clk[can1_ipg_gate] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20);
430 clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
431 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
426 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); 432 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
427 433
428 for (i = 0; i < ARRAY_SIZE(clk); i++) 434 for (i = 0; i < ARRAY_SIZE(clk); i++)
@@ -455,6 +461,10 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
455 clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi"); 461 clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi");
456 clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi"); 462 clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi");
457 clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi"); 463 clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi");
464 clk_register_clkdev(clk[can1_ipg_gate], "ipg", "53fc8000.can");
465 clk_register_clkdev(clk[can1_serial_gate], "per", "53fc8000.can");
466 clk_register_clkdev(clk[can2_ipg_gate], "ipg", "53fcc000.can");
467 clk_register_clkdev(clk[can2_serial_gate], "per", "53fcc000.can");
458 468
459 /* set SDHC root clock to 200MHZ*/ 469 /* set SDHC root clock to 200MHZ*/
460 clk_set_rate(clk[esdhc_a_podf], 200000000); 470 clk_set_rate(clk[esdhc_a_podf], 200000000);
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index 5b1cc35e6fba..3c6332753358 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -283,21 +283,25 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
283 case IRQ_TYPE_EDGE_RISING: 283 case IRQ_TYPE_EDGE_RISING:
284 /* Rising edge sensitive */ 284 /* Rising edge sensitive */
285 __lpc32xx_set_irq_type(d->hwirq, 1, 1); 285 __lpc32xx_set_irq_type(d->hwirq, 1, 1);
286 __irq_set_handler_locked(d->hwirq, handle_edge_irq);
286 break; 287 break;
287 288
288 case IRQ_TYPE_EDGE_FALLING: 289 case IRQ_TYPE_EDGE_FALLING:
289 /* Falling edge sensitive */ 290 /* Falling edge sensitive */
290 __lpc32xx_set_irq_type(d->hwirq, 0, 1); 291 __lpc32xx_set_irq_type(d->hwirq, 0, 1);
292 __irq_set_handler_locked(d->hwirq, handle_edge_irq);
291 break; 293 break;
292 294
293 case IRQ_TYPE_LEVEL_LOW: 295 case IRQ_TYPE_LEVEL_LOW:
294 /* Low level sensitive */ 296 /* Low level sensitive */
295 __lpc32xx_set_irq_type(d->hwirq, 0, 0); 297 __lpc32xx_set_irq_type(d->hwirq, 0, 0);
298 __irq_set_handler_locked(d->hwirq, handle_level_irq);
296 break; 299 break;
297 300
298 case IRQ_TYPE_LEVEL_HIGH: 301 case IRQ_TYPE_LEVEL_HIGH:
299 /* High level sensitive */ 302 /* High level sensitive */
300 __lpc32xx_set_irq_type(d->hwirq, 1, 0); 303 __lpc32xx_set_irq_type(d->hwirq, 1, 0);
304 __irq_set_handler_locked(d->hwirq, handle_level_irq);
301 break; 305 break;
302 306
303 /* Other modes are not supported */ 307 /* Other modes are not supported */
@@ -305,9 +309,6 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
305 return -EINVAL; 309 return -EINVAL;
306 } 310 }
307 311
308 /* Ok to use the level handler for all types */
309 irq_set_handler(d->hwirq, handle_level_irq);
310
311 return 0; 312 return 0;
312} 313}
313 314
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index b07dcc90829d..8f2a2f8712d7 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -37,6 +37,8 @@
37#include <linux/of_irq.h> 37#include <linux/of_irq.h>
38#include <linux/of_platform.h> 38#include <linux/of_platform.h>
39#include <linux/clk.h> 39#include <linux/clk.h>
40#include <linux/mtd/lpc32xx_slc.h>
41#include <linux/mtd/lpc32xx_mlc.h>
40 42
41#include <asm/setup.h> 43#include <asm/setup.h>
42#include <asm/mach-types.h> 44#include <asm/mach-types.h>
@@ -223,6 +225,14 @@ static struct mmci_platform_data lpc32xx_mmci_data = {
223 * gather, and the MMCI driver doesn't do it this way */ 225 * gather, and the MMCI driver doesn't do it this way */
224}; 226};
225 227
228static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {
229 .dma_filter = pl08x_filter_id,
230};
231
232static struct lpc32xx_mlc_platform_data lpc32xx_mlc_data = {
233 .dma_filter = pl08x_filter_id,
234};
235
226static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { 236static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
227 OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data), 237 OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data),
228 OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data), 238 OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data),
@@ -230,6 +240,10 @@ static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
230 OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd), 240 OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd),
231 OF_DEV_AUXDATA("arm,pl18x", 0x20098000, "20098000.sd", 241 OF_DEV_AUXDATA("arm,pl18x", 0x20098000, "20098000.sd",
232 &lpc32xx_mmci_data), 242 &lpc32xx_mmci_data),
243 OF_DEV_AUXDATA("nxp,lpc3220-slc", 0x20020000, "20020000.flash",
244 &lpc32xx_slc_data),
245 OF_DEV_AUXDATA("nxp,lpc3220-mlc", 0x200a8000, "200a8000.flash",
246 &lpc32xx_mlc_data),
233 { } 247 { }
234}; 248};
235 249
@@ -253,12 +267,6 @@ static void __init lpc3250_machine_init(void)
253 267
254 of_platform_populate(NULL, of_default_bus_match_table, 268 of_platform_populate(NULL, of_default_bus_match_table,
255 lpc32xx_auxdata_lookup, NULL); 269 lpc32xx_auxdata_lookup, NULL);
256
257 /* Register GPIOs used on this board */
258 if (gpio_request(MMC_PWR_ENABLE_GPIO, "mmc_power_en"))
259 pr_err("Error requesting gpio %u", MMC_PWR_ENABLE_GPIO);
260 else if (gpio_direction_output(MMC_PWR_ENABLE_GPIO, 1))
261 pr_err("Error setting gpio %u to output", MMC_PWR_ENABLE_GPIO);
262} 270}
263 271
264static char const *lpc32xx_dt_compat[] __initdata = { 272static char const *lpc32xx_dt_compat[] __initdata = {
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index c00c68961bb8..02b9478b786f 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -23,7 +23,6 @@
23#include <mach/irqs.h> 23#include <mach/irqs.h>
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/mach/map.h> 25#include <asm/mach/map.h>
26#include <asm/pmu.h>
27 26
28#include "iomap.h" 27#include "iomap.h"
29#include <plat/board.h> 28#include <plat/board.h>
@@ -448,7 +447,7 @@ static struct resource omap3_pmu_resource = {
448 447
449static struct platform_device omap_pmu_device = { 448static struct platform_device omap_pmu_device = {
450 .name = "arm-pmu", 449 .name = "arm-pmu",
451 .id = ARM_PMU_DEVICE_CPU, 450 .id = -1,
452 .num_resources = 1, 451 .num_resources = 1,
453}; 452};
454 453
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 166eee5b8a70..c1f3b1279d97 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -6,7 +6,6 @@
6#include <linux/spi/pxa2xx_spi.h> 6#include <linux/spi/pxa2xx_spi.h>
7#include <linux/i2c/pxa-i2c.h> 7#include <linux/i2c/pxa-i2c.h>
8 8
9#include <asm/pmu.h>
10#include <mach/udc.h> 9#include <mach/udc.h>
11#include <mach/pxa3xx-u2d.h> 10#include <mach/pxa3xx-u2d.h>
12#include <mach/pxafb.h> 11#include <mach/pxafb.h>
@@ -42,7 +41,7 @@ static struct resource pxa_resource_pmu = {
42 41
43struct platform_device pxa_device_pmu = { 42struct platform_device pxa_device_pmu = {
44 .name = "arm-pmu", 43 .name = "arm-pmu",
45 .id = ARM_PMU_DEVICE_CPU, 44 .id = -1,
46 .resource = &pxa_resource_pmu, 45 .resource = &pxa_resource_pmu,
47 .num_resources = 1, 46 .num_resources = 1,
48}; 47};
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index baf382c5e776..d7a6e9cebba4 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -32,7 +32,6 @@
32#include <asm/irq.h> 32#include <asm/irq.h>
33#include <asm/leds.h> 33#include <asm/leds.h>
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <asm/pmu.h>
36#include <asm/pgtable.h> 35#include <asm/pgtable.h>
37#include <asm/hardware/gic.h> 36#include <asm/hardware/gic.h>
38#include <asm/hardware/cache-l2x0.h> 37#include <asm/hardware/cache-l2x0.h>
@@ -297,7 +296,7 @@ static struct resource pmu_resources[] = {
297 296
298static struct platform_device pmu_device = { 297static struct platform_device pmu_device = {
299 .name = "arm-pmu", 298 .name = "arm-pmu",
300 .id = ARM_PMU_DEVICE_CPU, 299 .id = -1,
301 .num_resources = ARRAY_SIZE(pmu_resources), 300 .num_resources = ARRAY_SIZE(pmu_resources),
302 .resource = pmu_resources, 301 .resource = pmu_resources,
303}; 302};
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index b1d7cafa1a6d..361f898884c8 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -34,7 +34,6 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/leds.h> 35#include <asm/leds.h>
36#include <asm/mach-types.h> 36#include <asm/mach-types.h>
37#include <asm/pmu.h>
38#include <asm/pgtable.h> 37#include <asm/pgtable.h>
39#include <asm/hardware/gic.h> 38#include <asm/hardware/gic.h>
40#include <asm/hardware/cache-l2x0.h> 39#include <asm/hardware/cache-l2x0.h>
@@ -280,7 +279,7 @@ static struct resource pmu_resource = {
280 279
281static struct platform_device pmu_device = { 280static struct platform_device pmu_device = {
282 .name = "arm-pmu", 281 .name = "arm-pmu",
283 .id = ARM_PMU_DEVICE_CPU, 282 .id = -1,
284 .num_resources = 1, 283 .num_resources = 1,
285 .resource = &pmu_resource, 284 .resource = &pmu_resource,
286}; 285};
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index a98c536e3327..c56bc8d4d11b 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -32,7 +32,6 @@
32#include <asm/irq.h> 32#include <asm/irq.h>
33#include <asm/leds.h> 33#include <asm/leds.h>
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <asm/pmu.h>
36#include <asm/pgtable.h> 35#include <asm/pgtable.h>
37#include <asm/hardware/gic.h> 36#include <asm/hardware/gic.h>
38#include <asm/hardware/cache-l2x0.h> 37#include <asm/hardware/cache-l2x0.h>
@@ -263,7 +262,7 @@ static struct resource pmu_resources[] = {
263 262
264static struct platform_device pmu_device = { 263static struct platform_device pmu_device = {
265 .name = "arm-pmu", 264 .name = "arm-pmu",
266 .id = ARM_PMU_DEVICE_CPU, 265 .id = -1,
267 .num_resources = ARRAY_SIZE(pmu_resources), 266 .num_resources = ARRAY_SIZE(pmu_resources),
268 .resource = pmu_resources, 267 .resource = pmu_resources,
269}; 268};
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 59650174e6ed..040937582453 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -31,7 +31,6 @@
31#include <asm/irq.h> 31#include <asm/irq.h>
32#include <asm/leds.h> 32#include <asm/leds.h>
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <asm/pmu.h>
35#include <asm/pgtable.h> 34#include <asm/pgtable.h>
36#include <asm/hardware/gic.h> 35#include <asm/hardware/gic.h>
37 36
@@ -241,7 +240,7 @@ static struct resource pmu_resource = {
241 240
242static struct platform_device pmu_device = { 241static struct platform_device pmu_device = {
243 .name = "arm-pmu", 242 .name = "arm-pmu",
244 .id = ARM_PMU_DEVICE_CPU, 243 .id = -1,
245 .num_resources = 1, 244 .num_resources = 1,
246 .resource = &pmu_resource, 245 .resource = &pmu_resource,
247}; 246};
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 3f2f605624e9..97885dc11e8c 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -30,7 +30,6 @@
30#include <asm/irq.h> 30#include <asm/irq.h>
31#include <asm/leds.h> 31#include <asm/leds.h>
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33#include <asm/pmu.h>
34#include <asm/smp_twd.h> 33#include <asm/smp_twd.h>
35#include <asm/pgtable.h> 34#include <asm/pgtable.h>
36#include <asm/hardware/gic.h> 35#include <asm/hardware/gic.h>
@@ -280,7 +279,7 @@ static struct resource pmu_resources[] = {
280 279
281static struct platform_device pmu_device = { 280static struct platform_device pmu_device = {
282 .name = "arm-pmu", 281 .name = "arm-pmu",
283 .id = ARM_PMU_DEVICE_CPU, 282 .id = -1,
284 .num_resources = ARRAY_SIZE(pmu_resources), 283 .num_resources = ARRAY_SIZE(pmu_resources),
285 .resource = pmu_resources, 284 .resource = pmu_resources,
286}; 285};
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index 53b7ea92c32c..fd21fb6f9953 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -763,6 +763,13 @@ static void __init kzm_init(void)
763 platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); 763 platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
764} 764}
765 765
766static void kzm9g_restart(char mode, const char *cmd)
767{
768#define RESCNT2 0xe6188020
769 /* Do soft power on reset */
770 writel((1 << 31), RESCNT2);
771}
772
766static const char *kzm9g_boards_compat_dt[] __initdata = { 773static const char *kzm9g_boards_compat_dt[] __initdata = {
767 "renesas,kzm9g", 774 "renesas,kzm9g",
768 NULL, 775 NULL,
@@ -777,5 +784,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g")
777 .init_machine = kzm_init, 784 .init_machine = kzm_init,
778 .init_late = shmobile_init_late, 785 .init_late = shmobile_init_late,
779 .timer = &shmobile_timer, 786 .timer = &shmobile_timer,
787 .restart = kzm9g_restart,
780 .dt_compat = kzm9g_boards_compat_dt, 788 .dt_compat = kzm9g_boards_compat_dt,
781MACHINE_END 789MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 339c62c824d5..3cafb6ab5e9a 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -86,11 +86,16 @@ static struct clk div4_clks[DIV4_NR] = {
86 0x0300, CLK_ENABLE_ON_INIT), 86 0x0300, CLK_ENABLE_ON_INIT),
87}; 87};
88 88
89enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, 89enum { MSTP323, MSTP322, MSTP321, MSTP320,
90 MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
90 MSTP016, MSTP015, MSTP014, 91 MSTP016, MSTP015, MSTP014,
91 MSTP_NR }; 92 MSTP_NR };
92 93
93static struct clk mstp_clks[MSTP_NR] = { 94static struct clk mstp_clks[MSTP_NR] = {
95 [MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 23, 0), /* SDHI0 */
96 [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */
97 [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */
98 [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */
94 [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */ 99 [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */
95 [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */ 100 [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */
96 [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */ 101 [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */
@@ -149,6 +154,10 @@ static struct clk_lookup lookups[] = {
149 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */ 154 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
150 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */ 155 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
151 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */ 156 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
157 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
158 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
159 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
160 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
152}; 161};
153 162
154void __init r8a7779_clock_init(void) 163void __init r8a7779_clock_init(void)
diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
index dae9aa68bb09..61446f30e397 100644
--- a/arch/arm/mach-shmobile/setup-emev2.c
+++ b/arch/arm/mach-shmobile/setup-emev2.c
@@ -356,6 +356,26 @@ static struct platform_device gio4_device = {
356 }, 356 },
357}; 357};
358 358
359static struct resource pmu_resources[] = {
360 [0] = {
361 .start = 152,
362 .end = 152,
363 .flags = IORESOURCE_IRQ,
364 },
365 [1] = {
366 .start = 153,
367 .end = 153,
368 .flags = IORESOURCE_IRQ,
369 },
370};
371
372static struct platform_device pmu_device = {
373 .name = "arm-pmu",
374 .id = -1,
375 .num_resources = ARRAY_SIZE(pmu_resources),
376 .resource = pmu_resources,
377};
378
359static struct platform_device *emev2_early_devices[] __initdata = { 379static struct platform_device *emev2_early_devices[] __initdata = {
360 &uart0_device, 380 &uart0_device,
361 &uart1_device, 381 &uart1_device,
@@ -370,6 +390,7 @@ static struct platform_device *emev2_late_devices[] __initdata = {
370 &gio2_device, 390 &gio2_device,
371 &gio3_device, 391 &gio3_device,
372 &gio4_device, 392 &gio4_device,
393 &pmu_device,
373}; 394};
374 395
375void __init emev2_add_standard_devices(void) 396void __init emev2_add_standard_devices(void)
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index d230af656fc9..38ed2ddd3265 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -734,6 +734,26 @@ static struct platform_device mpdma0_device = {
734 }, 734 },
735}; 735};
736 736
737static struct resource pmu_resources[] = {
738 [0] = {
739 .start = gic_spi(55),
740 .end = gic_spi(55),
741 .flags = IORESOURCE_IRQ,
742 },
743 [1] = {
744 .start = gic_spi(56),
745 .end = gic_spi(56),
746 .flags = IORESOURCE_IRQ,
747 },
748};
749
750static struct platform_device pmu_device = {
751 .name = "arm-pmu",
752 .id = -1,
753 .num_resources = ARRAY_SIZE(pmu_resources),
754 .resource = pmu_resources,
755};
756
737static struct platform_device *sh73a0_early_devices[] __initdata = { 757static struct platform_device *sh73a0_early_devices[] __initdata = {
738 &scif0_device, 758 &scif0_device,
739 &scif1_device, 759 &scif1_device,
@@ -757,6 +777,7 @@ static struct platform_device *sh73a0_late_devices[] __initdata = {
757 &i2c4_device, 777 &i2c4_device,
758 &dma0_device, 778 &dma0_device,
759 &mpdma0_device, 779 &mpdma0_device,
780 &pmu_device,
760}; 781};
761 782
762#define SRCR2 0xe61580b0 783#define SRCR2 0xe61580b0
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index c70e65ffa36b..61e9603744a7 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -23,7 +23,6 @@
23#include <linux/fsl_devices.h> 23#include <linux/fsl_devices.h>
24#include <linux/serial_8250.h> 24#include <linux/serial_8250.h>
25#include <linux/i2c-tegra.h> 25#include <linux/i2c-tegra.h>
26#include <asm/pmu.h>
27#include <mach/irqs.h> 26#include <mach/irqs.h>
28#include <mach/iomap.h> 27#include <mach/iomap.h>
29#include <mach/dma.h> 28#include <mach/dma.h>
@@ -516,7 +515,7 @@ static struct resource tegra_pmu_resources[] = {
516 515
517struct platform_device tegra_pmu_device = { 516struct platform_device tegra_pmu_device = {
518 .name = "arm-pmu", 517 .name = "arm-pmu",
519 .id = ARM_PMU_DEVICE_CPU, 518 .id = -1,
520 .num_resources = ARRAY_SIZE(tegra_pmu_resources), 519 .num_resources = ARRAY_SIZE(tegra_pmu_resources),
521 .resource = tegra_pmu_resources, 520 .resource = tegra_pmu_resources,
522}; 521};
diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index dc12394295d5..75d5b512a3d5 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -38,7 +38,7 @@ static int __init ux500_l2x0_init(void)
38{ 38{
39 u32 aux_val = 0x3e000000; 39 u32 aux_val = 0x3e000000;
40 40
41 if (cpu_is_u8500_family()) 41 if (cpu_is_u8500_family() || cpu_is_ux540_family())
42 l2x0_base = __io_address(U8500_L2CC_BASE); 42 l2x0_base = __io_address(U8500_L2CC_BASE);
43 else 43 else
44 ux500_unknown_soc(); 44 ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 8d73b066a18d..bc5a516a5865 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -149,7 +149,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
149 unsigned long mturate; 149 unsigned long mturate;
150 unsigned long retclk; 150 unsigned long retclk;
151 151
152 if (cpu_is_u8500_family()) 152 if (cpu_is_u8500_family() || cpu_is_ux540_family())
153 addr = __io_address(U8500_PRCMU_BASE); 153 addr = __io_address(U8500_PRCMU_BASE);
154 else 154 else
155 ux500_unknown_soc(); 155 ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index db3c52d56ca4..8169f2c72d6c 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -19,7 +19,6 @@
19#include <linux/mfd/abx500/ab8500.h> 19#include <linux/mfd/abx500/ab8500.h>
20 20
21#include <asm/mach/map.h> 21#include <asm/mach/map.h>
22#include <asm/pmu.h>
23#include <plat/gpio-nomadik.h> 22#include <plat/gpio-nomadik.h>
24#include <mach/hardware.h> 23#include <mach/hardware.h>
25#include <mach/setup.h> 24#include <mach/setup.h>
@@ -80,7 +79,7 @@ void __init u8500_map_io(void)
80 79
81 iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc)); 80 iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc));
82 81
83 if (cpu_is_u9540()) 82 if (cpu_is_ux540_family())
84 iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc)); 83 iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
85 else 84 else
86 iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); 85 iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
@@ -122,7 +121,7 @@ struct arm_pmu_platdata db8500_pmu_platdata = {
122 121
123static struct platform_device db8500_pmu_device = { 122static struct platform_device db8500_pmu_device = {
124 .name = "arm-pmu", 123 .name = "arm-pmu",
125 .id = ARM_PMU_DEVICE_CPU, 124 .id = -1,
126 .num_resources = ARRAY_SIZE(db8500_pmu_resources), 125 .num_resources = ARRAY_SIZE(db8500_pmu_resources),
127 .resource = db8500_pmu_resources, 126 .resource = db8500_pmu_resources,
128 .dev.platform_data = &db8500_pmu_platdata, 127 .dev.platform_data = &db8500_pmu_platdata,
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index e2360e7c770d..4b0a9b300312 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -51,7 +51,7 @@ void __init ux500_init_irq(void)
51 void __iomem *dist_base; 51 void __iomem *dist_base;
52 void __iomem *cpu_base; 52 void __iomem *cpu_base;
53 53
54 if (cpu_is_u8500_family()) { 54 if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
55 dist_base = __io_address(U8500_GIC_DIST_BASE); 55 dist_base = __io_address(U8500_GIC_DIST_BASE);
56 cpu_base = __io_address(U8500_GIC_CPU_BASE); 56 cpu_base = __io_address(U8500_GIC_CPU_BASE);
57 } else 57 } else
diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h
index c6e2db9e9e51..9c42642ab168 100644
--- a/arch/arm/mach-ux500/include/mach/id.h
+++ b/arch/arm/mach-ux500/include/mach/id.h
@@ -41,43 +41,29 @@ static inline bool __attribute_const__ cpu_is_u8500(void)
41 return dbx500_partnumber() == 0x8500; 41 return dbx500_partnumber() == 0x8500;
42} 42}
43 43
44static inline bool __attribute_const__ cpu_is_u9540(void) 44static inline bool __attribute_const__ cpu_is_u8520(void)
45{ 45{
46 return dbx500_partnumber() == 0x9540; 46 return dbx500_partnumber() == 0x8520;
47} 47}
48 48
49static inline bool cpu_is_u8500_family(void) 49static inline bool cpu_is_u8500_family(void)
50{ 50{
51 return cpu_is_u8500() || cpu_is_u9540(); 51 return cpu_is_u8500() || cpu_is_u8520();
52}
53
54static inline bool __attribute_const__ cpu_is_u5500(void)
55{
56 return dbx500_partnumber() == 0x5500;
57}
58
59/*
60 * 5500 revisions
61 */
62
63static inline bool __attribute_const__ cpu_is_u5500v1(void)
64{
65 return cpu_is_u5500() && (dbx500_revision() & 0xf0) == 0xA0;
66} 52}
67 53
68static inline bool __attribute_const__ cpu_is_u5500v2(void) 54static inline bool __attribute_const__ cpu_is_u9540(void)
69{ 55{
70 return (dbx500_id.revision & 0xf0) == 0xB0; 56 return dbx500_partnumber() == 0x9540;
71} 57}
72 58
73static inline bool __attribute_const__ cpu_is_u5500v20(void) 59static inline bool __attribute_const__ cpu_is_u8540(void)
74{ 60{
75 return cpu_is_u5500() && ((dbx500_revision() & 0xf0) == 0xB0); 61 return dbx500_partnumber() == 0x8540;
76} 62}
77 63
78static inline bool __attribute_const__ cpu_is_u5500v21(void) 64static inline bool cpu_is_ux540_family(void)
79{ 65{
80 return cpu_is_u5500() && (dbx500_revision() == 0xB1); 66 return cpu_is_u9540() || cpu_is_u8540();
81} 67}
82 68
83/* 69/*
@@ -119,14 +105,14 @@ static inline bool cpu_is_u8500v21(void)
119 return cpu_is_u8500() && (dbx500_revision() == 0xB1); 105 return cpu_is_u8500() && (dbx500_revision() == 0xB1);
120} 106}
121 107
108static inline bool cpu_is_u8500v22(void)
109{
110 return cpu_is_u8500() && (dbx500_revision() == 0xB2);
111}
112
122static inline bool cpu_is_u8500v20_or_later(void) 113static inline bool cpu_is_u8500v20_or_later(void)
123{ 114{
124 /* 115 return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11());
125 * U9540 has so much in common with U8500 that is is considered a
126 * U8500 variant.
127 */
128 return cpu_is_u9540() ||
129 (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11());
130} 116}
131 117
132static inline bool ux500_is_svp(void) 118static inline bool ux500_is_svp(void)
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index da1d5ad5bd45..a5dda68444db 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -48,7 +48,7 @@ static void write_pen_release(int val)
48 48
49static void __iomem *scu_base_addr(void) 49static void __iomem *scu_base_addr(void)
50{ 50{
51 if (cpu_is_u8500_family()) 51 if (cpu_is_u8500_family() || cpu_is_ux540_family())
52 return __io_address(U8500_SCU_BASE); 52 return __io_address(U8500_SCU_BASE);
53 else 53 else
54 ux500_unknown_soc(); 54 ux500_unknown_soc();
@@ -118,7 +118,7 @@ static void __init wakeup_secondary(void)
118{ 118{
119 void __iomem *backupram; 119 void __iomem *backupram;
120 120
121 if (cpu_is_u8500_family()) 121 if (cpu_is_u8500_family() || cpu_is_ux540_family())
122 backupram = __io_address(U8500_BACKUPRAM0_BASE); 122 backupram = __io_address(U8500_BACKUPRAM0_BASE);
123 else 123 else
124 ux500_unknown_soc(); 124 ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index 66e7f00884ab..6f39731951b0 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -54,7 +54,7 @@ static void __init ux500_timer_init(void)
54 void __iomem *tmp_base; 54 void __iomem *tmp_base;
55 struct device_node *np; 55 struct device_node *np;
56 56
57 if (cpu_is_u8500_family()) { 57 if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
58 mtu_timer_base = __io_address(U8500_MTU0_BASE); 58 mtu_timer_base = __io_address(U8500_MTU0_BASE);
59 prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); 59 prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
60 } else { 60 } else {
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 61c492403b05..e4073a60a864 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -13,7 +13,6 @@
13#include <asm/hardware/arm_timer.h> 13#include <asm/hardware/arm_timer.h>
14#include <asm/hardware/cache-l2x0.h> 14#include <asm/hardware/cache-l2x0.h>
15#include <asm/hardware/gic.h> 15#include <asm/hardware/gic.h>
16#include <asm/pmu.h>
17#include <asm/smp_scu.h> 16#include <asm/smp_scu.h>
18#include <asm/smp_twd.h> 17#include <asm/smp_twd.h>
19 18
@@ -144,7 +143,7 @@ static struct resource pmu_resources[] = {
144 143
145static struct platform_device pmu_device = { 144static struct platform_device pmu_device = {
146 .name = "arm-pmu", 145 .name = "arm-pmu",
147 .id = ARM_PMU_DEVICE_CPU, 146 .id = -1,
148 .num_resources = ARRAY_SIZE(pmu_resources), 147 .num_resources = ARRAY_SIZE(pmu_resources),
149 .resource = pmu_resources, 148 .resource = pmu_resources,
150}; 149};
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c
index a2024b8685a1..ad9f9744a82d 100644
--- a/arch/arm/plat-iop/pmu.c
+++ b/arch/arm/plat-iop/pmu.c
@@ -9,7 +9,6 @@
9 */ 9 */
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <asm/pmu.h>
13#include <mach/irqs.h> 12#include <mach/irqs.h>
14 13
15static struct resource pmu_resource = { 14static struct resource pmu_resource = {
@@ -26,7 +25,7 @@ static struct resource pmu_resource = {
26 25
27static struct platform_device pmu_device = { 26static struct platform_device pmu_device = {
28 .name = "arm-pmu", 27 .name = "arm-pmu",
29 .id = ARM_PMU_DEVICE_CPU, 28 .id = -1,
30 .resource = &pmu_resource, 29 .resource = &pmu_resource,
31 .num_resources = 1, 30 .num_resources = 1,
32}; 31};
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index d8b65b51f2a9..f79f78a1c0ed 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -512,12 +512,16 @@ enum iomux_pins {
512#define MX31_PIN_CSPI3_SPI_RDY__CTS3 IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_ALT1) 512#define MX31_PIN_CSPI3_SPI_RDY__CTS3 IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_ALT1)
513#define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC) 513#define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC)
514#define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC) 514#define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC)
515#define MX31_PIN_RTS1__SFS IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_ALT2)
515#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC) 516#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC)
517#define MX31_PIN_TXD1__SCK IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_ALT2)
516#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC) 518#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC)
519#define MX31_PIN_RXD1__STXDA IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_ALT2)
517#define MX31_PIN_DCD_DCE1__DCD_DCE1 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_FUNC) 520#define MX31_PIN_DCD_DCE1__DCD_DCE1 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_FUNC)
518#define MX31_PIN_RI_DCE1__RI_DCE1 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_FUNC) 521#define MX31_PIN_RI_DCE1__RI_DCE1 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_FUNC)
519#define MX31_PIN_DSR_DCE1__DSR_DCE1 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_FUNC) 522#define MX31_PIN_DSR_DCE1__DSR_DCE1 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_FUNC)
520#define MX31_PIN_DTR_DCE1__DTR_DCE1 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_FUNC) 523#define MX31_PIN_DTR_DCE1__DTR_DCE1 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_FUNC)
524#define MX31_PIN_DTR_DCE1__SRXDA IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_ALT2)
521#define MX31_PIN_CTS2__CTS2 IOMUX_MODE(MX31_PIN_CTS2, IOMUX_CONFIG_FUNC) 525#define MX31_PIN_CTS2__CTS2 IOMUX_MODE(MX31_PIN_CTS2, IOMUX_CONFIG_FUNC)
522#define MX31_PIN_RTS2__RTS2 IOMUX_MODE(MX31_PIN_RTS2, IOMUX_CONFIG_FUNC) 526#define MX31_PIN_RTS2__RTS2 IOMUX_MODE(MX31_PIN_RTS2, IOMUX_CONFIG_FUNC)
523#define MX31_PIN_TXD2__TXD2 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_FUNC) 527#define MX31_PIN_TXD2__TXD2 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_FUNC)
@@ -721,6 +725,7 @@ enum iomux_pins {
721#define MX31_PIN_KEY_ROW2_KEY_ROW2 IOMUX_MODE(MX31_PIN_KEY_ROW2, IOMUX_CONFIG_FUNC) 725#define MX31_PIN_KEY_ROW2_KEY_ROW2 IOMUX_MODE(MX31_PIN_KEY_ROW2, IOMUX_CONFIG_FUNC)
722#define MX31_PIN_KEY_ROW3_KEY_ROW3 IOMUX_MODE(MX31_PIN_KEY_ROW3, IOMUX_CONFIG_FUNC) 726#define MX31_PIN_KEY_ROW3_KEY_ROW3 IOMUX_MODE(MX31_PIN_KEY_ROW3, IOMUX_CONFIG_FUNC)
723#define MX31_PIN_KEY_ROW4_KEY_ROW4 IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_FUNC) 727#define MX31_PIN_KEY_ROW4_KEY_ROW4 IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_FUNC)
728#define MX31_PIN_KEY_ROW4_GPIO IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO)
724#define MX31_PIN_KEY_ROW5_KEY_ROW5 IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_FUNC) 729#define MX31_PIN_KEY_ROW5_KEY_ROW5 IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_FUNC)
725#define MX31_PIN_KEY_ROW6_KEY_ROW6 IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_FUNC) 730#define MX31_PIN_KEY_ROW6_KEY_ROW6 IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_FUNC)
726#define MX31_PIN_KEY_ROW7_KEY_ROW7 IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_FUNC) 731#define MX31_PIN_KEY_ROW7_KEY_ROW7 IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_FUNC)
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/plat-mxc/ssi-fiq.S
index 8397a2dd19f2..a8b93c5f29b5 100644
--- a/arch/arm/plat-mxc/ssi-fiq.S
+++ b/arch/arm/plat-mxc/ssi-fiq.S
@@ -34,91 +34,98 @@
34 .global imx_ssi_fiq_rx_buffer 34 .global imx_ssi_fiq_rx_buffer
35 .global imx_ssi_fiq_tx_buffer 35 .global imx_ssi_fiq_tx_buffer
36 36
37/*
38 * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
39 * using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to
40 * mark the function body so that it can be copied to the FIQ vector in
41 * the vectors page. imx_ssi_fiq_start should only be called as the result
42 * of an FIQ: calling it directly will not work.
43 */
37imx_ssi_fiq_start: 44imx_ssi_fiq_start:
38 ldr r12, imx_ssi_fiq_base 45 ldr r12, .L_imx_ssi_fiq_base
39 46
40 /* TX */ 47 /* TX */
41 ldr r11, imx_ssi_fiq_tx_buffer 48 ldr r13, .L_imx_ssi_fiq_tx_buffer
42 49
43 /* shall we send? */ 50 /* shall we send? */
44 ldr r13, [r12, #SSI_SIER] 51 ldr r11, [r12, #SSI_SIER]
45 tst r13, #SSI_SIER_TFE0_EN 52 tst r11, #SSI_SIER_TFE0_EN
46 beq 1f 53 beq 1f
47 54
48 /* TX FIFO empty? */ 55 /* TX FIFO empty? */
49 ldr r13, [r12, #SSI_SISR] 56 ldr r11, [r12, #SSI_SISR]
50 tst r13, #SSI_SISR_TFE0 57 tst r11, #SSI_SISR_TFE0
51 beq 1f 58 beq 1f
52 59
53 mov r10, #0x10000 60 mov r10, #0x10000
54 sub r10, #1 61 sub r10, #1
55 and r10, r10, r8 /* r10: current buffer offset */ 62 and r10, r10, r8 /* r10: current buffer offset */
56 63
57 add r11, r11, r10 64 add r13, r13, r10
58 65
59 ldrh r13, [r11] 66 ldrh r11, [r13]
60 strh r13, [r12, #SSI_STX0] 67 strh r11, [r12, #SSI_STX0]
61 68
62 ldrh r13, [r11, #2] 69 ldrh r11, [r13, #2]
63 strh r13, [r12, #SSI_STX0] 70 strh r11, [r12, #SSI_STX0]
64 71
65 ldrh r13, [r11, #4] 72 ldrh r11, [r13, #4]
66 strh r13, [r12, #SSI_STX0] 73 strh r11, [r12, #SSI_STX0]
67 74
68 ldrh r13, [r11, #6] 75 ldrh r11, [r13, #6]
69 strh r13, [r12, #SSI_STX0] 76 strh r11, [r12, #SSI_STX0]
70 77
71 add r10, #8 78 add r10, #8
72 lsr r13, r8, #16 /* r13: buffer size */ 79 lsr r11, r8, #16 /* r11: buffer size */
73 cmp r10, r13 80 cmp r10, r11
74 lslgt r8, r13, #16 81 lslgt r8, r11, #16
75 addle r8, #8 82 addle r8, #8
761: 831:
77 /* RX */ 84 /* RX */
78 85
79 /* shall we receive? */ 86 /* shall we receive? */
80 ldr r13, [r12, #SSI_SIER] 87 ldr r11, [r12, #SSI_SIER]
81 tst r13, #SSI_SIER_RFF0_EN 88 tst r11, #SSI_SIER_RFF0_EN
82 beq 1f 89 beq 1f
83 90
84 /* RX FIFO full? */ 91 /* RX FIFO full? */
85 ldr r13, [r12, #SSI_SISR] 92 ldr r11, [r12, #SSI_SISR]
86 tst r13, #SSI_SISR_RFF0 93 tst r11, #SSI_SISR_RFF0
87 beq 1f 94 beq 1f
88 95
89 ldr r11, imx_ssi_fiq_rx_buffer 96 ldr r13, .L_imx_ssi_fiq_rx_buffer
90 97
91 mov r10, #0x10000 98 mov r10, #0x10000
92 sub r10, #1 99 sub r10, #1
93 and r10, r10, r9 /* r10: current buffer offset */ 100 and r10, r10, r9 /* r10: current buffer offset */
94 101
95 add r11, r11, r10 102 add r13, r13, r10
96 103
97 ldr r13, [r12, #SSI_SACNT] 104 ldr r11, [r12, #SSI_SACNT]
98 tst r13, #SSI_SACNT_AC97EN 105 tst r11, #SSI_SACNT_AC97EN
99 106
100 ldr r13, [r12, #SSI_SRX0] 107 ldr r11, [r12, #SSI_SRX0]
101 strh r13, [r11] 108 strh r11, [r13]
102 109
103 ldr r13, [r12, #SSI_SRX0] 110 ldr r11, [r12, #SSI_SRX0]
104 strh r13, [r11, #2] 111 strh r11, [r13, #2]
105 112
106 /* dummy read to skip slot 12 */ 113 /* dummy read to skip slot 12 */
107 ldrne r13, [r12, #SSI_SRX0] 114 ldrne r11, [r12, #SSI_SRX0]
108 115
109 ldr r13, [r12, #SSI_SRX0] 116 ldr r11, [r12, #SSI_SRX0]
110 strh r13, [r11, #4] 117 strh r11, [r13, #4]
111 118
112 ldr r13, [r12, #SSI_SRX0] 119 ldr r11, [r12, #SSI_SRX0]
113 strh r13, [r11, #6] 120 strh r11, [r13, #6]
114 121
115 /* dummy read to skip slot 12 */ 122 /* dummy read to skip slot 12 */
116 ldrne r13, [r12, #SSI_SRX0] 123 ldrne r11, [r12, #SSI_SRX0]
117 124
118 add r10, #8 125 add r10, #8
119 lsr r13, r9, #16 /* r13: buffer size */ 126 lsr r11, r9, #16 /* r11: buffer size */
120 cmp r10, r13 127 cmp r10, r11
121 lslgt r9, r13, #16 128 lslgt r9, r11, #16
122 addle r9, #8 129 addle r9, #8
123 130
1241: 1311:
@@ -126,11 +133,15 @@ imx_ssi_fiq_start:
126 subs pc, lr, #4 133 subs pc, lr, #4
127 134
128 .align 135 .align
136.L_imx_ssi_fiq_base:
129imx_ssi_fiq_base: 137imx_ssi_fiq_base:
130 .word 0x0 138 .word 0x0
139.L_imx_ssi_fiq_rx_buffer:
131imx_ssi_fiq_rx_buffer: 140imx_ssi_fiq_rx_buffer:
132 .word 0x0 141 .word 0x0
142.L_imx_ssi_fiq_tx_buffer:
133imx_ssi_fiq_tx_buffer: 143imx_ssi_fiq_tx_buffer:
134 .word 0x0 144 .word 0x0
145.L_imx_ssi_fiq_end:
135imx_ssi_fiq_end: 146imx_ssi_fiq_end:
136 147
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index fc49f3dabd76..6ff45d53362c 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -35,7 +35,6 @@
35#include <media/s5p_hdmi.h> 35#include <media/s5p_hdmi.h>
36 36
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/pmu.h>
39#include <asm/mach/arch.h> 38#include <asm/mach/arch.h>
40#include <asm/mach/map.h> 39#include <asm/mach/map.h>
41#include <asm/mach/irq.h> 40#include <asm/mach/irq.h>
@@ -1132,7 +1131,7 @@ static struct resource s5p_pmu_resource[] = {
1132 1131
1133static struct platform_device s5p_device_pmu = { 1132static struct platform_device s5p_device_pmu = {
1134 .name = "arm-pmu", 1133 .name = "arm-pmu",
1135 .id = ARM_PMU_DEVICE_CPU, 1134 .id = -1,
1136 .num_resources = ARRAY_SIZE(s5p_pmu_resource), 1135 .num_resources = ARRAY_SIZE(s5p_pmu_resource),
1137 .resource = s5p_pmu_resource, 1136 .resource = s5p_pmu_resource,
1138}; 1137};