diff options
106 files changed, 1492 insertions, 1075 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 1a8cc600067d..28f65c249b97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2649,11 +2649,11 @@ F: drivers/net/wan/dlci.c | |||
2649 | F: drivers/net/wan/sdla.c | 2649 | F: drivers/net/wan/sdla.c |
2650 | 2650 | ||
2651 | FRAMEBUFFER LAYER | 2651 | FRAMEBUFFER LAYER |
2652 | M: Paul Mundt <lethal@linux-sh.org> | 2652 | M: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> |
2653 | L: linux-fbdev@vger.kernel.org | 2653 | L: linux-fbdev@vger.kernel.org |
2654 | W: http://linux-fbdev.sourceforge.net/ | 2654 | W: http://linux-fbdev.sourceforge.net/ |
2655 | Q: http://patchwork.kernel.org/project/linux-fbdev/list/ | 2655 | Q: http://patchwork.kernel.org/project/linux-fbdev/list/ |
2656 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git | 2656 | T: git git://github.com/schandinat/linux-2.6.git fbdev-next |
2657 | S: Maintained | 2657 | S: Maintained |
2658 | F: Documentation/fb/ | 2658 | F: Documentation/fb/ |
2659 | F: Documentation/devicetree/bindings/fb/ | 2659 | F: Documentation/devicetree/bindings/fb/ |
@@ -4450,8 +4450,8 @@ M: "David S. Miller" <davem@davemloft.net> | |||
4450 | L: netdev@vger.kernel.org | 4450 | L: netdev@vger.kernel.org |
4451 | W: http://www.linuxfoundation.org/en/Net | 4451 | W: http://www.linuxfoundation.org/en/Net |
4452 | W: http://patchwork.ozlabs.org/project/netdev/list/ | 4452 | W: http://patchwork.ozlabs.org/project/netdev/list/ |
4453 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git | 4453 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git |
4454 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git | 4454 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git |
4455 | S: Maintained | 4455 | S: Maintained |
4456 | F: net/ | 4456 | F: net/ |
4457 | F: include/net/ | 4457 | F: include/net/ |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 73c320ea172c..5a3a78633177 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1271,6 +1271,18 @@ config ARM_ERRATA_754327 | |||
1271 | This workaround defines cpu_relax() as smp_mb(), preventing correctly | 1271 | This workaround defines cpu_relax() as smp_mb(), preventing correctly |
1272 | written polling loops from denying visibility of updates to memory. | 1272 | written polling loops from denying visibility of updates to memory. |
1273 | 1273 | ||
1274 | config ARM_ERRATA_364296 | ||
1275 | bool "ARM errata: Possible cache data corruption with hit-under-miss enabled" | ||
1276 | depends on CPU_V6 && !SMP | ||
1277 | help | ||
1278 | This options enables the workaround for the 364296 ARM1136 | ||
1279 | r0p2 erratum (possible cache data corruption with | ||
1280 | hit-under-miss enabled). It sets the undocumented bit 31 in | ||
1281 | the auxiliary control register and the FI bit in the control | ||
1282 | register, thus disabling hit-under-miss without putting the | ||
1283 | processor into full low interrupt latency mode. ARM11MPCore | ||
1284 | is not affected. | ||
1285 | |||
1274 | endmenu | 1286 | endmenu |
1275 | 1287 | ||
1276 | source "arch/arm/common/Kconfig" | 1288 | source "arch/arm/common/Kconfig" |
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c index b6f61d9a5a1b..672ae95db5c3 100644 --- a/arch/arm/boot/compressed/mmcif-sh7372.c +++ b/arch/arm/boot/compressed/mmcif-sh7372.c | |||
@@ -82,7 +82,7 @@ asmlinkage void mmc_loader(unsigned char *buf, unsigned long len) | |||
82 | 82 | ||
83 | 83 | ||
84 | /* Disable clock to MMC hardware block */ | 84 | /* Disable clock to MMC hardware block */ |
85 | __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3); | 85 | __raw_writel(__raw_readl(SMSTPCR3) | (1 << 12), SMSTPCR3); |
86 | 86 | ||
87 | mmc_update_progress(MMC_PROGRESS_DONE); | 87 | mmc_update_progress(MMC_PROGRESS_DONE); |
88 | } | 88 | } |
diff --git a/arch/arm/boot/compressed/sdhi-sh7372.c b/arch/arm/boot/compressed/sdhi-sh7372.c index d403a8b24d7f..d279294f2381 100644 --- a/arch/arm/boot/compressed/sdhi-sh7372.c +++ b/arch/arm/boot/compressed/sdhi-sh7372.c | |||
@@ -85,7 +85,7 @@ asmlinkage void mmc_loader(unsigned short *buf, unsigned long len) | |||
85 | goto err; | 85 | goto err; |
86 | 86 | ||
87 | /* Disable clock to SDHI1 hardware block */ | 87 | /* Disable clock to SDHI1 hardware block */ |
88 | __raw_writel(__raw_readl(SMSTPCR3) & (1 << 13), SMSTPCR3); | 88 | __raw_writel(__raw_readl(SMSTPCR3) | (1 << 13), SMSTPCR3); |
89 | 89 | ||
90 | mmc_update_progress(MMC_PROGRESS_DONE); | 90 | mmc_update_progress(MMC_PROGRESS_DONE); |
91 | 91 | ||
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 16bd48031583..bfa706ffd968 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h | |||
@@ -64,7 +64,7 @@ | |||
64 | #define L2X0_AUX_CTRL_MASK 0xc0000fff | 64 | #define L2X0_AUX_CTRL_MASK 0xc0000fff |
65 | #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 | 65 | #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 |
66 | #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 | 66 | #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 |
67 | #define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) | 67 | #define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17) |
68 | #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 | 68 | #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 |
69 | #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 | 69 | #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 |
70 | #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 | 70 | #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 |
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index f389b2704d82..c190bc992f0e 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -50,6 +50,7 @@ static inline void decode_ctrl_reg(u32 reg, | |||
50 | #define ARM_DEBUG_ARCH_V6_1 2 | 50 | #define ARM_DEBUG_ARCH_V6_1 2 |
51 | #define ARM_DEBUG_ARCH_V7_ECP14 3 | 51 | #define ARM_DEBUG_ARCH_V7_ECP14 3 |
52 | #define ARM_DEBUG_ARCH_V7_MM 4 | 52 | #define ARM_DEBUG_ARCH_V7_MM 4 |
53 | #define ARM_DEBUG_ARCH_V7_1 5 | ||
53 | 54 | ||
54 | /* Breakpoint */ | 55 | /* Breakpoint */ |
55 | #define ARM_BREAKPOINT_EXECUTE 0 | 56 | #define ARM_BREAKPOINT_EXECUTE 0 |
@@ -57,6 +58,7 @@ static inline void decode_ctrl_reg(u32 reg, | |||
57 | /* Watchpoints */ | 58 | /* Watchpoints */ |
58 | #define ARM_BREAKPOINT_LOAD 1 | 59 | #define ARM_BREAKPOINT_LOAD 1 |
59 | #define ARM_BREAKPOINT_STORE 2 | 60 | #define ARM_BREAKPOINT_STORE 2 |
61 | #define ARM_FSR_ACCESS_MASK (1 << 11) | ||
60 | 62 | ||
61 | /* Privilege Levels */ | 63 | /* Privilege Levels */ |
62 | #define ARM_BREAKPOINT_PRIV 1 | 64 | #define ARM_BREAKPOINT_PRIV 1 |
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 67c70a31a1be..71d99b83cdb9 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h | |||
@@ -13,7 +13,12 @@ | |||
13 | #define __ARM_PMU_H__ | 13 | #define __ARM_PMU_H__ |
14 | 14 | ||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/perf_event.h> | ||
16 | 17 | ||
18 | /* | ||
19 | * Types of PMUs that can be accessed directly and require mutual | ||
20 | * exclusion between profiling tools. | ||
21 | */ | ||
17 | enum arm_pmu_type { | 22 | enum arm_pmu_type { |
18 | ARM_PMU_DEVICE_CPU = 0, | 23 | ARM_PMU_DEVICE_CPU = 0, |
19 | ARM_NUM_PMU_DEVICES, | 24 | ARM_NUM_PMU_DEVICES, |
@@ -37,21 +42,17 @@ struct arm_pmu_platdata { | |||
37 | * reserve_pmu() - reserve the hardware performance counters | 42 | * reserve_pmu() - reserve the hardware performance counters |
38 | * | 43 | * |
39 | * Reserve the hardware performance counters in the system for exclusive use. | 44 | * Reserve the hardware performance counters in the system for exclusive use. |
40 | * The platform_device for the system is returned on success, ERR_PTR() | 45 | * Returns 0 on success or -EBUSY if the lock is already held. |
41 | * encoded error on failure. | ||
42 | */ | 46 | */ |
43 | extern struct platform_device * | 47 | extern int |
44 | reserve_pmu(enum arm_pmu_type device); | 48 | reserve_pmu(enum arm_pmu_type type); |
45 | 49 | ||
46 | /** | 50 | /** |
47 | * release_pmu() - Relinquish control of the performance counters | 51 | * release_pmu() - Relinquish control of the performance counters |
48 | * | 52 | * |
49 | * Release the performance counters and allow someone else to use them. | 53 | * Release the performance counters and allow someone else to use them. |
50 | * Callers must have disabled the counters and released IRQs before calling | ||
51 | * this. The platform_device returned from reserve_pmu() must be passed as | ||
52 | * a cookie. | ||
53 | */ | 54 | */ |
54 | extern int | 55 | extern void |
55 | release_pmu(enum arm_pmu_type type); | 56 | release_pmu(enum arm_pmu_type type); |
56 | 57 | ||
57 | /** | 58 | /** |
@@ -62,30 +63,84 @@ release_pmu(enum arm_pmu_type type); | |||
62 | * the actual hardware initialisation. | 63 | * the actual hardware initialisation. |
63 | */ | 64 | */ |
64 | extern int | 65 | extern int |
65 | init_pmu(enum arm_pmu_type device); | 66 | init_pmu(enum arm_pmu_type type); |
66 | 67 | ||
67 | #else /* CONFIG_CPU_HAS_PMU */ | 68 | #else /* CONFIG_CPU_HAS_PMU */ |
68 | 69 | ||
69 | #include <linux/err.h> | 70 | #include <linux/err.h> |
70 | 71 | ||
71 | static inline struct platform_device * | ||
72 | reserve_pmu(enum arm_pmu_type device) | ||
73 | { | ||
74 | return ERR_PTR(-ENODEV); | ||
75 | } | ||
76 | |||
77 | static inline int | 72 | static inline int |
78 | release_pmu(struct platform_device *pdev) | 73 | reserve_pmu(enum arm_pmu_type type) |
79 | { | 74 | { |
80 | return -ENODEV; | 75 | return -ENODEV; |
81 | } | 76 | } |
82 | 77 | ||
83 | static inline int | 78 | static inline void |
84 | init_pmu(enum arm_pmu_type device) | 79 | release_pmu(enum arm_pmu_type type) { } |
85 | { | ||
86 | return -ENODEV; | ||
87 | } | ||
88 | 80 | ||
89 | #endif /* CONFIG_CPU_HAS_PMU */ | 81 | #endif /* CONFIG_CPU_HAS_PMU */ |
90 | 82 | ||
83 | #ifdef CONFIG_HW_PERF_EVENTS | ||
84 | |||
85 | /* The events for a given PMU register set. */ | ||
86 | struct pmu_hw_events { | ||
87 | /* | ||
88 | * The events that are active on the PMU for the given index. | ||
89 | */ | ||
90 | struct perf_event **events; | ||
91 | |||
92 | /* | ||
93 | * A 1 bit for an index indicates that the counter is being used for | ||
94 | * an event. A 0 means that the counter can be used. | ||
95 | */ | ||
96 | unsigned long *used_mask; | ||
97 | |||
98 | /* | ||
99 | * Hardware lock to serialize accesses to PMU registers. Needed for the | ||
100 | * read/modify/write sequences. | ||
101 | */ | ||
102 | raw_spinlock_t pmu_lock; | ||
103 | }; | ||
104 | |||
105 | struct arm_pmu { | ||
106 | struct pmu pmu; | ||
107 | enum arm_perf_pmu_ids id; | ||
108 | enum arm_pmu_type type; | ||
109 | cpumask_t active_irqs; | ||
110 | const char *name; | ||
111 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | ||
112 | void (*enable)(struct hw_perf_event *evt, int idx); | ||
113 | void (*disable)(struct hw_perf_event *evt, int idx); | ||
114 | int (*get_event_idx)(struct pmu_hw_events *hw_events, | ||
115 | struct hw_perf_event *hwc); | ||
116 | int (*set_event_filter)(struct hw_perf_event *evt, | ||
117 | struct perf_event_attr *attr); | ||
118 | u32 (*read_counter)(int idx); | ||
119 | void (*write_counter)(int idx, u32 val); | ||
120 | void (*start)(void); | ||
121 | void (*stop)(void); | ||
122 | void (*reset)(void *); | ||
123 | int (*map_event)(struct perf_event *event); | ||
124 | int num_events; | ||
125 | atomic_t active_events; | ||
126 | struct mutex reserve_mutex; | ||
127 | u64 max_period; | ||
128 | struct platform_device *plat_device; | ||
129 | struct pmu_hw_events *(*get_hw_events)(void); | ||
130 | }; | ||
131 | |||
132 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) | ||
133 | |||
134 | int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type); | ||
135 | |||
136 | u64 armpmu_event_update(struct perf_event *event, | ||
137 | struct hw_perf_event *hwc, | ||
138 | int idx, int overflow); | ||
139 | |||
140 | int armpmu_event_set_period(struct perf_event *event, | ||
141 | struct hw_perf_event *hwc, | ||
142 | int idx); | ||
143 | |||
144 | #endif /* CONFIG_HW_PERF_EVENTS */ | ||
145 | |||
91 | #endif /* __ARM_PMU_H__ */ | 146 | #endif /* __ARM_PMU_H__ */ |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index a927ca1f5566..5a46225f007e 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -45,7 +45,6 @@ static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]); | |||
45 | 45 | ||
46 | /* Number of BRP/WRP registers on this CPU. */ | 46 | /* Number of BRP/WRP registers on this CPU. */ |
47 | static int core_num_brps; | 47 | static int core_num_brps; |
48 | static int core_num_reserved_brps; | ||
49 | static int core_num_wrps; | 48 | static int core_num_wrps; |
50 | 49 | ||
51 | /* Debug architecture version. */ | 50 | /* Debug architecture version. */ |
@@ -137,10 +136,11 @@ static u8 get_debug_arch(void) | |||
137 | u32 didr; | 136 | u32 didr; |
138 | 137 | ||
139 | /* Do we implement the extended CPUID interface? */ | 138 | /* Do we implement the extended CPUID interface? */ |
140 | if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf), | 139 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { |
141 | "CPUID feature registers not supported. " | 140 | pr_warning("CPUID feature registers not supported. " |
142 | "Assuming v6 debug is present.\n")) | 141 | "Assuming v6 debug is present.\n"); |
143 | return ARM_DEBUG_ARCH_V6; | 142 | return ARM_DEBUG_ARCH_V6; |
143 | } | ||
144 | 144 | ||
145 | ARM_DBG_READ(c0, 0, didr); | 145 | ARM_DBG_READ(c0, 0, didr); |
146 | return (didr >> 16) & 0xf; | 146 | return (didr >> 16) & 0xf; |
@@ -154,10 +154,21 @@ u8 arch_get_debug_arch(void) | |||
154 | static int debug_arch_supported(void) | 154 | static int debug_arch_supported(void) |
155 | { | 155 | { |
156 | u8 arch = get_debug_arch(); | 156 | u8 arch = get_debug_arch(); |
157 | return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; | 157 | |
158 | /* We don't support the memory-mapped interface. */ | ||
159 | return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) || | ||
160 | arch >= ARM_DEBUG_ARCH_V7_1; | ||
161 | } | ||
162 | |||
163 | /* Determine number of WRP registers available. */ | ||
164 | static int get_num_wrp_resources(void) | ||
165 | { | ||
166 | u32 didr; | ||
167 | ARM_DBG_READ(c0, 0, didr); | ||
168 | return ((didr >> 28) & 0xf) + 1; | ||
158 | } | 169 | } |
159 | 170 | ||
160 | /* Determine number of BRP register available. */ | 171 | /* Determine number of BRP registers available. */ |
161 | static int get_num_brp_resources(void) | 172 | static int get_num_brp_resources(void) |
162 | { | 173 | { |
163 | u32 didr; | 174 | u32 didr; |
@@ -176,9 +187,10 @@ static int core_has_mismatch_brps(void) | |||
176 | static int get_num_wrps(void) | 187 | static int get_num_wrps(void) |
177 | { | 188 | { |
178 | /* | 189 | /* |
179 | * FIXME: When a watchpoint fires, the only way to work out which | 190 | * On debug architectures prior to 7.1, when a watchpoint fires, the |
180 | * watchpoint it was is by disassembling the faulting instruction | 191 | * only way to work out which watchpoint it was is by disassembling |
181 | * and working out the address of the memory access. | 192 | * the faulting instruction and working out the address of the memory |
193 | * access. | ||
182 | * | 194 | * |
183 | * Furthermore, we can only do this if the watchpoint was precise | 195 | * Furthermore, we can only do this if the watchpoint was precise |
184 | * since imprecise watchpoints prevent us from calculating register | 196 | * since imprecise watchpoints prevent us from calculating register |
@@ -192,36 +204,17 @@ static int get_num_wrps(void) | |||
192 | * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows | 204 | * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows |
193 | * that it is set on some implementations]. | 205 | * that it is set on some implementations]. |
194 | */ | 206 | */ |
207 | if (get_debug_arch() < ARM_DEBUG_ARCH_V7_1) | ||
208 | return 1; | ||
195 | 209 | ||
196 | #if 0 | 210 | return get_num_wrp_resources(); |
197 | int wrps; | ||
198 | u32 didr; | ||
199 | ARM_DBG_READ(c0, 0, didr); | ||
200 | wrps = ((didr >> 28) & 0xf) + 1; | ||
201 | #endif | ||
202 | int wrps = 1; | ||
203 | |||
204 | if (core_has_mismatch_brps() && wrps >= get_num_brp_resources()) | ||
205 | wrps = get_num_brp_resources() - 1; | ||
206 | |||
207 | return wrps; | ||
208 | } | ||
209 | |||
210 | /* We reserve one breakpoint for each watchpoint. */ | ||
211 | static int get_num_reserved_brps(void) | ||
212 | { | ||
213 | if (core_has_mismatch_brps()) | ||
214 | return get_num_wrps(); | ||
215 | return 0; | ||
216 | } | 211 | } |
217 | 212 | ||
218 | /* Determine number of usable BRPs available. */ | 213 | /* Determine number of usable BRPs available. */ |
219 | static int get_num_brps(void) | 214 | static int get_num_brps(void) |
220 | { | 215 | { |
221 | int brps = get_num_brp_resources(); | 216 | int brps = get_num_brp_resources(); |
222 | if (core_has_mismatch_brps()) | 217 | return core_has_mismatch_brps() ? brps - 1 : brps; |
223 | brps -= get_num_reserved_brps(); | ||
224 | return brps; | ||
225 | } | 218 | } |
226 | 219 | ||
227 | /* | 220 | /* |
@@ -239,7 +232,7 @@ static int enable_monitor_mode(void) | |||
239 | 232 | ||
240 | /* Ensure that halting mode is disabled. */ | 233 | /* Ensure that halting mode is disabled. */ |
241 | if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, | 234 | if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, |
242 | "halting debug mode enabled. Unable to access hardware resources.\n")) { | 235 | "halting debug mode enabled. Unable to access hardware resources.\n")) { |
243 | ret = -EPERM; | 236 | ret = -EPERM; |
244 | goto out; | 237 | goto out; |
245 | } | 238 | } |
@@ -255,6 +248,7 @@ static int enable_monitor_mode(void) | |||
255 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | 248 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); |
256 | break; | 249 | break; |
257 | case ARM_DEBUG_ARCH_V7_ECP14: | 250 | case ARM_DEBUG_ARCH_V7_ECP14: |
251 | case ARM_DEBUG_ARCH_V7_1: | ||
258 | ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); | 252 | ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); |
259 | break; | 253 | break; |
260 | default: | 254 | default: |
@@ -346,24 +340,10 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
346 | val_base = ARM_BASE_BVR; | 340 | val_base = ARM_BASE_BVR; |
347 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); | 341 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); |
348 | max_slots = core_num_brps; | 342 | max_slots = core_num_brps; |
349 | if (info->step_ctrl.enabled) { | ||
350 | /* Override the breakpoint data with the step data. */ | ||
351 | addr = info->trigger & ~0x3; | ||
352 | ctrl = encode_ctrl_reg(info->step_ctrl); | ||
353 | } | ||
354 | } else { | 343 | } else { |
355 | /* Watchpoint */ | 344 | /* Watchpoint */ |
356 | if (info->step_ctrl.enabled) { | 345 | ctrl_base = ARM_BASE_WCR; |
357 | /* Install into the reserved breakpoint region. */ | 346 | val_base = ARM_BASE_WVR; |
358 | ctrl_base = ARM_BASE_BCR + core_num_brps; | ||
359 | val_base = ARM_BASE_BVR + core_num_brps; | ||
360 | /* Override the watchpoint data with the step data. */ | ||
361 | addr = info->trigger & ~0x3; | ||
362 | ctrl = encode_ctrl_reg(info->step_ctrl); | ||
363 | } else { | ||
364 | ctrl_base = ARM_BASE_WCR; | ||
365 | val_base = ARM_BASE_WVR; | ||
366 | } | ||
367 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | 347 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); |
368 | max_slots = core_num_wrps; | 348 | max_slots = core_num_wrps; |
369 | } | 349 | } |
@@ -382,6 +362,17 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
382 | goto out; | 362 | goto out; |
383 | } | 363 | } |
384 | 364 | ||
365 | /* Override the breakpoint data with the step data. */ | ||
366 | if (info->step_ctrl.enabled) { | ||
367 | addr = info->trigger & ~0x3; | ||
368 | ctrl = encode_ctrl_reg(info->step_ctrl); | ||
369 | if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE) { | ||
370 | i = 0; | ||
371 | ctrl_base = ARM_BASE_BCR + core_num_brps; | ||
372 | val_base = ARM_BASE_BVR + core_num_brps; | ||
373 | } | ||
374 | } | ||
375 | |||
385 | /* Setup the address register. */ | 376 | /* Setup the address register. */ |
386 | write_wb_reg(val_base + i, addr); | 377 | write_wb_reg(val_base + i, addr); |
387 | 378 | ||
@@ -405,10 +396,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
405 | max_slots = core_num_brps; | 396 | max_slots = core_num_brps; |
406 | } else { | 397 | } else { |
407 | /* Watchpoint */ | 398 | /* Watchpoint */ |
408 | if (info->step_ctrl.enabled) | 399 | base = ARM_BASE_WCR; |
409 | base = ARM_BASE_BCR + core_num_brps; | ||
410 | else | ||
411 | base = ARM_BASE_WCR; | ||
412 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | 400 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); |
413 | max_slots = core_num_wrps; | 401 | max_slots = core_num_wrps; |
414 | } | 402 | } |
@@ -426,6 +414,13 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
426 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) | 414 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) |
427 | return; | 415 | return; |
428 | 416 | ||
417 | /* Ensure that we disable the mismatch breakpoint. */ | ||
418 | if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && | ||
419 | info->step_ctrl.enabled) { | ||
420 | i = 0; | ||
421 | base = ARM_BASE_BCR + core_num_brps; | ||
422 | } | ||
423 | |||
429 | /* Reset the control register. */ | 424 | /* Reset the control register. */ |
430 | write_wb_reg(base + i, 0); | 425 | write_wb_reg(base + i, 0); |
431 | } | 426 | } |
@@ -632,10 +627,9 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
632 | * we can use the mismatch feature as a poor-man's hardware | 627 | * we can use the mismatch feature as a poor-man's hardware |
633 | * single-step, but this only works for per-task breakpoints. | 628 | * single-step, but this only works for per-task breakpoints. |
634 | */ | 629 | */ |
635 | if (WARN_ONCE(!bp->overflow_handler && | 630 | if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || |
636 | (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() | 631 | !core_has_mismatch_brps() || !bp->hw.bp_target)) { |
637 | || !bp->hw.bp_target), | 632 | pr_warning("overflow handler required but none found\n"); |
638 | "overflow handler required but none found\n")) { | ||
639 | ret = -EINVAL; | 633 | ret = -EINVAL; |
640 | } | 634 | } |
641 | out: | 635 | out: |
@@ -666,34 +660,62 @@ static void disable_single_step(struct perf_event *bp) | |||
666 | arch_install_hw_breakpoint(bp); | 660 | arch_install_hw_breakpoint(bp); |
667 | } | 661 | } |
668 | 662 | ||
669 | static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | 663 | static void watchpoint_handler(unsigned long addr, unsigned int fsr, |
664 | struct pt_regs *regs) | ||
670 | { | 665 | { |
671 | int i; | 666 | int i, access; |
667 | u32 val, ctrl_reg, alignment_mask; | ||
672 | struct perf_event *wp, **slots; | 668 | struct perf_event *wp, **slots; |
673 | struct arch_hw_breakpoint *info; | 669 | struct arch_hw_breakpoint *info; |
670 | struct arch_hw_breakpoint_ctrl ctrl; | ||
674 | 671 | ||
675 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | 672 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); |
676 | 673 | ||
677 | /* Without a disassembler, we can only handle 1 watchpoint. */ | ||
678 | BUG_ON(core_num_wrps > 1); | ||
679 | |||
680 | for (i = 0; i < core_num_wrps; ++i) { | 674 | for (i = 0; i < core_num_wrps; ++i) { |
681 | rcu_read_lock(); | 675 | rcu_read_lock(); |
682 | 676 | ||
683 | wp = slots[i]; | 677 | wp = slots[i]; |
684 | 678 | ||
685 | if (wp == NULL) { | 679 | if (wp == NULL) |
686 | rcu_read_unlock(); | 680 | goto unlock; |
687 | continue; | ||
688 | } | ||
689 | 681 | ||
682 | info = counter_arch_bp(wp); | ||
690 | /* | 683 | /* |
691 | * The DFAR is an unknown value. Since we only allow a | 684 | * The DFAR is an unknown value on debug architectures prior |
692 | * single watchpoint, we can set the trigger to the lowest | 685 | * to 7.1. Since we only allow a single watchpoint on these |
693 | * possible faulting address. | 686 | * older CPUs, we can set the trigger to the lowest possible |
687 | * faulting address. | ||
694 | */ | 688 | */ |
695 | info = counter_arch_bp(wp); | 689 | if (debug_arch < ARM_DEBUG_ARCH_V7_1) { |
696 | info->trigger = wp->attr.bp_addr; | 690 | BUG_ON(i > 0); |
691 | info->trigger = wp->attr.bp_addr; | ||
692 | } else { | ||
693 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) | ||
694 | alignment_mask = 0x7; | ||
695 | else | ||
696 | alignment_mask = 0x3; | ||
697 | |||
698 | /* Check if the watchpoint value matches. */ | ||
699 | val = read_wb_reg(ARM_BASE_WVR + i); | ||
700 | if (val != (addr & ~alignment_mask)) | ||
701 | goto unlock; | ||
702 | |||
703 | /* Possible match, check the byte address select. */ | ||
704 | ctrl_reg = read_wb_reg(ARM_BASE_WCR + i); | ||
705 | decode_ctrl_reg(ctrl_reg, &ctrl); | ||
706 | if (!((1 << (addr & alignment_mask)) & ctrl.len)) | ||
707 | goto unlock; | ||
708 | |||
709 | /* Check that the access type matches. */ | ||
710 | access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : | ||
711 | HW_BREAKPOINT_R; | ||
712 | if (!(access & hw_breakpoint_type(wp))) | ||
713 | goto unlock; | ||
714 | |||
715 | /* We have a winner. */ | ||
716 | info->trigger = addr; | ||
717 | } | ||
718 | |||
697 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); | 719 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); |
698 | perf_bp_event(wp, regs); | 720 | perf_bp_event(wp, regs); |
699 | 721 | ||
@@ -705,6 +727,7 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | |||
705 | if (!wp->overflow_handler) | 727 | if (!wp->overflow_handler) |
706 | enable_single_step(wp, instruction_pointer(regs)); | 728 | enable_single_step(wp, instruction_pointer(regs)); |
707 | 729 | ||
730 | unlock: | ||
708 | rcu_read_unlock(); | 731 | rcu_read_unlock(); |
709 | } | 732 | } |
710 | } | 733 | } |
@@ -717,7 +740,7 @@ static void watchpoint_single_step_handler(unsigned long pc) | |||
717 | 740 | ||
718 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | 741 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); |
719 | 742 | ||
720 | for (i = 0; i < core_num_reserved_brps; ++i) { | 743 | for (i = 0; i < core_num_wrps; ++i) { |
721 | rcu_read_lock(); | 744 | rcu_read_lock(); |
722 | 745 | ||
723 | wp = slots[i]; | 746 | wp = slots[i]; |
@@ -820,7 +843,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
820 | case ARM_ENTRY_ASYNC_WATCHPOINT: | 843 | case ARM_ENTRY_ASYNC_WATCHPOINT: |
821 | WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n"); | 844 | WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n"); |
822 | case ARM_ENTRY_SYNC_WATCHPOINT: | 845 | case ARM_ENTRY_SYNC_WATCHPOINT: |
823 | watchpoint_handler(addr, regs); | 846 | watchpoint_handler(addr, fsr, regs); |
824 | break; | 847 | break; |
825 | default: | 848 | default: |
826 | ret = 1; /* Unhandled fault. */ | 849 | ret = 1; /* Unhandled fault. */ |
@@ -834,11 +857,31 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
834 | /* | 857 | /* |
835 | * One-time initialisation. | 858 | * One-time initialisation. |
836 | */ | 859 | */ |
837 | static void reset_ctrl_regs(void *info) | 860 | static cpumask_t debug_err_mask; |
861 | |||
862 | static int debug_reg_trap(struct pt_regs *regs, unsigned int instr) | ||
838 | { | 863 | { |
839 | int i, cpu = smp_processor_id(); | 864 | int cpu = smp_processor_id(); |
865 | |||
866 | pr_warning("Debug register access (0x%x) caused undefined instruction on CPU %d\n", | ||
867 | instr, cpu); | ||
868 | |||
869 | /* Set the error flag for this CPU and skip the faulting instruction. */ | ||
870 | cpumask_set_cpu(cpu, &debug_err_mask); | ||
871 | instruction_pointer(regs) += 4; | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static struct undef_hook debug_reg_hook = { | ||
876 | .instr_mask = 0x0fe80f10, | ||
877 | .instr_val = 0x0e000e10, | ||
878 | .fn = debug_reg_trap, | ||
879 | }; | ||
880 | |||
881 | static void reset_ctrl_regs(void *unused) | ||
882 | { | ||
883 | int i, raw_num_brps, err = 0, cpu = smp_processor_id(); | ||
840 | u32 dbg_power; | 884 | u32 dbg_power; |
841 | cpumask_t *cpumask = info; | ||
842 | 885 | ||
843 | /* | 886 | /* |
844 | * v7 debug contains save and restore registers so that debug state | 887 | * v7 debug contains save and restore registers so that debug state |
@@ -848,38 +891,52 @@ static void reset_ctrl_regs(void *info) | |||
848 | * Access Register to avoid taking undefined instruction exceptions | 891 | * Access Register to avoid taking undefined instruction exceptions |
849 | * later on. | 892 | * later on. |
850 | */ | 893 | */ |
851 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | 894 | switch (debug_arch) { |
895 | case ARM_DEBUG_ARCH_V7_ECP14: | ||
852 | /* | 896 | /* |
853 | * Ensure sticky power-down is clear (i.e. debug logic is | 897 | * Ensure sticky power-down is clear (i.e. debug logic is |
854 | * powered up). | 898 | * powered up). |
855 | */ | 899 | */ |
856 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); | 900 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); |
857 | if ((dbg_power & 0x1) == 0) { | 901 | if ((dbg_power & 0x1) == 0) |
858 | pr_warning("CPU %d debug is powered down!\n", cpu); | 902 | err = -EPERM; |
859 | cpumask_or(cpumask, cpumask, cpumask_of(cpu)); | 903 | break; |
860 | return; | 904 | case ARM_DEBUG_ARCH_V7_1: |
861 | } | ||
862 | |||
863 | /* | 905 | /* |
864 | * Unconditionally clear the lock by writing a value | 906 | * Ensure the OS double lock is clear. |
865 | * other than 0xC5ACCE55 to the access register. | ||
866 | */ | 907 | */ |
867 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | 908 | asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power)); |
868 | isb(); | 909 | if ((dbg_power & 0x1) == 1) |
910 | err = -EPERM; | ||
911 | break; | ||
912 | } | ||
869 | 913 | ||
870 | /* | 914 | if (err) { |
871 | * Clear any configured vector-catch events before | 915 | pr_warning("CPU %d debug is powered down!\n", cpu); |
872 | * enabling monitor mode. | 916 | cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); |
873 | */ | 917 | return; |
874 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); | ||
875 | isb(); | ||
876 | } | 918 | } |
877 | 919 | ||
920 | /* | ||
921 | * Unconditionally clear the lock by writing a value | ||
922 | * other than 0xC5ACCE55 to the access register. | ||
923 | */ | ||
924 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | ||
925 | isb(); | ||
926 | |||
927 | /* | ||
928 | * Clear any configured vector-catch events before | ||
929 | * enabling monitor mode. | ||
930 | */ | ||
931 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); | ||
932 | isb(); | ||
933 | |||
878 | if (enable_monitor_mode()) | 934 | if (enable_monitor_mode()) |
879 | return; | 935 | return; |
880 | 936 | ||
881 | /* We must also reset any reserved registers. */ | 937 | /* We must also reset any reserved registers. */ |
882 | for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) { | 938 | raw_num_brps = get_num_brp_resources(); |
939 | for (i = 0; i < raw_num_brps; ++i) { | ||
883 | write_wb_reg(ARM_BASE_BCR + i, 0UL); | 940 | write_wb_reg(ARM_BASE_BCR + i, 0UL); |
884 | write_wb_reg(ARM_BASE_BVR + i, 0UL); | 941 | write_wb_reg(ARM_BASE_BVR + i, 0UL); |
885 | } | 942 | } |
@@ -895,6 +952,7 @@ static int __cpuinit dbg_reset_notify(struct notifier_block *self, | |||
895 | { | 952 | { |
896 | if (action == CPU_ONLINE) | 953 | if (action == CPU_ONLINE) |
897 | smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1); | 954 | smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1); |
955 | |||
898 | return NOTIFY_OK; | 956 | return NOTIFY_OK; |
899 | } | 957 | } |
900 | 958 | ||
@@ -905,7 +963,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { | |||
905 | static int __init arch_hw_breakpoint_init(void) | 963 | static int __init arch_hw_breakpoint_init(void) |
906 | { | 964 | { |
907 | u32 dscr; | 965 | u32 dscr; |
908 | cpumask_t cpumask = { CPU_BITS_NONE }; | ||
909 | 966 | ||
910 | debug_arch = get_debug_arch(); | 967 | debug_arch = get_debug_arch(); |
911 | 968 | ||
@@ -916,28 +973,31 @@ static int __init arch_hw_breakpoint_init(void) | |||
916 | 973 | ||
917 | /* Determine how many BRPs/WRPs are available. */ | 974 | /* Determine how many BRPs/WRPs are available. */ |
918 | core_num_brps = get_num_brps(); | 975 | core_num_brps = get_num_brps(); |
919 | core_num_reserved_brps = get_num_reserved_brps(); | ||
920 | core_num_wrps = get_num_wrps(); | 976 | core_num_wrps = get_num_wrps(); |
921 | 977 | ||
922 | pr_info("found %d breakpoint and %d watchpoint registers.\n", | 978 | /* |
923 | core_num_brps + core_num_reserved_brps, core_num_wrps); | 979 | * We need to tread carefully here because DBGSWENABLE may be |
924 | 980 | * driven low on this core and there isn't an architected way to | |
925 | if (core_num_reserved_brps) | 981 | * determine that. |
926 | pr_info("%d breakpoint(s) reserved for watchpoint " | 982 | */ |
927 | "single-step.\n", core_num_reserved_brps); | 983 | register_undef_hook(&debug_reg_hook); |
928 | 984 | ||
929 | /* | 985 | /* |
930 | * Reset the breakpoint resources. We assume that a halting | 986 | * Reset the breakpoint resources. We assume that a halting |
931 | * debugger will leave the world in a nice state for us. | 987 | * debugger will leave the world in a nice state for us. |
932 | */ | 988 | */ |
933 | on_each_cpu(reset_ctrl_regs, &cpumask, 1); | 989 | on_each_cpu(reset_ctrl_regs, NULL, 1); |
934 | if (!cpumask_empty(&cpumask)) { | 990 | unregister_undef_hook(&debug_reg_hook); |
991 | if (!cpumask_empty(&debug_err_mask)) { | ||
935 | core_num_brps = 0; | 992 | core_num_brps = 0; |
936 | core_num_reserved_brps = 0; | ||
937 | core_num_wrps = 0; | 993 | core_num_wrps = 0; |
938 | return 0; | 994 | return 0; |
939 | } | 995 | } |
940 | 996 | ||
997 | pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n", | ||
998 | core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " : | ||
999 | "", core_num_wrps); | ||
1000 | |||
941 | ARM_DBG_READ(c1, 0, dscr); | 1001 | ARM_DBG_READ(c1, 0, dscr); |
942 | if (dscr & ARM_DSCR_HDBGEN) { | 1002 | if (dscr & ARM_DSCR_HDBGEN) { |
943 | max_watchpoint_len = 4; | 1003 | max_watchpoint_len = 4; |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 53c9c2610cbc..e6e5d7c84f1a 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -12,6 +12,7 @@ | |||
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> | ||
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
@@ -26,16 +27,8 @@ | |||
26 | #include <asm/pmu.h> | 27 | #include <asm/pmu.h> |
27 | #include <asm/stacktrace.h> | 28 | #include <asm/stacktrace.h> |
28 | 29 | ||
29 | static struct platform_device *pmu_device; | ||
30 | |||
31 | /* | ||
32 | * Hardware lock to serialize accesses to PMU registers. Needed for the | ||
33 | * read/modify/write sequences. | ||
34 | */ | ||
35 | static DEFINE_RAW_SPINLOCK(pmu_lock); | ||
36 | |||
37 | /* | 30 | /* |
38 | * ARMv6 supports a maximum of 3 events, starting from index 1. If we add | 31 | * ARMv6 supports a maximum of 3 events, starting from index 0. If we add |
39 | * another platform that supports more, we need to increase this to be the | 32 | * another platform that supports more, we need to increase this to be the |
40 | * largest of all platforms. | 33 | * largest of all platforms. |
41 | * | 34 | * |
@@ -43,62 +36,24 @@ static DEFINE_RAW_SPINLOCK(pmu_lock); | |||
43 | * cycle counter CCNT + 31 events counters CNT0..30. | 36 | * cycle counter CCNT + 31 events counters CNT0..30. |
44 | * Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters. | 37 | * Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters. |
45 | */ | 38 | */ |
46 | #define ARMPMU_MAX_HWEVENTS 33 | 39 | #define ARMPMU_MAX_HWEVENTS 32 |
47 | 40 | ||
48 | /* The events for a given CPU. */ | 41 | static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); |
49 | struct cpu_hw_events { | 42 | static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); |
50 | /* | 43 | static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); |
51 | * The events that are active on the CPU for the given index. Index 0 | ||
52 | * is reserved. | ||
53 | */ | ||
54 | struct perf_event *events[ARMPMU_MAX_HWEVENTS]; | ||
55 | |||
56 | /* | ||
57 | * A 1 bit for an index indicates that the counter is being used for | ||
58 | * an event. A 0 means that the counter can be used. | ||
59 | */ | ||
60 | unsigned long used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; | ||
61 | 44 | ||
62 | /* | 45 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) |
63 | * A 1 bit for an index indicates that the counter is actively being | ||
64 | * used. | ||
65 | */ | ||
66 | unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; | ||
67 | }; | ||
68 | static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | ||
69 | |||
70 | struct arm_pmu { | ||
71 | enum arm_perf_pmu_ids id; | ||
72 | const char *name; | ||
73 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | ||
74 | void (*enable)(struct hw_perf_event *evt, int idx); | ||
75 | void (*disable)(struct hw_perf_event *evt, int idx); | ||
76 | int (*get_event_idx)(struct cpu_hw_events *cpuc, | ||
77 | struct hw_perf_event *hwc); | ||
78 | u32 (*read_counter)(int idx); | ||
79 | void (*write_counter)(int idx, u32 val); | ||
80 | void (*start)(void); | ||
81 | void (*stop)(void); | ||
82 | void (*reset)(void *); | ||
83 | const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX] | ||
84 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
85 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
86 | const unsigned (*event_map)[PERF_COUNT_HW_MAX]; | ||
87 | u32 raw_event_mask; | ||
88 | int num_events; | ||
89 | u64 max_period; | ||
90 | }; | ||
91 | 46 | ||
92 | /* Set at runtime when we know what CPU type we are. */ | 47 | /* Set at runtime when we know what CPU type we are. */ |
93 | static const struct arm_pmu *armpmu; | 48 | static struct arm_pmu *cpu_pmu; |
94 | 49 | ||
95 | enum arm_perf_pmu_ids | 50 | enum arm_perf_pmu_ids |
96 | armpmu_get_pmu_id(void) | 51 | armpmu_get_pmu_id(void) |
97 | { | 52 | { |
98 | int id = -ENODEV; | 53 | int id = -ENODEV; |
99 | 54 | ||
100 | if (armpmu != NULL) | 55 | if (cpu_pmu != NULL) |
101 | id = armpmu->id; | 56 | id = cpu_pmu->id; |
102 | 57 | ||
103 | return id; | 58 | return id; |
104 | } | 59 | } |
@@ -109,8 +64,8 @@ armpmu_get_max_events(void) | |||
109 | { | 64 | { |
110 | int max_events = 0; | 65 | int max_events = 0; |
111 | 66 | ||
112 | if (armpmu != NULL) | 67 | if (cpu_pmu != NULL) |
113 | max_events = armpmu->num_events; | 68 | max_events = cpu_pmu->num_events; |
114 | 69 | ||
115 | return max_events; | 70 | return max_events; |
116 | } | 71 | } |
@@ -130,7 +85,11 @@ EXPORT_SYMBOL_GPL(perf_num_counters); | |||
130 | #define CACHE_OP_UNSUPPORTED 0xFFFF | 85 | #define CACHE_OP_UNSUPPORTED 0xFFFF |
131 | 86 | ||
132 | static int | 87 | static int |
133 | armpmu_map_cache_event(u64 config) | 88 | armpmu_map_cache_event(const unsigned (*cache_map) |
89 | [PERF_COUNT_HW_CACHE_MAX] | ||
90 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
91 | [PERF_COUNT_HW_CACHE_RESULT_MAX], | ||
92 | u64 config) | ||
134 | { | 93 | { |
135 | unsigned int cache_type, cache_op, cache_result, ret; | 94 | unsigned int cache_type, cache_op, cache_result, ret; |
136 | 95 | ||
@@ -146,7 +105,7 @@ armpmu_map_cache_event(u64 config) | |||
146 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | 105 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) |
147 | return -EINVAL; | 106 | return -EINVAL; |
148 | 107 | ||
149 | ret = (int)(*armpmu->cache_map)[cache_type][cache_op][cache_result]; | 108 | ret = (int)(*cache_map)[cache_type][cache_op][cache_result]; |
150 | 109 | ||
151 | if (ret == CACHE_OP_UNSUPPORTED) | 110 | if (ret == CACHE_OP_UNSUPPORTED) |
152 | return -ENOENT; | 111 | return -ENOENT; |
@@ -155,23 +114,46 @@ armpmu_map_cache_event(u64 config) | |||
155 | } | 114 | } |
156 | 115 | ||
157 | static int | 116 | static int |
158 | armpmu_map_event(u64 config) | 117 | armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) |
159 | { | 118 | { |
160 | int mapping = (*armpmu->event_map)[config]; | 119 | int mapping = (*event_map)[config]; |
161 | return mapping == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : mapping; | 120 | return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; |
162 | } | 121 | } |
163 | 122 | ||
164 | static int | 123 | static int |
165 | armpmu_map_raw_event(u64 config) | 124 | armpmu_map_raw_event(u32 raw_event_mask, u64 config) |
166 | { | 125 | { |
167 | return (int)(config & armpmu->raw_event_mask); | 126 | return (int)(config & raw_event_mask); |
168 | } | 127 | } |
169 | 128 | ||
170 | static int | 129 | static int map_cpu_event(struct perf_event *event, |
130 | const unsigned (*event_map)[PERF_COUNT_HW_MAX], | ||
131 | const unsigned (*cache_map) | ||
132 | [PERF_COUNT_HW_CACHE_MAX] | ||
133 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
134 | [PERF_COUNT_HW_CACHE_RESULT_MAX], | ||
135 | u32 raw_event_mask) | ||
136 | { | ||
137 | u64 config = event->attr.config; | ||
138 | |||
139 | switch (event->attr.type) { | ||
140 | case PERF_TYPE_HARDWARE: | ||
141 | return armpmu_map_event(event_map, config); | ||
142 | case PERF_TYPE_HW_CACHE: | ||
143 | return armpmu_map_cache_event(cache_map, config); | ||
144 | case PERF_TYPE_RAW: | ||
145 | return armpmu_map_raw_event(raw_event_mask, config); | ||
146 | } | ||
147 | |||
148 | return -ENOENT; | ||
149 | } | ||
150 | |||
151 | int | ||
171 | armpmu_event_set_period(struct perf_event *event, | 152 | armpmu_event_set_period(struct perf_event *event, |
172 | struct hw_perf_event *hwc, | 153 | struct hw_perf_event *hwc, |
173 | int idx) | 154 | int idx) |
174 | { | 155 | { |
156 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
175 | s64 left = local64_read(&hwc->period_left); | 157 | s64 left = local64_read(&hwc->period_left); |
176 | s64 period = hwc->sample_period; | 158 | s64 period = hwc->sample_period; |
177 | int ret = 0; | 159 | int ret = 0; |
@@ -202,11 +184,12 @@ armpmu_event_set_period(struct perf_event *event, | |||
202 | return ret; | 184 | return ret; |
203 | } | 185 | } |
204 | 186 | ||
205 | static u64 | 187 | u64 |
206 | armpmu_event_update(struct perf_event *event, | 188 | armpmu_event_update(struct perf_event *event, |
207 | struct hw_perf_event *hwc, | 189 | struct hw_perf_event *hwc, |
208 | int idx, int overflow) | 190 | int idx, int overflow) |
209 | { | 191 | { |
192 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
210 | u64 delta, prev_raw_count, new_raw_count; | 193 | u64 delta, prev_raw_count, new_raw_count; |
211 | 194 | ||
212 | again: | 195 | again: |
@@ -246,11 +229,9 @@ armpmu_read(struct perf_event *event) | |||
246 | static void | 229 | static void |
247 | armpmu_stop(struct perf_event *event, int flags) | 230 | armpmu_stop(struct perf_event *event, int flags) |
248 | { | 231 | { |
232 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
249 | struct hw_perf_event *hwc = &event->hw; | 233 | struct hw_perf_event *hwc = &event->hw; |
250 | 234 | ||
251 | if (!armpmu) | ||
252 | return; | ||
253 | |||
254 | /* | 235 | /* |
255 | * ARM pmu always has to update the counter, so ignore | 236 | * ARM pmu always has to update the counter, so ignore |
256 | * PERF_EF_UPDATE, see comments in armpmu_start(). | 237 | * PERF_EF_UPDATE, see comments in armpmu_start(). |
@@ -266,11 +247,9 @@ armpmu_stop(struct perf_event *event, int flags) | |||
266 | static void | 247 | static void |
267 | armpmu_start(struct perf_event *event, int flags) | 248 | armpmu_start(struct perf_event *event, int flags) |
268 | { | 249 | { |
250 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
269 | struct hw_perf_event *hwc = &event->hw; | 251 | struct hw_perf_event *hwc = &event->hw; |
270 | 252 | ||
271 | if (!armpmu) | ||
272 | return; | ||
273 | |||
274 | /* | 253 | /* |
275 | * ARM pmu always has to reprogram the period, so ignore | 254 | * ARM pmu always has to reprogram the period, so ignore |
276 | * PERF_EF_RELOAD, see the comment below. | 255 | * PERF_EF_RELOAD, see the comment below. |
@@ -293,16 +272,16 @@ armpmu_start(struct perf_event *event, int flags) | |||
293 | static void | 272 | static void |
294 | armpmu_del(struct perf_event *event, int flags) | 273 | armpmu_del(struct perf_event *event, int flags) |
295 | { | 274 | { |
296 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 275 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); |
276 | struct pmu_hw_events *hw_events = armpmu->get_hw_events(); | ||
297 | struct hw_perf_event *hwc = &event->hw; | 277 | struct hw_perf_event *hwc = &event->hw; |
298 | int idx = hwc->idx; | 278 | int idx = hwc->idx; |
299 | 279 | ||
300 | WARN_ON(idx < 0); | 280 | WARN_ON(idx < 0); |
301 | 281 | ||
302 | clear_bit(idx, cpuc->active_mask); | ||
303 | armpmu_stop(event, PERF_EF_UPDATE); | 282 | armpmu_stop(event, PERF_EF_UPDATE); |
304 | cpuc->events[idx] = NULL; | 283 | hw_events->events[idx] = NULL; |
305 | clear_bit(idx, cpuc->used_mask); | 284 | clear_bit(idx, hw_events->used_mask); |
306 | 285 | ||
307 | perf_event_update_userpage(event); | 286 | perf_event_update_userpage(event); |
308 | } | 287 | } |
@@ -310,7 +289,8 @@ armpmu_del(struct perf_event *event, int flags) | |||
310 | static int | 289 | static int |
311 | armpmu_add(struct perf_event *event, int flags) | 290 | armpmu_add(struct perf_event *event, int flags) |
312 | { | 291 | { |
313 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 292 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); |
293 | struct pmu_hw_events *hw_events = armpmu->get_hw_events(); | ||
314 | struct hw_perf_event *hwc = &event->hw; | 294 | struct hw_perf_event *hwc = &event->hw; |
315 | int idx; | 295 | int idx; |
316 | int err = 0; | 296 | int err = 0; |
@@ -318,7 +298,7 @@ armpmu_add(struct perf_event *event, int flags) | |||
318 | perf_pmu_disable(event->pmu); | 298 | perf_pmu_disable(event->pmu); |
319 | 299 | ||
320 | /* If we don't have a space for the counter then finish early. */ | 300 | /* If we don't have a space for the counter then finish early. */ |
321 | idx = armpmu->get_event_idx(cpuc, hwc); | 301 | idx = armpmu->get_event_idx(hw_events, hwc); |
322 | if (idx < 0) { | 302 | if (idx < 0) { |
323 | err = idx; | 303 | err = idx; |
324 | goto out; | 304 | goto out; |
@@ -330,8 +310,7 @@ armpmu_add(struct perf_event *event, int flags) | |||
330 | */ | 310 | */ |
331 | event->hw.idx = idx; | 311 | event->hw.idx = idx; |
332 | armpmu->disable(hwc, idx); | 312 | armpmu->disable(hwc, idx); |
333 | cpuc->events[idx] = event; | 313 | hw_events->events[idx] = event; |
334 | set_bit(idx, cpuc->active_mask); | ||
335 | 314 | ||
336 | hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; | 315 | hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; |
337 | if (flags & PERF_EF_START) | 316 | if (flags & PERF_EF_START) |
@@ -345,25 +324,25 @@ out: | |||
345 | return err; | 324 | return err; |
346 | } | 325 | } |
347 | 326 | ||
348 | static struct pmu pmu; | ||
349 | |||
350 | static int | 327 | static int |
351 | validate_event(struct cpu_hw_events *cpuc, | 328 | validate_event(struct pmu_hw_events *hw_events, |
352 | struct perf_event *event) | 329 | struct perf_event *event) |
353 | { | 330 | { |
331 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
354 | struct hw_perf_event fake_event = event->hw; | 332 | struct hw_perf_event fake_event = event->hw; |
333 | struct pmu *leader_pmu = event->group_leader->pmu; | ||
355 | 334 | ||
356 | if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) | 335 | if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) |
357 | return 1; | 336 | return 1; |
358 | 337 | ||
359 | return armpmu->get_event_idx(cpuc, &fake_event) >= 0; | 338 | return armpmu->get_event_idx(hw_events, &fake_event) >= 0; |
360 | } | 339 | } |
361 | 340 | ||
362 | static int | 341 | static int |
363 | validate_group(struct perf_event *event) | 342 | validate_group(struct perf_event *event) |
364 | { | 343 | { |
365 | struct perf_event *sibling, *leader = event->group_leader; | 344 | struct perf_event *sibling, *leader = event->group_leader; |
366 | struct cpu_hw_events fake_pmu; | 345 | struct pmu_hw_events fake_pmu; |
367 | 346 | ||
368 | memset(&fake_pmu, 0, sizeof(fake_pmu)); | 347 | memset(&fake_pmu, 0, sizeof(fake_pmu)); |
369 | 348 | ||
@@ -383,110 +362,119 @@ validate_group(struct perf_event *event) | |||
383 | 362 | ||
384 | static irqreturn_t armpmu_platform_irq(int irq, void *dev) | 363 | static irqreturn_t armpmu_platform_irq(int irq, void *dev) |
385 | { | 364 | { |
386 | struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev); | 365 | struct arm_pmu *armpmu = (struct arm_pmu *) dev; |
366 | struct platform_device *plat_device = armpmu->plat_device; | ||
367 | struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev); | ||
387 | 368 | ||
388 | return plat->handle_irq(irq, dev, armpmu->handle_irq); | 369 | return plat->handle_irq(irq, dev, armpmu->handle_irq); |
389 | } | 370 | } |
390 | 371 | ||
372 | static void | ||
373 | armpmu_release_hardware(struct arm_pmu *armpmu) | ||
374 | { | ||
375 | int i, irq, irqs; | ||
376 | struct platform_device *pmu_device = armpmu->plat_device; | ||
377 | |||
378 | irqs = min(pmu_device->num_resources, num_possible_cpus()); | ||
379 | |||
380 | for (i = 0; i < irqs; ++i) { | ||
381 | if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs)) | ||
382 | continue; | ||
383 | irq = platform_get_irq(pmu_device, i); | ||
384 | if (irq >= 0) | ||
385 | free_irq(irq, armpmu); | ||
386 | } | ||
387 | |||
388 | release_pmu(armpmu->type); | ||
389 | } | ||
390 | |||
391 | static int | 391 | static int |
392 | armpmu_reserve_hardware(void) | 392 | armpmu_reserve_hardware(struct arm_pmu *armpmu) |
393 | { | 393 | { |
394 | struct arm_pmu_platdata *plat; | 394 | struct arm_pmu_platdata *plat; |
395 | irq_handler_t handle_irq; | 395 | irq_handler_t handle_irq; |
396 | int i, err = -ENODEV, irq; | 396 | int i, err, irq, irqs; |
397 | struct platform_device *pmu_device = armpmu->plat_device; | ||
397 | 398 | ||
398 | pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); | 399 | err = reserve_pmu(armpmu->type); |
399 | if (IS_ERR(pmu_device)) { | 400 | if (err) { |
400 | pr_warning("unable to reserve pmu\n"); | 401 | pr_warning("unable to reserve pmu\n"); |
401 | return PTR_ERR(pmu_device); | 402 | return err; |
402 | } | 403 | } |
403 | 404 | ||
404 | init_pmu(ARM_PMU_DEVICE_CPU); | ||
405 | |||
406 | plat = dev_get_platdata(&pmu_device->dev); | 405 | plat = dev_get_platdata(&pmu_device->dev); |
407 | if (plat && plat->handle_irq) | 406 | if (plat && plat->handle_irq) |
408 | handle_irq = armpmu_platform_irq; | 407 | handle_irq = armpmu_platform_irq; |
409 | else | 408 | else |
410 | handle_irq = armpmu->handle_irq; | 409 | handle_irq = armpmu->handle_irq; |
411 | 410 | ||
412 | if (pmu_device->num_resources < 1) { | 411 | irqs = min(pmu_device->num_resources, num_possible_cpus()); |
412 | if (irqs < 1) { | ||
413 | pr_err("no irqs for PMUs defined\n"); | 413 | pr_err("no irqs for PMUs defined\n"); |
414 | return -ENODEV; | 414 | return -ENODEV; |
415 | } | 415 | } |
416 | 416 | ||
417 | for (i = 0; i < pmu_device->num_resources; ++i) { | 417 | for (i = 0; i < irqs; ++i) { |
418 | err = 0; | ||
418 | irq = platform_get_irq(pmu_device, i); | 419 | irq = platform_get_irq(pmu_device, i); |
419 | if (irq < 0) | 420 | if (irq < 0) |
420 | continue; | 421 | continue; |
421 | 422 | ||
423 | /* | ||
424 | * If we have a single PMU interrupt that we can't shift, | ||
425 | * assume that we're running on a uniprocessor machine and | ||
426 | * continue. Otherwise, continue without this interrupt. | ||
427 | */ | ||
428 | if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) { | ||
429 | pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n", | ||
430 | irq, i); | ||
431 | continue; | ||
432 | } | ||
433 | |||
422 | err = request_irq(irq, handle_irq, | 434 | err = request_irq(irq, handle_irq, |
423 | IRQF_DISABLED | IRQF_NOBALANCING, | 435 | IRQF_DISABLED | IRQF_NOBALANCING, |
424 | "armpmu", NULL); | 436 | "arm-pmu", armpmu); |
425 | if (err) { | 437 | if (err) { |
426 | pr_warning("unable to request IRQ%d for ARM perf " | 438 | pr_err("unable to request IRQ%d for ARM PMU counters\n", |
427 | "counters\n", irq); | 439 | irq); |
428 | break; | 440 | armpmu_release_hardware(armpmu); |
441 | return err; | ||
429 | } | 442 | } |
430 | } | ||
431 | 443 | ||
432 | if (err) { | 444 | cpumask_set_cpu(i, &armpmu->active_irqs); |
433 | for (i = i - 1; i >= 0; --i) { | ||
434 | irq = platform_get_irq(pmu_device, i); | ||
435 | if (irq >= 0) | ||
436 | free_irq(irq, NULL); | ||
437 | } | ||
438 | release_pmu(ARM_PMU_DEVICE_CPU); | ||
439 | pmu_device = NULL; | ||
440 | } | 445 | } |
441 | 446 | ||
442 | return err; | 447 | return 0; |
443 | } | 448 | } |
444 | 449 | ||
445 | static void | 450 | static void |
446 | armpmu_release_hardware(void) | 451 | hw_perf_event_destroy(struct perf_event *event) |
447 | { | 452 | { |
448 | int i, irq; | 453 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); |
454 | atomic_t *active_events = &armpmu->active_events; | ||
455 | struct mutex *pmu_reserve_mutex = &armpmu->reserve_mutex; | ||
449 | 456 | ||
450 | for (i = pmu_device->num_resources - 1; i >= 0; --i) { | 457 | if (atomic_dec_and_mutex_lock(active_events, pmu_reserve_mutex)) { |
451 | irq = platform_get_irq(pmu_device, i); | 458 | armpmu_release_hardware(armpmu); |
452 | if (irq >= 0) | 459 | mutex_unlock(pmu_reserve_mutex); |
453 | free_irq(irq, NULL); | ||
454 | } | 460 | } |
455 | armpmu->stop(); | ||
456 | |||
457 | release_pmu(ARM_PMU_DEVICE_CPU); | ||
458 | pmu_device = NULL; | ||
459 | } | 461 | } |
460 | 462 | ||
461 | static atomic_t active_events = ATOMIC_INIT(0); | 463 | static int |
462 | static DEFINE_MUTEX(pmu_reserve_mutex); | 464 | event_requires_mode_exclusion(struct perf_event_attr *attr) |
463 | |||
464 | static void | ||
465 | hw_perf_event_destroy(struct perf_event *event) | ||
466 | { | 465 | { |
467 | if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) { | 466 | return attr->exclude_idle || attr->exclude_user || |
468 | armpmu_release_hardware(); | 467 | attr->exclude_kernel || attr->exclude_hv; |
469 | mutex_unlock(&pmu_reserve_mutex); | ||
470 | } | ||
471 | } | 468 | } |
472 | 469 | ||
473 | static int | 470 | static int |
474 | __hw_perf_event_init(struct perf_event *event) | 471 | __hw_perf_event_init(struct perf_event *event) |
475 | { | 472 | { |
473 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
476 | struct hw_perf_event *hwc = &event->hw; | 474 | struct hw_perf_event *hwc = &event->hw; |
477 | int mapping, err; | 475 | int mapping, err; |
478 | 476 | ||
479 | /* Decode the generic type into an ARM event identifier. */ | 477 | mapping = armpmu->map_event(event); |
480 | if (PERF_TYPE_HARDWARE == event->attr.type) { | ||
481 | mapping = armpmu_map_event(event->attr.config); | ||
482 | } else if (PERF_TYPE_HW_CACHE == event->attr.type) { | ||
483 | mapping = armpmu_map_cache_event(event->attr.config); | ||
484 | } else if (PERF_TYPE_RAW == event->attr.type) { | ||
485 | mapping = armpmu_map_raw_event(event->attr.config); | ||
486 | } else { | ||
487 | pr_debug("event type %x not supported\n", event->attr.type); | ||
488 | return -EOPNOTSUPP; | ||
489 | } | ||
490 | 478 | ||
491 | if (mapping < 0) { | 479 | if (mapping < 0) { |
492 | pr_debug("event %x:%llx not supported\n", event->attr.type, | 480 | pr_debug("event %x:%llx not supported\n", event->attr.type, |
@@ -495,34 +483,31 @@ __hw_perf_event_init(struct perf_event *event) | |||
495 | } | 483 | } |
496 | 484 | ||
497 | /* | 485 | /* |
486 | * We don't assign an index until we actually place the event onto | ||
487 | * hardware. Use -1 to signify that we haven't decided where to put it | ||
488 | * yet. For SMP systems, each core has it's own PMU so we can't do any | ||
489 | * clever allocation or constraints checking at this point. | ||
490 | */ | ||
491 | hwc->idx = -1; | ||
492 | hwc->config_base = 0; | ||
493 | hwc->config = 0; | ||
494 | hwc->event_base = 0; | ||
495 | |||
496 | /* | ||
498 | * Check whether we need to exclude the counter from certain modes. | 497 | * Check whether we need to exclude the counter from certain modes. |
499 | * The ARM performance counters are on all of the time so if someone | ||
500 | * has asked us for some excludes then we have to fail. | ||
501 | */ | 498 | */ |
502 | if (event->attr.exclude_kernel || event->attr.exclude_user || | 499 | if ((!armpmu->set_event_filter || |
503 | event->attr.exclude_hv || event->attr.exclude_idle) { | 500 | armpmu->set_event_filter(hwc, &event->attr)) && |
501 | event_requires_mode_exclusion(&event->attr)) { | ||
504 | pr_debug("ARM performance counters do not support " | 502 | pr_debug("ARM performance counters do not support " |
505 | "mode exclusion\n"); | 503 | "mode exclusion\n"); |
506 | return -EPERM; | 504 | return -EPERM; |
507 | } | 505 | } |
508 | 506 | ||
509 | /* | 507 | /* |
510 | * We don't assign an index until we actually place the event onto | 508 | * Store the event encoding into the config_base field. |
511 | * hardware. Use -1 to signify that we haven't decided where to put it | ||
512 | * yet. For SMP systems, each core has it's own PMU so we can't do any | ||
513 | * clever allocation or constraints checking at this point. | ||
514 | */ | 509 | */ |
515 | hwc->idx = -1; | 510 | hwc->config_base |= (unsigned long)mapping; |
516 | |||
517 | /* | ||
518 | * Store the event encoding into the config_base field. config and | ||
519 | * event_base are unused as the only 2 things we need to know are | ||
520 | * the event mapping and the counter to use. The counter to use is | ||
521 | * also the indx and the config_base is the event type. | ||
522 | */ | ||
523 | hwc->config_base = (unsigned long)mapping; | ||
524 | hwc->config = 0; | ||
525 | hwc->event_base = 0; | ||
526 | 511 | ||
527 | if (!hwc->sample_period) { | 512 | if (!hwc->sample_period) { |
528 | hwc->sample_period = armpmu->max_period; | 513 | hwc->sample_period = armpmu->max_period; |
@@ -542,32 +527,23 @@ __hw_perf_event_init(struct perf_event *event) | |||
542 | 527 | ||
543 | static int armpmu_event_init(struct perf_event *event) | 528 | static int armpmu_event_init(struct perf_event *event) |
544 | { | 529 | { |
530 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
545 | int err = 0; | 531 | int err = 0; |
532 | atomic_t *active_events = &armpmu->active_events; | ||
546 | 533 | ||
547 | switch (event->attr.type) { | 534 | if (armpmu->map_event(event) == -ENOENT) |
548 | case PERF_TYPE_RAW: | ||
549 | case PERF_TYPE_HARDWARE: | ||
550 | case PERF_TYPE_HW_CACHE: | ||
551 | break; | ||
552 | |||
553 | default: | ||
554 | return -ENOENT; | 535 | return -ENOENT; |
555 | } | ||
556 | |||
557 | if (!armpmu) | ||
558 | return -ENODEV; | ||
559 | 536 | ||
560 | event->destroy = hw_perf_event_destroy; | 537 | event->destroy = hw_perf_event_destroy; |
561 | 538 | ||
562 | if (!atomic_inc_not_zero(&active_events)) { | 539 | if (!atomic_inc_not_zero(active_events)) { |
563 | mutex_lock(&pmu_reserve_mutex); | 540 | mutex_lock(&armpmu->reserve_mutex); |
564 | if (atomic_read(&active_events) == 0) { | 541 | if (atomic_read(active_events) == 0) |
565 | err = armpmu_reserve_hardware(); | 542 | err = armpmu_reserve_hardware(armpmu); |
566 | } | ||
567 | 543 | ||
568 | if (!err) | 544 | if (!err) |
569 | atomic_inc(&active_events); | 545 | atomic_inc(active_events); |
570 | mutex_unlock(&pmu_reserve_mutex); | 546 | mutex_unlock(&armpmu->reserve_mutex); |
571 | } | 547 | } |
572 | 548 | ||
573 | if (err) | 549 | if (err) |
@@ -582,22 +558,9 @@ static int armpmu_event_init(struct perf_event *event) | |||
582 | 558 | ||
583 | static void armpmu_enable(struct pmu *pmu) | 559 | static void armpmu_enable(struct pmu *pmu) |
584 | { | 560 | { |
585 | /* Enable all of the perf events on hardware. */ | 561 | struct arm_pmu *armpmu = to_arm_pmu(pmu); |
586 | int idx, enabled = 0; | 562 | struct pmu_hw_events *hw_events = armpmu->get_hw_events(); |
587 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 563 | int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events); |
588 | |||
589 | if (!armpmu) | ||
590 | return; | ||
591 | |||
592 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
593 | struct perf_event *event = cpuc->events[idx]; | ||
594 | |||
595 | if (!event) | ||
596 | continue; | ||
597 | |||
598 | armpmu->enable(&event->hw, idx); | ||
599 | enabled = 1; | ||
600 | } | ||
601 | 564 | ||
602 | if (enabled) | 565 | if (enabled) |
603 | armpmu->start(); | 566 | armpmu->start(); |
@@ -605,20 +568,32 @@ static void armpmu_enable(struct pmu *pmu) | |||
605 | 568 | ||
606 | static void armpmu_disable(struct pmu *pmu) | 569 | static void armpmu_disable(struct pmu *pmu) |
607 | { | 570 | { |
608 | if (armpmu) | 571 | struct arm_pmu *armpmu = to_arm_pmu(pmu); |
609 | armpmu->stop(); | 572 | armpmu->stop(); |
610 | } | 573 | } |
611 | 574 | ||
612 | static struct pmu pmu = { | 575 | static void __init armpmu_init(struct arm_pmu *armpmu) |
613 | .pmu_enable = armpmu_enable, | 576 | { |
614 | .pmu_disable = armpmu_disable, | 577 | atomic_set(&armpmu->active_events, 0); |
615 | .event_init = armpmu_event_init, | 578 | mutex_init(&armpmu->reserve_mutex); |
616 | .add = armpmu_add, | 579 | |
617 | .del = armpmu_del, | 580 | armpmu->pmu = (struct pmu) { |
618 | .start = armpmu_start, | 581 | .pmu_enable = armpmu_enable, |
619 | .stop = armpmu_stop, | 582 | .pmu_disable = armpmu_disable, |
620 | .read = armpmu_read, | 583 | .event_init = armpmu_event_init, |
621 | }; | 584 | .add = armpmu_add, |
585 | .del = armpmu_del, | ||
586 | .start = armpmu_start, | ||
587 | .stop = armpmu_stop, | ||
588 | .read = armpmu_read, | ||
589 | }; | ||
590 | } | ||
591 | |||
592 | int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) | ||
593 | { | ||
594 | armpmu_init(armpmu); | ||
595 | return perf_pmu_register(&armpmu->pmu, name, type); | ||
596 | } | ||
622 | 597 | ||
623 | /* Include the PMU-specific implementations. */ | 598 | /* Include the PMU-specific implementations. */ |
624 | #include "perf_event_xscale.c" | 599 | #include "perf_event_xscale.c" |
@@ -630,14 +605,72 @@ static struct pmu pmu = { | |||
630 | * This requires SMP to be available, so exists as a separate initcall. | 605 | * This requires SMP to be available, so exists as a separate initcall. |
631 | */ | 606 | */ |
632 | static int __init | 607 | static int __init |
633 | armpmu_reset(void) | 608 | cpu_pmu_reset(void) |
609 | { | ||
610 | if (cpu_pmu && cpu_pmu->reset) | ||
611 | return on_each_cpu(cpu_pmu->reset, NULL, 1); | ||
612 | return 0; | ||
613 | } | ||
614 | arch_initcall(cpu_pmu_reset); | ||
615 | |||
616 | /* | ||
617 | * PMU platform driver and devicetree bindings. | ||
618 | */ | ||
619 | static struct of_device_id armpmu_of_device_ids[] = { | ||
620 | {.compatible = "arm,cortex-a9-pmu"}, | ||
621 | {.compatible = "arm,cortex-a8-pmu"}, | ||
622 | {.compatible = "arm,arm1136-pmu"}, | ||
623 | {.compatible = "arm,arm1176-pmu"}, | ||
624 | {}, | ||
625 | }; | ||
626 | |||
627 | static struct platform_device_id armpmu_plat_device_ids[] = { | ||
628 | {.name = "arm-pmu"}, | ||
629 | {}, | ||
630 | }; | ||
631 | |||
632 | static int __devinit armpmu_device_probe(struct platform_device *pdev) | ||
634 | { | 633 | { |
635 | if (armpmu && armpmu->reset) | 634 | cpu_pmu->plat_device = pdev; |
636 | return on_each_cpu(armpmu->reset, NULL, 1); | ||
637 | return 0; | 635 | return 0; |
638 | } | 636 | } |
639 | arch_initcall(armpmu_reset); | ||
640 | 637 | ||
638 | static struct platform_driver armpmu_driver = { | ||
639 | .driver = { | ||
640 | .name = "arm-pmu", | ||
641 | .of_match_table = armpmu_of_device_ids, | ||
642 | }, | ||
643 | .probe = armpmu_device_probe, | ||
644 | .id_table = armpmu_plat_device_ids, | ||
645 | }; | ||
646 | |||
647 | static int __init register_pmu_driver(void) | ||
648 | { | ||
649 | return platform_driver_register(&armpmu_driver); | ||
650 | } | ||
651 | device_initcall(register_pmu_driver); | ||
652 | |||
653 | static struct pmu_hw_events *armpmu_get_cpu_events(void) | ||
654 | { | ||
655 | return &__get_cpu_var(cpu_hw_events); | ||
656 | } | ||
657 | |||
658 | static void __init cpu_pmu_init(struct arm_pmu *armpmu) | ||
659 | { | ||
660 | int cpu; | ||
661 | for_each_possible_cpu(cpu) { | ||
662 | struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu); | ||
663 | events->events = per_cpu(hw_events, cpu); | ||
664 | events->used_mask = per_cpu(used_mask, cpu); | ||
665 | raw_spin_lock_init(&events->pmu_lock); | ||
666 | } | ||
667 | armpmu->get_hw_events = armpmu_get_cpu_events; | ||
668 | armpmu->type = ARM_PMU_DEVICE_CPU; | ||
669 | } | ||
670 | |||
671 | /* | ||
672 | * CPU PMU identification and registration. | ||
673 | */ | ||
641 | static int __init | 674 | static int __init |
642 | init_hw_perf_events(void) | 675 | init_hw_perf_events(void) |
643 | { | 676 | { |
@@ -651,22 +684,22 @@ init_hw_perf_events(void) | |||
651 | case 0xB360: /* ARM1136 */ | 684 | case 0xB360: /* ARM1136 */ |
652 | case 0xB560: /* ARM1156 */ | 685 | case 0xB560: /* ARM1156 */ |
653 | case 0xB760: /* ARM1176 */ | 686 | case 0xB760: /* ARM1176 */ |
654 | armpmu = armv6pmu_init(); | 687 | cpu_pmu = armv6pmu_init(); |
655 | break; | 688 | break; |
656 | case 0xB020: /* ARM11mpcore */ | 689 | case 0xB020: /* ARM11mpcore */ |
657 | armpmu = armv6mpcore_pmu_init(); | 690 | cpu_pmu = armv6mpcore_pmu_init(); |
658 | break; | 691 | break; |
659 | case 0xC080: /* Cortex-A8 */ | 692 | case 0xC080: /* Cortex-A8 */ |
660 | armpmu = armv7_a8_pmu_init(); | 693 | cpu_pmu = armv7_a8_pmu_init(); |
661 | break; | 694 | break; |
662 | case 0xC090: /* Cortex-A9 */ | 695 | case 0xC090: /* Cortex-A9 */ |
663 | armpmu = armv7_a9_pmu_init(); | 696 | cpu_pmu = armv7_a9_pmu_init(); |
664 | break; | 697 | break; |
665 | case 0xC050: /* Cortex-A5 */ | 698 | case 0xC050: /* Cortex-A5 */ |
666 | armpmu = armv7_a5_pmu_init(); | 699 | cpu_pmu = armv7_a5_pmu_init(); |
667 | break; | 700 | break; |
668 | case 0xC0F0: /* Cortex-A15 */ | 701 | case 0xC0F0: /* Cortex-A15 */ |
669 | armpmu = armv7_a15_pmu_init(); | 702 | cpu_pmu = armv7_a15_pmu_init(); |
670 | break; | 703 | break; |
671 | } | 704 | } |
672 | /* Intel CPUs [xscale]. */ | 705 | /* Intel CPUs [xscale]. */ |
@@ -674,23 +707,23 @@ init_hw_perf_events(void) | |||
674 | part_number = (cpuid >> 13) & 0x7; | 707 | part_number = (cpuid >> 13) & 0x7; |
675 | switch (part_number) { | 708 | switch (part_number) { |
676 | case 1: | 709 | case 1: |
677 | armpmu = xscale1pmu_init(); | 710 | cpu_pmu = xscale1pmu_init(); |
678 | break; | 711 | break; |
679 | case 2: | 712 | case 2: |
680 | armpmu = xscale2pmu_init(); | 713 | cpu_pmu = xscale2pmu_init(); |
681 | break; | 714 | break; |
682 | } | 715 | } |
683 | } | 716 | } |
684 | 717 | ||
685 | if (armpmu) { | 718 | if (cpu_pmu) { |
686 | pr_info("enabled with %s PMU driver, %d counters available\n", | 719 | pr_info("enabled with %s PMU driver, %d counters available\n", |
687 | armpmu->name, armpmu->num_events); | 720 | cpu_pmu->name, cpu_pmu->num_events); |
721 | cpu_pmu_init(cpu_pmu); | ||
722 | armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW); | ||
688 | } else { | 723 | } else { |
689 | pr_info("no hardware support available\n"); | 724 | pr_info("no hardware support available\n"); |
690 | } | 725 | } |
691 | 726 | ||
692 | perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); | ||
693 | |||
694 | return 0; | 727 | return 0; |
695 | } | 728 | } |
696 | early_initcall(init_hw_perf_events); | 729 | early_initcall(init_hw_perf_events); |
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index dd7f3b9f4cb3..e63d8115c01b 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c | |||
@@ -54,7 +54,7 @@ enum armv6_perf_types { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | enum armv6_counters { | 56 | enum armv6_counters { |
57 | ARMV6_CYCLE_COUNTER = 1, | 57 | ARMV6_CYCLE_COUNTER = 0, |
58 | ARMV6_COUNTER0, | 58 | ARMV6_COUNTER0, |
59 | ARMV6_COUNTER1, | 59 | ARMV6_COUNTER1, |
60 | }; | 60 | }; |
@@ -433,6 +433,7 @@ armv6pmu_enable_event(struct hw_perf_event *hwc, | |||
433 | int idx) | 433 | int idx) |
434 | { | 434 | { |
435 | unsigned long val, mask, evt, flags; | 435 | unsigned long val, mask, evt, flags; |
436 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
436 | 437 | ||
437 | if (ARMV6_CYCLE_COUNTER == idx) { | 438 | if (ARMV6_CYCLE_COUNTER == idx) { |
438 | mask = 0; | 439 | mask = 0; |
@@ -454,12 +455,29 @@ armv6pmu_enable_event(struct hw_perf_event *hwc, | |||
454 | * Mask out the current event and set the counter to count the event | 455 | * Mask out the current event and set the counter to count the event |
455 | * that we're interested in. | 456 | * that we're interested in. |
456 | */ | 457 | */ |
457 | raw_spin_lock_irqsave(&pmu_lock, flags); | 458 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
458 | val = armv6_pmcr_read(); | 459 | val = armv6_pmcr_read(); |
459 | val &= ~mask; | 460 | val &= ~mask; |
460 | val |= evt; | 461 | val |= evt; |
461 | armv6_pmcr_write(val); | 462 | armv6_pmcr_write(val); |
462 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 463 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
464 | } | ||
465 | |||
466 | static int counter_is_active(unsigned long pmcr, int idx) | ||
467 | { | ||
468 | unsigned long mask = 0; | ||
469 | if (idx == ARMV6_CYCLE_COUNTER) | ||
470 | mask = ARMV6_PMCR_CCOUNT_IEN; | ||
471 | else if (idx == ARMV6_COUNTER0) | ||
472 | mask = ARMV6_PMCR_COUNT0_IEN; | ||
473 | else if (idx == ARMV6_COUNTER1) | ||
474 | mask = ARMV6_PMCR_COUNT1_IEN; | ||
475 | |||
476 | if (mask) | ||
477 | return pmcr & mask; | ||
478 | |||
479 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
480 | return 0; | ||
463 | } | 481 | } |
464 | 482 | ||
465 | static irqreturn_t | 483 | static irqreturn_t |
@@ -468,7 +486,7 @@ armv6pmu_handle_irq(int irq_num, | |||
468 | { | 486 | { |
469 | unsigned long pmcr = armv6_pmcr_read(); | 487 | unsigned long pmcr = armv6_pmcr_read(); |
470 | struct perf_sample_data data; | 488 | struct perf_sample_data data; |
471 | struct cpu_hw_events *cpuc; | 489 | struct pmu_hw_events *cpuc; |
472 | struct pt_regs *regs; | 490 | struct pt_regs *regs; |
473 | int idx; | 491 | int idx; |
474 | 492 | ||
@@ -487,11 +505,11 @@ armv6pmu_handle_irq(int irq_num, | |||
487 | perf_sample_data_init(&data, 0); | 505 | perf_sample_data_init(&data, 0); |
488 | 506 | ||
489 | cpuc = &__get_cpu_var(cpu_hw_events); | 507 | cpuc = &__get_cpu_var(cpu_hw_events); |
490 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | 508 | for (idx = 0; idx < cpu_pmu->num_events; ++idx) { |
491 | struct perf_event *event = cpuc->events[idx]; | 509 | struct perf_event *event = cpuc->events[idx]; |
492 | struct hw_perf_event *hwc; | 510 | struct hw_perf_event *hwc; |
493 | 511 | ||
494 | if (!test_bit(idx, cpuc->active_mask)) | 512 | if (!counter_is_active(pmcr, idx)) |
495 | continue; | 513 | continue; |
496 | 514 | ||
497 | /* | 515 | /* |
@@ -508,7 +526,7 @@ armv6pmu_handle_irq(int irq_num, | |||
508 | continue; | 526 | continue; |
509 | 527 | ||
510 | if (perf_event_overflow(event, &data, regs)) | 528 | if (perf_event_overflow(event, &data, regs)) |
511 | armpmu->disable(hwc, idx); | 529 | cpu_pmu->disable(hwc, idx); |
512 | } | 530 | } |
513 | 531 | ||
514 | /* | 532 | /* |
@@ -527,28 +545,30 @@ static void | |||
527 | armv6pmu_start(void) | 545 | armv6pmu_start(void) |
528 | { | 546 | { |
529 | unsigned long flags, val; | 547 | unsigned long flags, val; |
548 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
530 | 549 | ||
531 | raw_spin_lock_irqsave(&pmu_lock, flags); | 550 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
532 | val = armv6_pmcr_read(); | 551 | val = armv6_pmcr_read(); |
533 | val |= ARMV6_PMCR_ENABLE; | 552 | val |= ARMV6_PMCR_ENABLE; |
534 | armv6_pmcr_write(val); | 553 | armv6_pmcr_write(val); |
535 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 554 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
536 | } | 555 | } |
537 | 556 | ||
538 | static void | 557 | static void |
539 | armv6pmu_stop(void) | 558 | armv6pmu_stop(void) |
540 | { | 559 | { |
541 | unsigned long flags, val; | 560 | unsigned long flags, val; |
561 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
542 | 562 | ||
543 | raw_spin_lock_irqsave(&pmu_lock, flags); | 563 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
544 | val = armv6_pmcr_read(); | 564 | val = armv6_pmcr_read(); |
545 | val &= ~ARMV6_PMCR_ENABLE; | 565 | val &= ~ARMV6_PMCR_ENABLE; |
546 | armv6_pmcr_write(val); | 566 | armv6_pmcr_write(val); |
547 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 567 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
548 | } | 568 | } |
549 | 569 | ||
550 | static int | 570 | static int |
551 | armv6pmu_get_event_idx(struct cpu_hw_events *cpuc, | 571 | armv6pmu_get_event_idx(struct pmu_hw_events *cpuc, |
552 | struct hw_perf_event *event) | 572 | struct hw_perf_event *event) |
553 | { | 573 | { |
554 | /* Always place a cycle counter into the cycle counter. */ | 574 | /* Always place a cycle counter into the cycle counter. */ |
@@ -578,6 +598,7 @@ armv6pmu_disable_event(struct hw_perf_event *hwc, | |||
578 | int idx) | 598 | int idx) |
579 | { | 599 | { |
580 | unsigned long val, mask, evt, flags; | 600 | unsigned long val, mask, evt, flags; |
601 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
581 | 602 | ||
582 | if (ARMV6_CYCLE_COUNTER == idx) { | 603 | if (ARMV6_CYCLE_COUNTER == idx) { |
583 | mask = ARMV6_PMCR_CCOUNT_IEN; | 604 | mask = ARMV6_PMCR_CCOUNT_IEN; |
@@ -598,12 +619,12 @@ armv6pmu_disable_event(struct hw_perf_event *hwc, | |||
598 | * of ETM bus signal assertion cycles. The external reporting should | 619 | * of ETM bus signal assertion cycles. The external reporting should |
599 | * be disabled and so this should never increment. | 620 | * be disabled and so this should never increment. |
600 | */ | 621 | */ |
601 | raw_spin_lock_irqsave(&pmu_lock, flags); | 622 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
602 | val = armv6_pmcr_read(); | 623 | val = armv6_pmcr_read(); |
603 | val &= ~mask; | 624 | val &= ~mask; |
604 | val |= evt; | 625 | val |= evt; |
605 | armv6_pmcr_write(val); | 626 | armv6_pmcr_write(val); |
606 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 627 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
607 | } | 628 | } |
608 | 629 | ||
609 | static void | 630 | static void |
@@ -611,6 +632,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | |||
611 | int idx) | 632 | int idx) |
612 | { | 633 | { |
613 | unsigned long val, mask, flags, evt = 0; | 634 | unsigned long val, mask, flags, evt = 0; |
635 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
614 | 636 | ||
615 | if (ARMV6_CYCLE_COUNTER == idx) { | 637 | if (ARMV6_CYCLE_COUNTER == idx) { |
616 | mask = ARMV6_PMCR_CCOUNT_IEN; | 638 | mask = ARMV6_PMCR_CCOUNT_IEN; |
@@ -627,15 +649,21 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | |||
627 | * Unlike UP ARMv6, we don't have a way of stopping the counters. We | 649 | * Unlike UP ARMv6, we don't have a way of stopping the counters. We |
628 | * simply disable the interrupt reporting. | 650 | * simply disable the interrupt reporting. |
629 | */ | 651 | */ |
630 | raw_spin_lock_irqsave(&pmu_lock, flags); | 652 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
631 | val = armv6_pmcr_read(); | 653 | val = armv6_pmcr_read(); |
632 | val &= ~mask; | 654 | val &= ~mask; |
633 | val |= evt; | 655 | val |= evt; |
634 | armv6_pmcr_write(val); | 656 | armv6_pmcr_write(val); |
635 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 657 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
658 | } | ||
659 | |||
660 | static int armv6_map_event(struct perf_event *event) | ||
661 | { | ||
662 | return map_cpu_event(event, &armv6_perf_map, | ||
663 | &armv6_perf_cache_map, 0xFF); | ||
636 | } | 664 | } |
637 | 665 | ||
638 | static const struct arm_pmu armv6pmu = { | 666 | static struct arm_pmu armv6pmu = { |
639 | .id = ARM_PERF_PMU_ID_V6, | 667 | .id = ARM_PERF_PMU_ID_V6, |
640 | .name = "v6", | 668 | .name = "v6", |
641 | .handle_irq = armv6pmu_handle_irq, | 669 | .handle_irq = armv6pmu_handle_irq, |
@@ -646,14 +674,12 @@ static const struct arm_pmu armv6pmu = { | |||
646 | .get_event_idx = armv6pmu_get_event_idx, | 674 | .get_event_idx = armv6pmu_get_event_idx, |
647 | .start = armv6pmu_start, | 675 | .start = armv6pmu_start, |
648 | .stop = armv6pmu_stop, | 676 | .stop = armv6pmu_stop, |
649 | .cache_map = &armv6_perf_cache_map, | 677 | .map_event = armv6_map_event, |
650 | .event_map = &armv6_perf_map, | ||
651 | .raw_event_mask = 0xFF, | ||
652 | .num_events = 3, | 678 | .num_events = 3, |
653 | .max_period = (1LLU << 32) - 1, | 679 | .max_period = (1LLU << 32) - 1, |
654 | }; | 680 | }; |
655 | 681 | ||
656 | static const struct arm_pmu *__init armv6pmu_init(void) | 682 | static struct arm_pmu *__init armv6pmu_init(void) |
657 | { | 683 | { |
658 | return &armv6pmu; | 684 | return &armv6pmu; |
659 | } | 685 | } |
@@ -665,7 +691,14 @@ static const struct arm_pmu *__init armv6pmu_init(void) | |||
665 | * disable the interrupt reporting and update the event. When unthrottling we | 691 | * disable the interrupt reporting and update the event. When unthrottling we |
666 | * reset the period and enable the interrupt reporting. | 692 | * reset the period and enable the interrupt reporting. |
667 | */ | 693 | */ |
668 | static const struct arm_pmu armv6mpcore_pmu = { | 694 | |
695 | static int armv6mpcore_map_event(struct perf_event *event) | ||
696 | { | ||
697 | return map_cpu_event(event, &armv6mpcore_perf_map, | ||
698 | &armv6mpcore_perf_cache_map, 0xFF); | ||
699 | } | ||
700 | |||
701 | static struct arm_pmu armv6mpcore_pmu = { | ||
669 | .id = ARM_PERF_PMU_ID_V6MP, | 702 | .id = ARM_PERF_PMU_ID_V6MP, |
670 | .name = "v6mpcore", | 703 | .name = "v6mpcore", |
671 | .handle_irq = armv6pmu_handle_irq, | 704 | .handle_irq = armv6pmu_handle_irq, |
@@ -676,24 +709,22 @@ static const struct arm_pmu armv6mpcore_pmu = { | |||
676 | .get_event_idx = armv6pmu_get_event_idx, | 709 | .get_event_idx = armv6pmu_get_event_idx, |
677 | .start = armv6pmu_start, | 710 | .start = armv6pmu_start, |
678 | .stop = armv6pmu_stop, | 711 | .stop = armv6pmu_stop, |
679 | .cache_map = &armv6mpcore_perf_cache_map, | 712 | .map_event = armv6mpcore_map_event, |
680 | .event_map = &armv6mpcore_perf_map, | ||
681 | .raw_event_mask = 0xFF, | ||
682 | .num_events = 3, | 713 | .num_events = 3, |
683 | .max_period = (1LLU << 32) - 1, | 714 | .max_period = (1LLU << 32) - 1, |
684 | }; | 715 | }; |
685 | 716 | ||
686 | static const struct arm_pmu *__init armv6mpcore_pmu_init(void) | 717 | static struct arm_pmu *__init armv6mpcore_pmu_init(void) |
687 | { | 718 | { |
688 | return &armv6mpcore_pmu; | 719 | return &armv6mpcore_pmu; |
689 | } | 720 | } |
690 | #else | 721 | #else |
691 | static const struct arm_pmu *__init armv6pmu_init(void) | 722 | static struct arm_pmu *__init armv6pmu_init(void) |
692 | { | 723 | { |
693 | return NULL; | 724 | return NULL; |
694 | } | 725 | } |
695 | 726 | ||
696 | static const struct arm_pmu *__init armv6mpcore_pmu_init(void) | 727 | static struct arm_pmu *__init armv6mpcore_pmu_init(void) |
697 | { | 728 | { |
698 | return NULL; | 729 | return NULL; |
699 | } | 730 | } |
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4c851834f68e..98b75738345e 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
@@ -17,6 +17,9 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #ifdef CONFIG_CPU_V7 | 19 | #ifdef CONFIG_CPU_V7 |
20 | |||
21 | static struct arm_pmu armv7pmu; | ||
22 | |||
20 | /* | 23 | /* |
21 | * Common ARMv7 event types | 24 | * Common ARMv7 event types |
22 | * | 25 | * |
@@ -676,23 +679,24 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
676 | }; | 679 | }; |
677 | 680 | ||
678 | /* | 681 | /* |
679 | * Perf Events counters | 682 | * Perf Events' indices |
680 | */ | 683 | */ |
681 | enum armv7_counters { | 684 | #define ARMV7_IDX_CYCLE_COUNTER 0 |
682 | ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */ | 685 | #define ARMV7_IDX_COUNTER0 1 |
683 | ARMV7_COUNTER0 = 2, /* First event counter */ | 686 | #define ARMV7_IDX_COUNTER_LAST (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1) |
684 | }; | 687 | |
688 | #define ARMV7_MAX_COUNTERS 32 | ||
689 | #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1) | ||
685 | 690 | ||
686 | /* | 691 | /* |
687 | * The cycle counter is ARMV7_CYCLE_COUNTER. | 692 | * ARMv7 low level PMNC access |
688 | * The first event counter is ARMV7_COUNTER0. | ||
689 | * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1). | ||
690 | */ | 693 | */ |
691 | #define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1) | ||
692 | 694 | ||
693 | /* | 695 | /* |
694 | * ARMv7 low level PMNC access | 696 | * Perf Event to low level counters mapping |
695 | */ | 697 | */ |
698 | #define ARMV7_IDX_TO_COUNTER(x) \ | ||
699 | (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK) | ||
696 | 700 | ||
697 | /* | 701 | /* |
698 | * Per-CPU PMNC: config reg | 702 | * Per-CPU PMNC: config reg |
@@ -708,103 +712,76 @@ enum armv7_counters { | |||
708 | #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */ | 712 | #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */ |
709 | 713 | ||
710 | /* | 714 | /* |
711 | * Available counters | 715 | * FLAG: counters overflow flag status reg |
712 | */ | ||
713 | #define ARMV7_CNT0 0 /* First event counter */ | ||
714 | #define ARMV7_CCNT 31 /* Cycle counter */ | ||
715 | |||
716 | /* Perf Event to low level counters mapping */ | ||
717 | #define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0) | ||
718 | |||
719 | /* | ||
720 | * CNTENS: counters enable reg | ||
721 | */ | ||
722 | #define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
723 | #define ARMV7_CNTENS_C (1 << ARMV7_CCNT) | ||
724 | |||
725 | /* | ||
726 | * CNTENC: counters disable reg | ||
727 | */ | ||
728 | #define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
729 | #define ARMV7_CNTENC_C (1 << ARMV7_CCNT) | ||
730 | |||
731 | /* | ||
732 | * INTENS: counters overflow interrupt enable reg | ||
733 | */ | ||
734 | #define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
735 | #define ARMV7_INTENS_C (1 << ARMV7_CCNT) | ||
736 | |||
737 | /* | ||
738 | * INTENC: counters overflow interrupt disable reg | ||
739 | */ | ||
740 | #define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
741 | #define ARMV7_INTENC_C (1 << ARMV7_CCNT) | ||
742 | |||
743 | /* | ||
744 | * EVTSEL: Event selection reg | ||
745 | */ | 716 | */ |
746 | #define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */ | 717 | #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */ |
718 | #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK | ||
747 | 719 | ||
748 | /* | 720 | /* |
749 | * SELECT: Counter selection reg | 721 | * PMXEVTYPER: Event selection reg |
750 | */ | 722 | */ |
751 | #define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */ | 723 | #define ARMV7_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */ |
724 | #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */ | ||
752 | 725 | ||
753 | /* | 726 | /* |
754 | * FLAG: counters overflow flag status reg | 727 | * Event filters for PMUv2 |
755 | */ | 728 | */ |
756 | #define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | 729 | #define ARMV7_EXCLUDE_PL1 (1 << 31) |
757 | #define ARMV7_FLAG_C (1 << ARMV7_CCNT) | 730 | #define ARMV7_EXCLUDE_USER (1 << 30) |
758 | #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */ | 731 | #define ARMV7_INCLUDE_HYP (1 << 27) |
759 | #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK | ||
760 | 732 | ||
761 | static inline unsigned long armv7_pmnc_read(void) | 733 | static inline u32 armv7_pmnc_read(void) |
762 | { | 734 | { |
763 | u32 val; | 735 | u32 val; |
764 | asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val)); | 736 | asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val)); |
765 | return val; | 737 | return val; |
766 | } | 738 | } |
767 | 739 | ||
768 | static inline void armv7_pmnc_write(unsigned long val) | 740 | static inline void armv7_pmnc_write(u32 val) |
769 | { | 741 | { |
770 | val &= ARMV7_PMNC_MASK; | 742 | val &= ARMV7_PMNC_MASK; |
771 | isb(); | 743 | isb(); |
772 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); | 744 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); |
773 | } | 745 | } |
774 | 746 | ||
775 | static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) | 747 | static inline int armv7_pmnc_has_overflowed(u32 pmnc) |
776 | { | 748 | { |
777 | return pmnc & ARMV7_OVERFLOWED_MASK; | 749 | return pmnc & ARMV7_OVERFLOWED_MASK; |
778 | } | 750 | } |
779 | 751 | ||
780 | static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, | 752 | static inline int armv7_pmnc_counter_valid(int idx) |
781 | enum armv7_counters counter) | 753 | { |
754 | return idx >= ARMV7_IDX_CYCLE_COUNTER && idx <= ARMV7_IDX_COUNTER_LAST; | ||
755 | } | ||
756 | |||
757 | static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx) | ||
782 | { | 758 | { |
783 | int ret = 0; | 759 | int ret = 0; |
760 | u32 counter; | ||
784 | 761 | ||
785 | if (counter == ARMV7_CYCLE_COUNTER) | 762 | if (!armv7_pmnc_counter_valid(idx)) { |
786 | ret = pmnc & ARMV7_FLAG_C; | ||
787 | else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST)) | ||
788 | ret = pmnc & ARMV7_FLAG_P(counter); | ||
789 | else | ||
790 | pr_err("CPU%u checking wrong counter %d overflow status\n", | 763 | pr_err("CPU%u checking wrong counter %d overflow status\n", |
791 | smp_processor_id(), counter); | 764 | smp_processor_id(), idx); |
765 | } else { | ||
766 | counter = ARMV7_IDX_TO_COUNTER(idx); | ||
767 | ret = pmnc & BIT(counter); | ||
768 | } | ||
792 | 769 | ||
793 | return ret; | 770 | return ret; |
794 | } | 771 | } |
795 | 772 | ||
796 | static inline int armv7_pmnc_select_counter(unsigned int idx) | 773 | static inline int armv7_pmnc_select_counter(int idx) |
797 | { | 774 | { |
798 | u32 val; | 775 | u32 counter; |
799 | 776 | ||
800 | if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) { | 777 | if (!armv7_pmnc_counter_valid(idx)) { |
801 | pr_err("CPU%u selecting wrong PMNC counter" | 778 | pr_err("CPU%u selecting wrong PMNC counter %d\n", |
802 | " %d\n", smp_processor_id(), idx); | 779 | smp_processor_id(), idx); |
803 | return -1; | 780 | return -EINVAL; |
804 | } | 781 | } |
805 | 782 | ||
806 | val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; | 783 | counter = ARMV7_IDX_TO_COUNTER(idx); |
807 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); | 784 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter)); |
808 | isb(); | 785 | isb(); |
809 | 786 | ||
810 | return idx; | 787 | return idx; |
@@ -812,124 +789,95 @@ static inline int armv7_pmnc_select_counter(unsigned int idx) | |||
812 | 789 | ||
813 | static inline u32 armv7pmu_read_counter(int idx) | 790 | static inline u32 armv7pmu_read_counter(int idx) |
814 | { | 791 | { |
815 | unsigned long value = 0; | 792 | u32 value = 0; |
816 | 793 | ||
817 | if (idx == ARMV7_CYCLE_COUNTER) | 794 | if (!armv7_pmnc_counter_valid(idx)) |
818 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); | ||
819 | else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { | ||
820 | if (armv7_pmnc_select_counter(idx) == idx) | ||
821 | asm volatile("mrc p15, 0, %0, c9, c13, 2" | ||
822 | : "=r" (value)); | ||
823 | } else | ||
824 | pr_err("CPU%u reading wrong counter %d\n", | 795 | pr_err("CPU%u reading wrong counter %d\n", |
825 | smp_processor_id(), idx); | 796 | smp_processor_id(), idx); |
797 | else if (idx == ARMV7_IDX_CYCLE_COUNTER) | ||
798 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); | ||
799 | else if (armv7_pmnc_select_counter(idx) == idx) | ||
800 | asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value)); | ||
826 | 801 | ||
827 | return value; | 802 | return value; |
828 | } | 803 | } |
829 | 804 | ||
830 | static inline void armv7pmu_write_counter(int idx, u32 value) | 805 | static inline void armv7pmu_write_counter(int idx, u32 value) |
831 | { | 806 | { |
832 | if (idx == ARMV7_CYCLE_COUNTER) | 807 | if (!armv7_pmnc_counter_valid(idx)) |
833 | asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); | ||
834 | else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { | ||
835 | if (armv7_pmnc_select_counter(idx) == idx) | ||
836 | asm volatile("mcr p15, 0, %0, c9, c13, 2" | ||
837 | : : "r" (value)); | ||
838 | } else | ||
839 | pr_err("CPU%u writing wrong counter %d\n", | 808 | pr_err("CPU%u writing wrong counter %d\n", |
840 | smp_processor_id(), idx); | 809 | smp_processor_id(), idx); |
810 | else if (idx == ARMV7_IDX_CYCLE_COUNTER) | ||
811 | asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); | ||
812 | else if (armv7_pmnc_select_counter(idx) == idx) | ||
813 | asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value)); | ||
841 | } | 814 | } |
842 | 815 | ||
843 | static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val) | 816 | static inline void armv7_pmnc_write_evtsel(int idx, u32 val) |
844 | { | 817 | { |
845 | if (armv7_pmnc_select_counter(idx) == idx) { | 818 | if (armv7_pmnc_select_counter(idx) == idx) { |
846 | val &= ARMV7_EVTSEL_MASK; | 819 | val &= ARMV7_EVTYPE_MASK; |
847 | asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); | 820 | asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); |
848 | } | 821 | } |
849 | } | 822 | } |
850 | 823 | ||
851 | static inline u32 armv7_pmnc_enable_counter(unsigned int idx) | 824 | static inline int armv7_pmnc_enable_counter(int idx) |
852 | { | 825 | { |
853 | u32 val; | 826 | u32 counter; |
854 | 827 | ||
855 | if ((idx != ARMV7_CYCLE_COUNTER) && | 828 | if (!armv7_pmnc_counter_valid(idx)) { |
856 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | 829 | pr_err("CPU%u enabling wrong PMNC counter %d\n", |
857 | pr_err("CPU%u enabling wrong PMNC counter" | 830 | smp_processor_id(), idx); |
858 | " %d\n", smp_processor_id(), idx); | 831 | return -EINVAL; |
859 | return -1; | ||
860 | } | 832 | } |
861 | 833 | ||
862 | if (idx == ARMV7_CYCLE_COUNTER) | 834 | counter = ARMV7_IDX_TO_COUNTER(idx); |
863 | val = ARMV7_CNTENS_C; | 835 | asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter))); |
864 | else | ||
865 | val = ARMV7_CNTENS_P(idx); | ||
866 | |||
867 | asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); | ||
868 | |||
869 | return idx; | 836 | return idx; |
870 | } | 837 | } |
871 | 838 | ||
872 | static inline u32 armv7_pmnc_disable_counter(unsigned int idx) | 839 | static inline int armv7_pmnc_disable_counter(int idx) |
873 | { | 840 | { |
874 | u32 val; | 841 | u32 counter; |
875 | |||
876 | 842 | ||
877 | if ((idx != ARMV7_CYCLE_COUNTER) && | 843 | if (!armv7_pmnc_counter_valid(idx)) { |
878 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | 844 | pr_err("CPU%u disabling wrong PMNC counter %d\n", |
879 | pr_err("CPU%u disabling wrong PMNC counter" | 845 | smp_processor_id(), idx); |
880 | " %d\n", smp_processor_id(), idx); | 846 | return -EINVAL; |
881 | return -1; | ||
882 | } | 847 | } |
883 | 848 | ||
884 | if (idx == ARMV7_CYCLE_COUNTER) | 849 | counter = ARMV7_IDX_TO_COUNTER(idx); |
885 | val = ARMV7_CNTENC_C; | 850 | asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter))); |
886 | else | ||
887 | val = ARMV7_CNTENC_P(idx); | ||
888 | |||
889 | asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); | ||
890 | |||
891 | return idx; | 851 | return idx; |
892 | } | 852 | } |
893 | 853 | ||
894 | static inline u32 armv7_pmnc_enable_intens(unsigned int idx) | 854 | static inline int armv7_pmnc_enable_intens(int idx) |
895 | { | 855 | { |
896 | u32 val; | 856 | u32 counter; |
897 | 857 | ||
898 | if ((idx != ARMV7_CYCLE_COUNTER) && | 858 | if (!armv7_pmnc_counter_valid(idx)) { |
899 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | 859 | pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n", |
900 | pr_err("CPU%u enabling wrong PMNC counter" | 860 | smp_processor_id(), idx); |
901 | " interrupt enable %d\n", smp_processor_id(), idx); | 861 | return -EINVAL; |
902 | return -1; | ||
903 | } | 862 | } |
904 | 863 | ||
905 | if (idx == ARMV7_CYCLE_COUNTER) | 864 | counter = ARMV7_IDX_TO_COUNTER(idx); |
906 | val = ARMV7_INTENS_C; | 865 | asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter))); |
907 | else | ||
908 | val = ARMV7_INTENS_P(idx); | ||
909 | |||
910 | asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val)); | ||
911 | |||
912 | return idx; | 866 | return idx; |
913 | } | 867 | } |
914 | 868 | ||
915 | static inline u32 armv7_pmnc_disable_intens(unsigned int idx) | 869 | static inline int armv7_pmnc_disable_intens(int idx) |
916 | { | 870 | { |
917 | u32 val; | 871 | u32 counter; |
918 | 872 | ||
919 | if ((idx != ARMV7_CYCLE_COUNTER) && | 873 | if (!armv7_pmnc_counter_valid(idx)) { |
920 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | 874 | pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n", |
921 | pr_err("CPU%u disabling wrong PMNC counter" | 875 | smp_processor_id(), idx); |
922 | " interrupt enable %d\n", smp_processor_id(), idx); | 876 | return -EINVAL; |
923 | return -1; | ||
924 | } | 877 | } |
925 | 878 | ||
926 | if (idx == ARMV7_CYCLE_COUNTER) | 879 | counter = ARMV7_IDX_TO_COUNTER(idx); |
927 | val = ARMV7_INTENC_C; | 880 | asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter))); |
928 | else | ||
929 | val = ARMV7_INTENC_P(idx); | ||
930 | |||
931 | asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val)); | ||
932 | |||
933 | return idx; | 881 | return idx; |
934 | } | 882 | } |
935 | 883 | ||
@@ -973,14 +921,14 @@ static void armv7_pmnc_dump_regs(void) | |||
973 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); | 921 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); |
974 | printk(KERN_INFO "CCNT =0x%08x\n", val); | 922 | printk(KERN_INFO "CCNT =0x%08x\n", val); |
975 | 923 | ||
976 | for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) { | 924 | for (cnt = ARMV7_IDX_COUNTER0; cnt <= ARMV7_IDX_COUNTER_LAST; cnt++) { |
977 | armv7_pmnc_select_counter(cnt); | 925 | armv7_pmnc_select_counter(cnt); |
978 | asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); | 926 | asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); |
979 | printk(KERN_INFO "CNT[%d] count =0x%08x\n", | 927 | printk(KERN_INFO "CNT[%d] count =0x%08x\n", |
980 | cnt-ARMV7_EVENT_CNT_TO_CNTx, val); | 928 | ARMV7_IDX_TO_COUNTER(cnt), val); |
981 | asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); | 929 | asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); |
982 | printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", | 930 | printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", |
983 | cnt-ARMV7_EVENT_CNT_TO_CNTx, val); | 931 | ARMV7_IDX_TO_COUNTER(cnt), val); |
984 | } | 932 | } |
985 | } | 933 | } |
986 | #endif | 934 | #endif |
@@ -988,12 +936,13 @@ static void armv7_pmnc_dump_regs(void) | |||
988 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | 936 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) |
989 | { | 937 | { |
990 | unsigned long flags; | 938 | unsigned long flags; |
939 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
991 | 940 | ||
992 | /* | 941 | /* |
993 | * Enable counter and interrupt, and set the counter to count | 942 | * Enable counter and interrupt, and set the counter to count |
994 | * the event that we're interested in. | 943 | * the event that we're interested in. |
995 | */ | 944 | */ |
996 | raw_spin_lock_irqsave(&pmu_lock, flags); | 945 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
997 | 946 | ||
998 | /* | 947 | /* |
999 | * Disable counter | 948 | * Disable counter |
@@ -1002,9 +951,10 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
1002 | 951 | ||
1003 | /* | 952 | /* |
1004 | * Set event (if destined for PMNx counters) | 953 | * Set event (if destined for PMNx counters) |
1005 | * We don't need to set the event if it's a cycle count | 954 | * We only need to set the event for the cycle counter if we |
955 | * have the ability to perform event filtering. | ||
1006 | */ | 956 | */ |
1007 | if (idx != ARMV7_CYCLE_COUNTER) | 957 | if (armv7pmu.set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER) |
1008 | armv7_pmnc_write_evtsel(idx, hwc->config_base); | 958 | armv7_pmnc_write_evtsel(idx, hwc->config_base); |
1009 | 959 | ||
1010 | /* | 960 | /* |
@@ -1017,17 +967,18 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
1017 | */ | 967 | */ |
1018 | armv7_pmnc_enable_counter(idx); | 968 | armv7_pmnc_enable_counter(idx); |
1019 | 969 | ||
1020 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 970 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1021 | } | 971 | } |
1022 | 972 | ||
1023 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | 973 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) |
1024 | { | 974 | { |
1025 | unsigned long flags; | 975 | unsigned long flags; |
976 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
1026 | 977 | ||
1027 | /* | 978 | /* |
1028 | * Disable counter and interrupt | 979 | * Disable counter and interrupt |
1029 | */ | 980 | */ |
1030 | raw_spin_lock_irqsave(&pmu_lock, flags); | 981 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1031 | 982 | ||
1032 | /* | 983 | /* |
1033 | * Disable counter | 984 | * Disable counter |
@@ -1039,14 +990,14 @@ static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
1039 | */ | 990 | */ |
1040 | armv7_pmnc_disable_intens(idx); | 991 | armv7_pmnc_disable_intens(idx); |
1041 | 992 | ||
1042 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 993 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1043 | } | 994 | } |
1044 | 995 | ||
1045 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | 996 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) |
1046 | { | 997 | { |
1047 | unsigned long pmnc; | 998 | u32 pmnc; |
1048 | struct perf_sample_data data; | 999 | struct perf_sample_data data; |
1049 | struct cpu_hw_events *cpuc; | 1000 | struct pmu_hw_events *cpuc; |
1050 | struct pt_regs *regs; | 1001 | struct pt_regs *regs; |
1051 | int idx; | 1002 | int idx; |
1052 | 1003 | ||
@@ -1069,13 +1020,10 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
1069 | perf_sample_data_init(&data, 0); | 1020 | perf_sample_data_init(&data, 0); |
1070 | 1021 | ||
1071 | cpuc = &__get_cpu_var(cpu_hw_events); | 1022 | cpuc = &__get_cpu_var(cpu_hw_events); |
1072 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | 1023 | for (idx = 0; idx < cpu_pmu->num_events; ++idx) { |
1073 | struct perf_event *event = cpuc->events[idx]; | 1024 | struct perf_event *event = cpuc->events[idx]; |
1074 | struct hw_perf_event *hwc; | 1025 | struct hw_perf_event *hwc; |
1075 | 1026 | ||
1076 | if (!test_bit(idx, cpuc->active_mask)) | ||
1077 | continue; | ||
1078 | |||
1079 | /* | 1027 | /* |
1080 | * We have a single interrupt for all counters. Check that | 1028 | * We have a single interrupt for all counters. Check that |
1081 | * each counter has overflowed before we process it. | 1029 | * each counter has overflowed before we process it. |
@@ -1090,7 +1038,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
1090 | continue; | 1038 | continue; |
1091 | 1039 | ||
1092 | if (perf_event_overflow(event, &data, regs)) | 1040 | if (perf_event_overflow(event, &data, regs)) |
1093 | armpmu->disable(hwc, idx); | 1041 | cpu_pmu->disable(hwc, idx); |
1094 | } | 1042 | } |
1095 | 1043 | ||
1096 | /* | 1044 | /* |
@@ -1108,61 +1056,114 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
1108 | static void armv7pmu_start(void) | 1056 | static void armv7pmu_start(void) |
1109 | { | 1057 | { |
1110 | unsigned long flags; | 1058 | unsigned long flags; |
1059 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
1111 | 1060 | ||
1112 | raw_spin_lock_irqsave(&pmu_lock, flags); | 1061 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1113 | /* Enable all counters */ | 1062 | /* Enable all counters */ |
1114 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); | 1063 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); |
1115 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 1064 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1116 | } | 1065 | } |
1117 | 1066 | ||
1118 | static void armv7pmu_stop(void) | 1067 | static void armv7pmu_stop(void) |
1119 | { | 1068 | { |
1120 | unsigned long flags; | 1069 | unsigned long flags; |
1070 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
1121 | 1071 | ||
1122 | raw_spin_lock_irqsave(&pmu_lock, flags); | 1072 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1123 | /* Disable all counters */ | 1073 | /* Disable all counters */ |
1124 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); | 1074 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); |
1125 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 1075 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1126 | } | 1076 | } |
1127 | 1077 | ||
1128 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, | 1078 | static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc, |
1129 | struct hw_perf_event *event) | 1079 | struct hw_perf_event *event) |
1130 | { | 1080 | { |
1131 | int idx; | 1081 | int idx; |
1082 | unsigned long evtype = event->config_base & ARMV7_EVTYPE_EVENT; | ||
1132 | 1083 | ||
1133 | /* Always place a cycle counter into the cycle counter. */ | 1084 | /* Always place a cycle counter into the cycle counter. */ |
1134 | if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) { | 1085 | if (evtype == ARMV7_PERFCTR_CPU_CYCLES) { |
1135 | if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask)) | 1086 | if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask)) |
1136 | return -EAGAIN; | 1087 | return -EAGAIN; |
1137 | 1088 | ||
1138 | return ARMV7_CYCLE_COUNTER; | 1089 | return ARMV7_IDX_CYCLE_COUNTER; |
1139 | } else { | 1090 | } |
1140 | /* | ||
1141 | * For anything other than a cycle counter, try and use | ||
1142 | * the events counters | ||
1143 | */ | ||
1144 | for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) { | ||
1145 | if (!test_and_set_bit(idx, cpuc->used_mask)) | ||
1146 | return idx; | ||
1147 | } | ||
1148 | 1091 | ||
1149 | /* The counters are all in use. */ | 1092 | /* |
1150 | return -EAGAIN; | 1093 | * For anything other than a cycle counter, try and use |
1094 | * the events counters | ||
1095 | */ | ||
1096 | for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) { | ||
1097 | if (!test_and_set_bit(idx, cpuc->used_mask)) | ||
1098 | return idx; | ||
1151 | } | 1099 | } |
1100 | |||
1101 | /* The counters are all in use. */ | ||
1102 | return -EAGAIN; | ||
1103 | } | ||
1104 | |||
1105 | /* | ||
1106 | * Add an event filter to a given event. This will only work for PMUv2 PMUs. | ||
1107 | */ | ||
1108 | static int armv7pmu_set_event_filter(struct hw_perf_event *event, | ||
1109 | struct perf_event_attr *attr) | ||
1110 | { | ||
1111 | unsigned long config_base = 0; | ||
1112 | |||
1113 | if (attr->exclude_idle) | ||
1114 | return -EPERM; | ||
1115 | if (attr->exclude_user) | ||
1116 | config_base |= ARMV7_EXCLUDE_USER; | ||
1117 | if (attr->exclude_kernel) | ||
1118 | config_base |= ARMV7_EXCLUDE_PL1; | ||
1119 | if (!attr->exclude_hv) | ||
1120 | config_base |= ARMV7_INCLUDE_HYP; | ||
1121 | |||
1122 | /* | ||
1123 | * Install the filter into config_base as this is used to | ||
1124 | * construct the event type. | ||
1125 | */ | ||
1126 | event->config_base = config_base; | ||
1127 | |||
1128 | return 0; | ||
1152 | } | 1129 | } |
1153 | 1130 | ||
1154 | static void armv7pmu_reset(void *info) | 1131 | static void armv7pmu_reset(void *info) |
1155 | { | 1132 | { |
1156 | u32 idx, nb_cnt = armpmu->num_events; | 1133 | u32 idx, nb_cnt = cpu_pmu->num_events; |
1157 | 1134 | ||
1158 | /* The counter and interrupt enable registers are unknown at reset. */ | 1135 | /* The counter and interrupt enable registers are unknown at reset. */ |
1159 | for (idx = 1; idx < nb_cnt; ++idx) | 1136 | for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) |
1160 | armv7pmu_disable_event(NULL, idx); | 1137 | armv7pmu_disable_event(NULL, idx); |
1161 | 1138 | ||
1162 | /* Initialize & Reset PMNC: C and P bits */ | 1139 | /* Initialize & Reset PMNC: C and P bits */ |
1163 | armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); | 1140 | armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); |
1164 | } | 1141 | } |
1165 | 1142 | ||
1143 | static int armv7_a8_map_event(struct perf_event *event) | ||
1144 | { | ||
1145 | return map_cpu_event(event, &armv7_a8_perf_map, | ||
1146 | &armv7_a8_perf_cache_map, 0xFF); | ||
1147 | } | ||
1148 | |||
1149 | static int armv7_a9_map_event(struct perf_event *event) | ||
1150 | { | ||
1151 | return map_cpu_event(event, &armv7_a9_perf_map, | ||
1152 | &armv7_a9_perf_cache_map, 0xFF); | ||
1153 | } | ||
1154 | |||
1155 | static int armv7_a5_map_event(struct perf_event *event) | ||
1156 | { | ||
1157 | return map_cpu_event(event, &armv7_a5_perf_map, | ||
1158 | &armv7_a5_perf_cache_map, 0xFF); | ||
1159 | } | ||
1160 | |||
1161 | static int armv7_a15_map_event(struct perf_event *event) | ||
1162 | { | ||
1163 | return map_cpu_event(event, &armv7_a15_perf_map, | ||
1164 | &armv7_a15_perf_cache_map, 0xFF); | ||
1165 | } | ||
1166 | |||
1166 | static struct arm_pmu armv7pmu = { | 1167 | static struct arm_pmu armv7pmu = { |
1167 | .handle_irq = armv7pmu_handle_irq, | 1168 | .handle_irq = armv7pmu_handle_irq, |
1168 | .enable = armv7pmu_enable_event, | 1169 | .enable = armv7pmu_enable_event, |
@@ -1173,7 +1174,6 @@ static struct arm_pmu armv7pmu = { | |||
1173 | .start = armv7pmu_start, | 1174 | .start = armv7pmu_start, |
1174 | .stop = armv7pmu_stop, | 1175 | .stop = armv7pmu_stop, |
1175 | .reset = armv7pmu_reset, | 1176 | .reset = armv7pmu_reset, |
1176 | .raw_event_mask = 0xFF, | ||
1177 | .max_period = (1LLU << 32) - 1, | 1177 | .max_period = (1LLU << 32) - 1, |
1178 | }; | 1178 | }; |
1179 | 1179 | ||
@@ -1188,62 +1188,59 @@ static u32 __init armv7_read_num_pmnc_events(void) | |||
1188 | return nb_cnt + 1; | 1188 | return nb_cnt + 1; |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | static const struct arm_pmu *__init armv7_a8_pmu_init(void) | 1191 | static struct arm_pmu *__init armv7_a8_pmu_init(void) |
1192 | { | 1192 | { |
1193 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; | 1193 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; |
1194 | armv7pmu.name = "ARMv7 Cortex-A8"; | 1194 | armv7pmu.name = "ARMv7 Cortex-A8"; |
1195 | armv7pmu.cache_map = &armv7_a8_perf_cache_map; | 1195 | armv7pmu.map_event = armv7_a8_map_event; |
1196 | armv7pmu.event_map = &armv7_a8_perf_map; | ||
1197 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1196 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
1198 | return &armv7pmu; | 1197 | return &armv7pmu; |
1199 | } | 1198 | } |
1200 | 1199 | ||
1201 | static const struct arm_pmu *__init armv7_a9_pmu_init(void) | 1200 | static struct arm_pmu *__init armv7_a9_pmu_init(void) |
1202 | { | 1201 | { |
1203 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; | 1202 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; |
1204 | armv7pmu.name = "ARMv7 Cortex-A9"; | 1203 | armv7pmu.name = "ARMv7 Cortex-A9"; |
1205 | armv7pmu.cache_map = &armv7_a9_perf_cache_map; | 1204 | armv7pmu.map_event = armv7_a9_map_event; |
1206 | armv7pmu.event_map = &armv7_a9_perf_map; | ||
1207 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1205 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
1208 | return &armv7pmu; | 1206 | return &armv7pmu; |
1209 | } | 1207 | } |
1210 | 1208 | ||
1211 | static const struct arm_pmu *__init armv7_a5_pmu_init(void) | 1209 | static struct arm_pmu *__init armv7_a5_pmu_init(void) |
1212 | { | 1210 | { |
1213 | armv7pmu.id = ARM_PERF_PMU_ID_CA5; | 1211 | armv7pmu.id = ARM_PERF_PMU_ID_CA5; |
1214 | armv7pmu.name = "ARMv7 Cortex-A5"; | 1212 | armv7pmu.name = "ARMv7 Cortex-A5"; |
1215 | armv7pmu.cache_map = &armv7_a5_perf_cache_map; | 1213 | armv7pmu.map_event = armv7_a5_map_event; |
1216 | armv7pmu.event_map = &armv7_a5_perf_map; | ||
1217 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1214 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
1218 | return &armv7pmu; | 1215 | return &armv7pmu; |
1219 | } | 1216 | } |
1220 | 1217 | ||
1221 | static const struct arm_pmu *__init armv7_a15_pmu_init(void) | 1218 | static struct arm_pmu *__init armv7_a15_pmu_init(void) |
1222 | { | 1219 | { |
1223 | armv7pmu.id = ARM_PERF_PMU_ID_CA15; | 1220 | armv7pmu.id = ARM_PERF_PMU_ID_CA15; |
1224 | armv7pmu.name = "ARMv7 Cortex-A15"; | 1221 | armv7pmu.name = "ARMv7 Cortex-A15"; |
1225 | armv7pmu.cache_map = &armv7_a15_perf_cache_map; | 1222 | armv7pmu.map_event = armv7_a15_map_event; |
1226 | armv7pmu.event_map = &armv7_a15_perf_map; | ||
1227 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1223 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
1224 | armv7pmu.set_event_filter = armv7pmu_set_event_filter; | ||
1228 | return &armv7pmu; | 1225 | return &armv7pmu; |
1229 | } | 1226 | } |
1230 | #else | 1227 | #else |
1231 | static const struct arm_pmu *__init armv7_a8_pmu_init(void) | 1228 | static struct arm_pmu *__init armv7_a8_pmu_init(void) |
1232 | { | 1229 | { |
1233 | return NULL; | 1230 | return NULL; |
1234 | } | 1231 | } |
1235 | 1232 | ||
1236 | static const struct arm_pmu *__init armv7_a9_pmu_init(void) | 1233 | static struct arm_pmu *__init armv7_a9_pmu_init(void) |
1237 | { | 1234 | { |
1238 | return NULL; | 1235 | return NULL; |
1239 | } | 1236 | } |
1240 | 1237 | ||
1241 | static const struct arm_pmu *__init armv7_a5_pmu_init(void) | 1238 | static struct arm_pmu *__init armv7_a5_pmu_init(void) |
1242 | { | 1239 | { |
1243 | return NULL; | 1240 | return NULL; |
1244 | } | 1241 | } |
1245 | 1242 | ||
1246 | static const struct arm_pmu *__init armv7_a15_pmu_init(void) | 1243 | static struct arm_pmu *__init armv7_a15_pmu_init(void) |
1247 | { | 1244 | { |
1248 | return NULL; | 1245 | return NULL; |
1249 | } | 1246 | } |
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index 3c4397491d08..e0cca10a8411 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c | |||
@@ -40,7 +40,7 @@ enum xscale_perf_types { | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | enum xscale_counters { | 42 | enum xscale_counters { |
43 | XSCALE_CYCLE_COUNTER = 1, | 43 | XSCALE_CYCLE_COUNTER = 0, |
44 | XSCALE_COUNTER0, | 44 | XSCALE_COUNTER0, |
45 | XSCALE_COUNTER1, | 45 | XSCALE_COUNTER1, |
46 | XSCALE_COUNTER2, | 46 | XSCALE_COUNTER2, |
@@ -222,7 +222,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev) | |||
222 | { | 222 | { |
223 | unsigned long pmnc; | 223 | unsigned long pmnc; |
224 | struct perf_sample_data data; | 224 | struct perf_sample_data data; |
225 | struct cpu_hw_events *cpuc; | 225 | struct pmu_hw_events *cpuc; |
226 | struct pt_regs *regs; | 226 | struct pt_regs *regs; |
227 | int idx; | 227 | int idx; |
228 | 228 | ||
@@ -249,13 +249,10 @@ xscale1pmu_handle_irq(int irq_num, void *dev) | |||
249 | perf_sample_data_init(&data, 0); | 249 | perf_sample_data_init(&data, 0); |
250 | 250 | ||
251 | cpuc = &__get_cpu_var(cpu_hw_events); | 251 | cpuc = &__get_cpu_var(cpu_hw_events); |
252 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | 252 | for (idx = 0; idx < cpu_pmu->num_events; ++idx) { |
253 | struct perf_event *event = cpuc->events[idx]; | 253 | struct perf_event *event = cpuc->events[idx]; |
254 | struct hw_perf_event *hwc; | 254 | struct hw_perf_event *hwc; |
255 | 255 | ||
256 | if (!test_bit(idx, cpuc->active_mask)) | ||
257 | continue; | ||
258 | |||
259 | if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx)) | 256 | if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx)) |
260 | continue; | 257 | continue; |
261 | 258 | ||
@@ -266,7 +263,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev) | |||
266 | continue; | 263 | continue; |
267 | 264 | ||
268 | if (perf_event_overflow(event, &data, regs)) | 265 | if (perf_event_overflow(event, &data, regs)) |
269 | armpmu->disable(hwc, idx); | 266 | cpu_pmu->disable(hwc, idx); |
270 | } | 267 | } |
271 | 268 | ||
272 | irq_work_run(); | 269 | irq_work_run(); |
@@ -284,6 +281,7 @@ static void | |||
284 | xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) | 281 | xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) |
285 | { | 282 | { |
286 | unsigned long val, mask, evt, flags; | 283 | unsigned long val, mask, evt, flags; |
284 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
287 | 285 | ||
288 | switch (idx) { | 286 | switch (idx) { |
289 | case XSCALE_CYCLE_COUNTER: | 287 | case XSCALE_CYCLE_COUNTER: |
@@ -305,18 +303,19 @@ xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
305 | return; | 303 | return; |
306 | } | 304 | } |
307 | 305 | ||
308 | raw_spin_lock_irqsave(&pmu_lock, flags); | 306 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
309 | val = xscale1pmu_read_pmnc(); | 307 | val = xscale1pmu_read_pmnc(); |
310 | val &= ~mask; | 308 | val &= ~mask; |
311 | val |= evt; | 309 | val |= evt; |
312 | xscale1pmu_write_pmnc(val); | 310 | xscale1pmu_write_pmnc(val); |
313 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 311 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
314 | } | 312 | } |
315 | 313 | ||
316 | static void | 314 | static void |
317 | xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) | 315 | xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) |
318 | { | 316 | { |
319 | unsigned long val, mask, evt, flags; | 317 | unsigned long val, mask, evt, flags; |
318 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
320 | 319 | ||
321 | switch (idx) { | 320 | switch (idx) { |
322 | case XSCALE_CYCLE_COUNTER: | 321 | case XSCALE_CYCLE_COUNTER: |
@@ -336,16 +335,16 @@ xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
336 | return; | 335 | return; |
337 | } | 336 | } |
338 | 337 | ||
339 | raw_spin_lock_irqsave(&pmu_lock, flags); | 338 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
340 | val = xscale1pmu_read_pmnc(); | 339 | val = xscale1pmu_read_pmnc(); |
341 | val &= ~mask; | 340 | val &= ~mask; |
342 | val |= evt; | 341 | val |= evt; |
343 | xscale1pmu_write_pmnc(val); | 342 | xscale1pmu_write_pmnc(val); |
344 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 343 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
345 | } | 344 | } |
346 | 345 | ||
347 | static int | 346 | static int |
348 | xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc, | 347 | xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc, |
349 | struct hw_perf_event *event) | 348 | struct hw_perf_event *event) |
350 | { | 349 | { |
351 | if (XSCALE_PERFCTR_CCNT == event->config_base) { | 350 | if (XSCALE_PERFCTR_CCNT == event->config_base) { |
@@ -368,24 +367,26 @@ static void | |||
368 | xscale1pmu_start(void) | 367 | xscale1pmu_start(void) |
369 | { | 368 | { |
370 | unsigned long flags, val; | 369 | unsigned long flags, val; |
370 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
371 | 371 | ||
372 | raw_spin_lock_irqsave(&pmu_lock, flags); | 372 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
373 | val = xscale1pmu_read_pmnc(); | 373 | val = xscale1pmu_read_pmnc(); |
374 | val |= XSCALE_PMU_ENABLE; | 374 | val |= XSCALE_PMU_ENABLE; |
375 | xscale1pmu_write_pmnc(val); | 375 | xscale1pmu_write_pmnc(val); |
376 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 376 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
377 | } | 377 | } |
378 | 378 | ||
379 | static void | 379 | static void |
380 | xscale1pmu_stop(void) | 380 | xscale1pmu_stop(void) |
381 | { | 381 | { |
382 | unsigned long flags, val; | 382 | unsigned long flags, val; |
383 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
383 | 384 | ||
384 | raw_spin_lock_irqsave(&pmu_lock, flags); | 385 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
385 | val = xscale1pmu_read_pmnc(); | 386 | val = xscale1pmu_read_pmnc(); |
386 | val &= ~XSCALE_PMU_ENABLE; | 387 | val &= ~XSCALE_PMU_ENABLE; |
387 | xscale1pmu_write_pmnc(val); | 388 | xscale1pmu_write_pmnc(val); |
388 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 389 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
389 | } | 390 | } |
390 | 391 | ||
391 | static inline u32 | 392 | static inline u32 |
@@ -424,7 +425,13 @@ xscale1pmu_write_counter(int counter, u32 val) | |||
424 | } | 425 | } |
425 | } | 426 | } |
426 | 427 | ||
427 | static const struct arm_pmu xscale1pmu = { | 428 | static int xscale_map_event(struct perf_event *event) |
429 | { | ||
430 | return map_cpu_event(event, &xscale_perf_map, | ||
431 | &xscale_perf_cache_map, 0xFF); | ||
432 | } | ||
433 | |||
434 | static struct arm_pmu xscale1pmu = { | ||
428 | .id = ARM_PERF_PMU_ID_XSCALE1, | 435 | .id = ARM_PERF_PMU_ID_XSCALE1, |
429 | .name = "xscale1", | 436 | .name = "xscale1", |
430 | .handle_irq = xscale1pmu_handle_irq, | 437 | .handle_irq = xscale1pmu_handle_irq, |
@@ -435,14 +442,12 @@ static const struct arm_pmu xscale1pmu = { | |||
435 | .get_event_idx = xscale1pmu_get_event_idx, | 442 | .get_event_idx = xscale1pmu_get_event_idx, |
436 | .start = xscale1pmu_start, | 443 | .start = xscale1pmu_start, |
437 | .stop = xscale1pmu_stop, | 444 | .stop = xscale1pmu_stop, |
438 | .cache_map = &xscale_perf_cache_map, | 445 | .map_event = xscale_map_event, |
439 | .event_map = &xscale_perf_map, | ||
440 | .raw_event_mask = 0xFF, | ||
441 | .num_events = 3, | 446 | .num_events = 3, |
442 | .max_period = (1LLU << 32) - 1, | 447 | .max_period = (1LLU << 32) - 1, |
443 | }; | 448 | }; |
444 | 449 | ||
445 | static const struct arm_pmu *__init xscale1pmu_init(void) | 450 | static struct arm_pmu *__init xscale1pmu_init(void) |
446 | { | 451 | { |
447 | return &xscale1pmu; | 452 | return &xscale1pmu; |
448 | } | 453 | } |
@@ -560,7 +565,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev) | |||
560 | { | 565 | { |
561 | unsigned long pmnc, of_flags; | 566 | unsigned long pmnc, of_flags; |
562 | struct perf_sample_data data; | 567 | struct perf_sample_data data; |
563 | struct cpu_hw_events *cpuc; | 568 | struct pmu_hw_events *cpuc; |
564 | struct pt_regs *regs; | 569 | struct pt_regs *regs; |
565 | int idx; | 570 | int idx; |
566 | 571 | ||
@@ -581,13 +586,10 @@ xscale2pmu_handle_irq(int irq_num, void *dev) | |||
581 | perf_sample_data_init(&data, 0); | 586 | perf_sample_data_init(&data, 0); |
582 | 587 | ||
583 | cpuc = &__get_cpu_var(cpu_hw_events); | 588 | cpuc = &__get_cpu_var(cpu_hw_events); |
584 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | 589 | for (idx = 0; idx < cpu_pmu->num_events; ++idx) { |
585 | struct perf_event *event = cpuc->events[idx]; | 590 | struct perf_event *event = cpuc->events[idx]; |
586 | struct hw_perf_event *hwc; | 591 | struct hw_perf_event *hwc; |
587 | 592 | ||
588 | if (!test_bit(idx, cpuc->active_mask)) | ||
589 | continue; | ||
590 | |||
591 | if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx)) | 593 | if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx)) |
592 | continue; | 594 | continue; |
593 | 595 | ||
@@ -598,7 +600,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev) | |||
598 | continue; | 600 | continue; |
599 | 601 | ||
600 | if (perf_event_overflow(event, &data, regs)) | 602 | if (perf_event_overflow(event, &data, regs)) |
601 | armpmu->disable(hwc, idx); | 603 | cpu_pmu->disable(hwc, idx); |
602 | } | 604 | } |
603 | 605 | ||
604 | irq_work_run(); | 606 | irq_work_run(); |
@@ -616,6 +618,7 @@ static void | |||
616 | xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) | 618 | xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) |
617 | { | 619 | { |
618 | unsigned long flags, ien, evtsel; | 620 | unsigned long flags, ien, evtsel; |
621 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
619 | 622 | ||
620 | ien = xscale2pmu_read_int_enable(); | 623 | ien = xscale2pmu_read_int_enable(); |
621 | evtsel = xscale2pmu_read_event_select(); | 624 | evtsel = xscale2pmu_read_event_select(); |
@@ -649,16 +652,17 @@ xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
649 | return; | 652 | return; |
650 | } | 653 | } |
651 | 654 | ||
652 | raw_spin_lock_irqsave(&pmu_lock, flags); | 655 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
653 | xscale2pmu_write_event_select(evtsel); | 656 | xscale2pmu_write_event_select(evtsel); |
654 | xscale2pmu_write_int_enable(ien); | 657 | xscale2pmu_write_int_enable(ien); |
655 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 658 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
656 | } | 659 | } |
657 | 660 | ||
658 | static void | 661 | static void |
659 | xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) | 662 | xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) |
660 | { | 663 | { |
661 | unsigned long flags, ien, evtsel; | 664 | unsigned long flags, ien, evtsel; |
665 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
662 | 666 | ||
663 | ien = xscale2pmu_read_int_enable(); | 667 | ien = xscale2pmu_read_int_enable(); |
664 | evtsel = xscale2pmu_read_event_select(); | 668 | evtsel = xscale2pmu_read_event_select(); |
@@ -692,14 +696,14 @@ xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
692 | return; | 696 | return; |
693 | } | 697 | } |
694 | 698 | ||
695 | raw_spin_lock_irqsave(&pmu_lock, flags); | 699 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
696 | xscale2pmu_write_event_select(evtsel); | 700 | xscale2pmu_write_event_select(evtsel); |
697 | xscale2pmu_write_int_enable(ien); | 701 | xscale2pmu_write_int_enable(ien); |
698 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 702 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
699 | } | 703 | } |
700 | 704 | ||
701 | static int | 705 | static int |
702 | xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc, | 706 | xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc, |
703 | struct hw_perf_event *event) | 707 | struct hw_perf_event *event) |
704 | { | 708 | { |
705 | int idx = xscale1pmu_get_event_idx(cpuc, event); | 709 | int idx = xscale1pmu_get_event_idx(cpuc, event); |
@@ -718,24 +722,26 @@ static void | |||
718 | xscale2pmu_start(void) | 722 | xscale2pmu_start(void) |
719 | { | 723 | { |
720 | unsigned long flags, val; | 724 | unsigned long flags, val; |
725 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
721 | 726 | ||
722 | raw_spin_lock_irqsave(&pmu_lock, flags); | 727 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
723 | val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; | 728 | val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; |
724 | val |= XSCALE_PMU_ENABLE; | 729 | val |= XSCALE_PMU_ENABLE; |
725 | xscale2pmu_write_pmnc(val); | 730 | xscale2pmu_write_pmnc(val); |
726 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 731 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
727 | } | 732 | } |
728 | 733 | ||
729 | static void | 734 | static void |
730 | xscale2pmu_stop(void) | 735 | xscale2pmu_stop(void) |
731 | { | 736 | { |
732 | unsigned long flags, val; | 737 | unsigned long flags, val; |
738 | struct pmu_hw_events *events = cpu_pmu->get_hw_events(); | ||
733 | 739 | ||
734 | raw_spin_lock_irqsave(&pmu_lock, flags); | 740 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
735 | val = xscale2pmu_read_pmnc(); | 741 | val = xscale2pmu_read_pmnc(); |
736 | val &= ~XSCALE_PMU_ENABLE; | 742 | val &= ~XSCALE_PMU_ENABLE; |
737 | xscale2pmu_write_pmnc(val); | 743 | xscale2pmu_write_pmnc(val); |
738 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 744 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
739 | } | 745 | } |
740 | 746 | ||
741 | static inline u32 | 747 | static inline u32 |
@@ -786,7 +792,7 @@ xscale2pmu_write_counter(int counter, u32 val) | |||
786 | } | 792 | } |
787 | } | 793 | } |
788 | 794 | ||
789 | static const struct arm_pmu xscale2pmu = { | 795 | static struct arm_pmu xscale2pmu = { |
790 | .id = ARM_PERF_PMU_ID_XSCALE2, | 796 | .id = ARM_PERF_PMU_ID_XSCALE2, |
791 | .name = "xscale2", | 797 | .name = "xscale2", |
792 | .handle_irq = xscale2pmu_handle_irq, | 798 | .handle_irq = xscale2pmu_handle_irq, |
@@ -797,24 +803,22 @@ static const struct arm_pmu xscale2pmu = { | |||
797 | .get_event_idx = xscale2pmu_get_event_idx, | 803 | .get_event_idx = xscale2pmu_get_event_idx, |
798 | .start = xscale2pmu_start, | 804 | .start = xscale2pmu_start, |
799 | .stop = xscale2pmu_stop, | 805 | .stop = xscale2pmu_stop, |
800 | .cache_map = &xscale_perf_cache_map, | 806 | .map_event = xscale_map_event, |
801 | .event_map = &xscale_perf_map, | ||
802 | .raw_event_mask = 0xFF, | ||
803 | .num_events = 5, | 807 | .num_events = 5, |
804 | .max_period = (1LLU << 32) - 1, | 808 | .max_period = (1LLU << 32) - 1, |
805 | }; | 809 | }; |
806 | 810 | ||
807 | static const struct arm_pmu *__init xscale2pmu_init(void) | 811 | static struct arm_pmu *__init xscale2pmu_init(void) |
808 | { | 812 | { |
809 | return &xscale2pmu; | 813 | return &xscale2pmu; |
810 | } | 814 | } |
811 | #else | 815 | #else |
812 | static const struct arm_pmu *__init xscale1pmu_init(void) | 816 | static struct arm_pmu *__init xscale1pmu_init(void) |
813 | { | 817 | { |
814 | return NULL; | 818 | return NULL; |
815 | } | 819 | } |
816 | 820 | ||
817 | static const struct arm_pmu *__init xscale2pmu_init(void) | 821 | static struct arm_pmu *__init xscale2pmu_init(void) |
818 | { | 822 | { |
819 | return NULL; | 823 | return NULL; |
820 | } | 824 | } |
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index 2b70709376c3..2c3407ee8576 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c | |||
@@ -10,192 +10,26 @@ | |||
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) "PMU: " fmt | ||
14 | |||
15 | #include <linux/cpumask.h> | ||
16 | #include <linux/err.h> | 13 | #include <linux/err.h> |
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 15 | #include <linux/module.h> |
20 | #include <linux/of_device.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | 16 | ||
23 | #include <asm/pmu.h> | 17 | #include <asm/pmu.h> |
24 | 18 | ||
25 | static volatile long pmu_lock; | 19 | /* |
26 | 20 | * PMU locking to ensure mutual exclusion between different subsystems. | |
27 | static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES]; | 21 | */ |
28 | 22 | static unsigned long pmu_lock[BITS_TO_LONGS(ARM_NUM_PMU_DEVICES)]; | |
29 | static int __devinit pmu_register(struct platform_device *pdev, | ||
30 | enum arm_pmu_type type) | ||
31 | { | ||
32 | if (type < 0 || type >= ARM_NUM_PMU_DEVICES) { | ||
33 | pr_warning("received registration request for unknown " | ||
34 | "device %d\n", type); | ||
35 | return -EINVAL; | ||
36 | } | ||
37 | |||
38 | if (pmu_devices[type]) { | ||
39 | pr_warning("rejecting duplicate registration of PMU device " | ||
40 | "type %d.", type); | ||
41 | return -ENOSPC; | ||
42 | } | ||
43 | |||
44 | pr_info("registered new PMU device of type %d\n", type); | ||
45 | pmu_devices[type] = pdev; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | #define OF_MATCH_PMU(_name, _type) { \ | ||
50 | .compatible = _name, \ | ||
51 | .data = (void *)_type, \ | ||
52 | } | ||
53 | |||
54 | #define OF_MATCH_CPU(name) OF_MATCH_PMU(name, ARM_PMU_DEVICE_CPU) | ||
55 | |||
56 | static struct of_device_id armpmu_of_device_ids[] = { | ||
57 | OF_MATCH_CPU("arm,cortex-a9-pmu"), | ||
58 | OF_MATCH_CPU("arm,cortex-a8-pmu"), | ||
59 | OF_MATCH_CPU("arm,arm1136-pmu"), | ||
60 | OF_MATCH_CPU("arm,arm1176-pmu"), | ||
61 | {}, | ||
62 | }; | ||
63 | |||
64 | #define PLAT_MATCH_PMU(_name, _type) { \ | ||
65 | .name = _name, \ | ||
66 | .driver_data = _type, \ | ||
67 | } | ||
68 | |||
69 | #define PLAT_MATCH_CPU(_name) PLAT_MATCH_PMU(_name, ARM_PMU_DEVICE_CPU) | ||
70 | |||
71 | static struct platform_device_id armpmu_plat_device_ids[] = { | ||
72 | PLAT_MATCH_CPU("arm-pmu"), | ||
73 | {}, | ||
74 | }; | ||
75 | |||
76 | enum arm_pmu_type armpmu_device_type(struct platform_device *pdev) | ||
77 | { | ||
78 | const struct of_device_id *of_id; | ||
79 | const struct platform_device_id *pdev_id; | ||
80 | |||
81 | /* provided by of_device_id table */ | ||
82 | if (pdev->dev.of_node) { | ||
83 | of_id = of_match_device(armpmu_of_device_ids, &pdev->dev); | ||
84 | BUG_ON(!of_id); | ||
85 | return (enum arm_pmu_type)of_id->data; | ||
86 | } | ||
87 | |||
88 | /* Provided by platform_device_id table */ | ||
89 | pdev_id = platform_get_device_id(pdev); | ||
90 | BUG_ON(!pdev_id); | ||
91 | return pdev_id->driver_data; | ||
92 | } | ||
93 | |||
94 | static int __devinit armpmu_device_probe(struct platform_device *pdev) | ||
95 | { | ||
96 | return pmu_register(pdev, armpmu_device_type(pdev)); | ||
97 | } | ||
98 | |||
99 | static struct platform_driver armpmu_driver = { | ||
100 | .driver = { | ||
101 | .name = "arm-pmu", | ||
102 | .of_match_table = armpmu_of_device_ids, | ||
103 | }, | ||
104 | .probe = armpmu_device_probe, | ||
105 | .id_table = armpmu_plat_device_ids, | ||
106 | }; | ||
107 | |||
108 | static int __init register_pmu_driver(void) | ||
109 | { | ||
110 | return platform_driver_register(&armpmu_driver); | ||
111 | } | ||
112 | device_initcall(register_pmu_driver); | ||
113 | |||
114 | struct platform_device * | ||
115 | reserve_pmu(enum arm_pmu_type device) | ||
116 | { | ||
117 | struct platform_device *pdev; | ||
118 | |||
119 | if (test_and_set_bit_lock(device, &pmu_lock)) { | ||
120 | pdev = ERR_PTR(-EBUSY); | ||
121 | } else if (pmu_devices[device] == NULL) { | ||
122 | clear_bit_unlock(device, &pmu_lock); | ||
123 | pdev = ERR_PTR(-ENODEV); | ||
124 | } else { | ||
125 | pdev = pmu_devices[device]; | ||
126 | } | ||
127 | |||
128 | return pdev; | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(reserve_pmu); | ||
131 | 23 | ||
132 | int | 24 | int |
133 | release_pmu(enum arm_pmu_type device) | 25 | reserve_pmu(enum arm_pmu_type type) |
134 | { | ||
135 | if (WARN_ON(!pmu_devices[device])) | ||
136 | return -EINVAL; | ||
137 | clear_bit_unlock(device, &pmu_lock); | ||
138 | return 0; | ||
139 | } | ||
140 | EXPORT_SYMBOL_GPL(release_pmu); | ||
141 | |||
142 | static int | ||
143 | set_irq_affinity(int irq, | ||
144 | unsigned int cpu) | ||
145 | { | 26 | { |
146 | #ifdef CONFIG_SMP | 27 | return test_and_set_bit_lock(type, pmu_lock) ? -EBUSY : 0; |
147 | int err = irq_set_affinity(irq, cpumask_of(cpu)); | ||
148 | if (err) | ||
149 | pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n", | ||
150 | irq, cpu); | ||
151 | return err; | ||
152 | #else | ||
153 | return -EINVAL; | ||
154 | #endif | ||
155 | } | ||
156 | |||
157 | static int | ||
158 | init_cpu_pmu(void) | ||
159 | { | ||
160 | int i, irqs, err = 0; | ||
161 | struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU]; | ||
162 | |||
163 | if (!pdev) | ||
164 | return -ENODEV; | ||
165 | |||
166 | irqs = pdev->num_resources; | ||
167 | |||
168 | /* | ||
169 | * If we have a single PMU interrupt that we can't shift, assume that | ||
170 | * we're running on a uniprocessor machine and continue. | ||
171 | */ | ||
172 | if (irqs == 1 && !irq_can_set_affinity(platform_get_irq(pdev, 0))) | ||
173 | return 0; | ||
174 | |||
175 | for (i = 0; i < irqs; ++i) { | ||
176 | err = set_irq_affinity(platform_get_irq(pdev, i), i); | ||
177 | if (err) | ||
178 | break; | ||
179 | } | ||
180 | |||
181 | return err; | ||
182 | } | 28 | } |
29 | EXPORT_SYMBOL_GPL(reserve_pmu); | ||
183 | 30 | ||
184 | int | 31 | void |
185 | init_pmu(enum arm_pmu_type device) | 32 | release_pmu(enum arm_pmu_type type) |
186 | { | 33 | { |
187 | int err = 0; | 34 | clear_bit_unlock(type, pmu_lock); |
188 | |||
189 | switch (device) { | ||
190 | case ARM_PMU_DEVICE_CPU: | ||
191 | err = init_cpu_pmu(); | ||
192 | break; | ||
193 | default: | ||
194 | pr_warning("attempt to initialise unknown device %d\n", | ||
195 | device); | ||
196 | err = -EINVAL; | ||
197 | } | ||
198 | |||
199 | return err; | ||
200 | } | 35 | } |
201 | EXPORT_SYMBOL_GPL(init_pmu); | ||
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 9cf4cbf8f95b..d0cdedf4864d 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S | |||
@@ -57,7 +57,8 @@ relocate_new_kernel: | |||
57 | mov r0,#0 | 57 | mov r0,#0 |
58 | ldr r1,kexec_mach_type | 58 | ldr r1,kexec_mach_type |
59 | ldr r2,kexec_boot_atags | 59 | ldr r2,kexec_boot_atags |
60 | mov pc,lr | 60 | ARM( mov pc, lr ) |
61 | THUMB( bx lr ) | ||
61 | 62 | ||
62 | .align | 63 | .align |
63 | 64 | ||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 78d197d6ec34..6136144f8f8d 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -280,18 +280,19 @@ static void __init cacheid_init(void) | |||
280 | if (arch >= CPU_ARCH_ARMv6) { | 280 | if (arch >= CPU_ARCH_ARMv6) { |
281 | if ((cachetype & (7 << 29)) == 4 << 29) { | 281 | if ((cachetype & (7 << 29)) == 4 << 29) { |
282 | /* ARMv7 register format */ | 282 | /* ARMv7 register format */ |
283 | arch = CPU_ARCH_ARMv7; | ||
283 | cacheid = CACHEID_VIPT_NONALIASING; | 284 | cacheid = CACHEID_VIPT_NONALIASING; |
284 | if ((cachetype & (3 << 14)) == 1 << 14) | 285 | if ((cachetype & (3 << 14)) == 1 << 14) |
285 | cacheid |= CACHEID_ASID_TAGGED; | 286 | cacheid |= CACHEID_ASID_TAGGED; |
286 | else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7)) | ||
287 | cacheid |= CACHEID_VIPT_I_ALIASING; | ||
288 | } else if (cachetype & (1 << 23)) { | ||
289 | cacheid = CACHEID_VIPT_ALIASING; | ||
290 | } else { | 287 | } else { |
291 | cacheid = CACHEID_VIPT_NONALIASING; | 288 | arch = CPU_ARCH_ARMv6; |
292 | if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6)) | 289 | if (cachetype & (1 << 23)) |
293 | cacheid |= CACHEID_VIPT_I_ALIASING; | 290 | cacheid = CACHEID_VIPT_ALIASING; |
291 | else | ||
292 | cacheid = CACHEID_VIPT_NONALIASING; | ||
294 | } | 293 | } |
294 | if (cpu_has_aliasing_icache(arch)) | ||
295 | cacheid |= CACHEID_VIPT_I_ALIASING; | ||
295 | } else { | 296 | } else { |
296 | cacheid = CACHEID_VIVT; | 297 | cacheid = CACHEID_VIVT; |
297 | } | 298 | } |
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 2c277d40cee6..01c186222f3b 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c | |||
@@ -137,8 +137,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) | |||
137 | clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); | 137 | clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); |
138 | clk->min_delta_ns = clockevent_delta2ns(0xf, clk); | 138 | clk->min_delta_ns = clockevent_delta2ns(0xf, clk); |
139 | 139 | ||
140 | clockevents_register_device(clk); | ||
141 | |||
140 | /* Make sure our local interrupt controller has this enabled */ | 142 | /* Make sure our local interrupt controller has this enabled */ |
141 | gic_enable_ppi(clk->irq); | 143 | gic_enable_ppi(clk->irq); |
142 | |||
143 | clockevents_register_device(clk); | ||
144 | } | 144 | } |
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index d522b47e30b5..6c8e3b5f669f 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -157,7 +157,7 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
157 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | 157 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), |
158 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | 158 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), |
159 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | 159 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), |
160 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk), | 160 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), |
161 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 161 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), |
162 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 162 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
163 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), | 163 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), |
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 0eabec62cd9d..f1397a13e76b 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * TS72xx memory map: | 6 | * TS72xx memory map: |
7 | * | 7 | * |
8 | * virt phys size | 8 | * virt phys size |
9 | * febff000 22000000 4K model number register | 9 | * febff000 22000000 4K model number register (bits 0-2) |
10 | * febfe000 22400000 4K options register | 10 | * febfe000 22400000 4K options register |
11 | * febfd000 22800000 4K options register #2 | 11 | * febfd000 22800000 4K options register #2 |
12 | * febf9000 10800000 4K TS-5620 RTC index register | 12 | * febf9000 10800000 4K TS-5620 RTC index register |
@@ -20,6 +20,9 @@ | |||
20 | #define TS72XX_MODEL_TS7200 0x00 | 20 | #define TS72XX_MODEL_TS7200 0x00 |
21 | #define TS72XX_MODEL_TS7250 0x01 | 21 | #define TS72XX_MODEL_TS7250 0x01 |
22 | #define TS72XX_MODEL_TS7260 0x02 | 22 | #define TS72XX_MODEL_TS7260 0x02 |
23 | #define TS72XX_MODEL_TS7300 0x03 | ||
24 | #define TS72XX_MODEL_TS7400 0x04 | ||
25 | #define TS72XX_MODEL_MASK 0x07 | ||
23 | 26 | ||
24 | 27 | ||
25 | #define TS72XX_OPTIONS_PHYS_BASE 0x22400000 | 28 | #define TS72XX_OPTIONS_PHYS_BASE 0x22400000 |
@@ -51,19 +54,34 @@ | |||
51 | 54 | ||
52 | #ifndef __ASSEMBLY__ | 55 | #ifndef __ASSEMBLY__ |
53 | 56 | ||
57 | static inline int ts72xx_model(void) | ||
58 | { | ||
59 | return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK; | ||
60 | } | ||
61 | |||
54 | static inline int board_is_ts7200(void) | 62 | static inline int board_is_ts7200(void) |
55 | { | 63 | { |
56 | return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200; | 64 | return ts72xx_model() == TS72XX_MODEL_TS7200; |
57 | } | 65 | } |
58 | 66 | ||
59 | static inline int board_is_ts7250(void) | 67 | static inline int board_is_ts7250(void) |
60 | { | 68 | { |
61 | return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250; | 69 | return ts72xx_model() == TS72XX_MODEL_TS7250; |
62 | } | 70 | } |
63 | 71 | ||
64 | static inline int board_is_ts7260(void) | 72 | static inline int board_is_ts7260(void) |
65 | { | 73 | { |
66 | return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260; | 74 | return ts72xx_model() == TS72XX_MODEL_TS7260; |
75 | } | ||
76 | |||
77 | static inline int board_is_ts7300(void) | ||
78 | { | ||
79 | return ts72xx_model() == TS72XX_MODEL_TS7300; | ||
80 | } | ||
81 | |||
82 | static inline int board_is_ts7400(void) | ||
83 | { | ||
84 | return ts72xx_model() == TS72XX_MODEL_TS7400; | ||
67 | } | 85 | } |
68 | 86 | ||
69 | static inline int is_max197_installed(void) | 87 | static inline int is_max197_installed(void) |
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index 851dea018578..1561b036a9bf 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c | |||
@@ -520,7 +520,7 @@ static struct clk init_clocks_off[] = { | |||
520 | .ctrlbit = (1 << 21), | 520 | .ctrlbit = (1 << 21), |
521 | }, { | 521 | }, { |
522 | .name = "ac97", | 522 | .name = "ac97", |
523 | .id = -1, | 523 | .devname = "samsung-ac97", |
524 | .enable = exynos4_clk_ip_peril_ctrl, | 524 | .enable = exynos4_clk_ip_peril_ctrl, |
525 | .ctrlbit = (1 << 27), | 525 | .ctrlbit = (1 << 27), |
526 | }, { | 526 | }, { |
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 2d8a40c9e6e5..746d6fc6d397 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c | |||
@@ -24,12 +24,13 @@ | |||
24 | #include <plat/exynos4.h> | 24 | #include <plat/exynos4.h> |
25 | #include <plat/adc-core.h> | 25 | #include <plat/adc-core.h> |
26 | #include <plat/sdhci.h> | 26 | #include <plat/sdhci.h> |
27 | #include <plat/devs.h> | ||
28 | #include <plat/fb-core.h> | 27 | #include <plat/fb-core.h> |
29 | #include <plat/fimc-core.h> | 28 | #include <plat/fimc-core.h> |
30 | #include <plat/iic-core.h> | 29 | #include <plat/iic-core.h> |
30 | #include <plat/reset.h> | ||
31 | 31 | ||
32 | #include <mach/regs-irq.h> | 32 | #include <mach/regs-irq.h> |
33 | #include <mach/regs-pmu.h> | ||
33 | 34 | ||
34 | extern int combiner_init(unsigned int combiner_nr, void __iomem *base, | 35 | extern int combiner_init(unsigned int combiner_nr, void __iomem *base, |
35 | unsigned int irq_start); | 36 | unsigned int irq_start); |
@@ -128,6 +129,11 @@ static void exynos4_idle(void) | |||
128 | local_irq_enable(); | 129 | local_irq_enable(); |
129 | } | 130 | } |
130 | 131 | ||
132 | static void exynos4_sw_reset(void) | ||
133 | { | ||
134 | __raw_writel(0x1, S5P_SWRESET); | ||
135 | } | ||
136 | |||
131 | /* | 137 | /* |
132 | * exynos4_map_io | 138 | * exynos4_map_io |
133 | * | 139 | * |
@@ -241,5 +247,8 @@ int __init exynos4_init(void) | |||
241 | /* set idle function */ | 247 | /* set idle function */ |
242 | pm_idle = exynos4_idle; | 248 | pm_idle = exynos4_idle; |
243 | 249 | ||
250 | /* set sw_reset function */ | ||
251 | s5p_reset_hook = exynos4_sw_reset; | ||
252 | |||
244 | return sysdev_register(&exynos4_sysdev); | 253 | return sysdev_register(&exynos4_sysdev); |
245 | } | 254 | } |
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h index 934d2a493982..f8952f8f3757 100644 --- a/arch/arm/mach-exynos4/include/mach/irqs.h +++ b/arch/arm/mach-exynos4/include/mach/irqs.h | |||
@@ -80,9 +80,8 @@ | |||
80 | #define IRQ_HSMMC3 IRQ_SPI(76) | 80 | #define IRQ_HSMMC3 IRQ_SPI(76) |
81 | #define IRQ_DWMCI IRQ_SPI(77) | 81 | #define IRQ_DWMCI IRQ_SPI(77) |
82 | 82 | ||
83 | #define IRQ_MIPICSI0 IRQ_SPI(78) | 83 | #define IRQ_MIPI_CSIS0 IRQ_SPI(78) |
84 | 84 | #define IRQ_MIPI_CSIS1 IRQ_SPI(80) | |
85 | #define IRQ_MIPICSI1 IRQ_SPI(80) | ||
86 | 85 | ||
87 | #define IRQ_ONENAND_AUDI IRQ_SPI(82) | 86 | #define IRQ_ONENAND_AUDI IRQ_SPI(82) |
88 | #define IRQ_ROTATOR IRQ_SPI(83) | 87 | #define IRQ_ROTATOR IRQ_SPI(83) |
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h index fa49bbb8e7b0..cdf9b47c303c 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h | |||
@@ -29,6 +29,8 @@ | |||
29 | #define S5P_USE_STANDBY_WFE1 (1 << 25) | 29 | #define S5P_USE_STANDBY_WFE1 (1 << 25) |
30 | #define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24)) | 30 | #define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24)) |
31 | 31 | ||
32 | #define S5P_SWRESET S5P_PMUREG(0x0400) | ||
33 | |||
32 | #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) | 34 | #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) |
33 | #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) | 35 | #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) |
34 | #define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) | 36 | #define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) |
diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos4/irq-eint.c index 9d87d2ac7f68..badb8c66fc9b 100644 --- a/arch/arm/mach-exynos4/irq-eint.c +++ b/arch/arm/mach-exynos4/irq-eint.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #include <mach/regs-gpio.h> | 24 | #include <mach/regs-gpio.h> |
25 | 25 | ||
26 | #include <asm/mach/irq.h> | ||
27 | |||
26 | static DEFINE_SPINLOCK(eint_lock); | 28 | static DEFINE_SPINLOCK(eint_lock); |
27 | 29 | ||
28 | static unsigned int eint0_15_data[16]; | 30 | static unsigned int eint0_15_data[16]; |
@@ -184,8 +186,11 @@ static inline void exynos4_irq_demux_eint(unsigned int start) | |||
184 | 186 | ||
185 | static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | 187 | static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) |
186 | { | 188 | { |
189 | struct irq_chip *chip = irq_get_chip(irq); | ||
190 | chained_irq_enter(chip, desc); | ||
187 | exynos4_irq_demux_eint(IRQ_EINT(16)); | 191 | exynos4_irq_demux_eint(IRQ_EINT(16)); |
188 | exynos4_irq_demux_eint(IRQ_EINT(24)); | 192 | exynos4_irq_demux_eint(IRQ_EINT(24)); |
193 | chained_irq_exit(chip, desc); | ||
189 | } | 194 | } |
190 | 195 | ||
191 | static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | 196 | static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) |
@@ -193,6 +198,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | |||
193 | u32 *irq_data = irq_get_handler_data(irq); | 198 | u32 *irq_data = irq_get_handler_data(irq); |
194 | struct irq_chip *chip = irq_get_chip(irq); | 199 | struct irq_chip *chip = irq_get_chip(irq); |
195 | 200 | ||
201 | chained_irq_enter(chip, desc); | ||
196 | chip->irq_mask(&desc->irq_data); | 202 | chip->irq_mask(&desc->irq_data); |
197 | 203 | ||
198 | if (chip->irq_ack) | 204 | if (chip->irq_ack) |
@@ -201,6 +207,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | |||
201 | generic_handle_irq(*irq_data); | 207 | generic_handle_irq(*irq_data); |
202 | 208 | ||
203 | chip->irq_unmask(&desc->irq_data); | 209 | chip->irq_unmask(&desc->irq_data); |
210 | chained_irq_exit(chip, desc); | ||
204 | } | 211 | } |
205 | 212 | ||
206 | int __init exynos4_init_irq_eint(void) | 213 | int __init exynos4_init_irq_eint(void) |
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c index d7ec84d586f2..2aac6f755c8e 100644 --- a/arch/arm/mach-exynos4/mach-universal_c210.c +++ b/arch/arm/mach-exynos4/mach-universal_c210.c | |||
@@ -79,7 +79,7 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = { | |||
79 | }; | 79 | }; |
80 | 80 | ||
81 | static struct regulator_consumer_supply max8952_consumer = | 81 | static struct regulator_consumer_supply max8952_consumer = |
82 | REGULATOR_SUPPLY("vddarm", NULL); | 82 | REGULATOR_SUPPLY("vdd_arm", NULL); |
83 | 83 | ||
84 | static struct max8952_platform_data universal_max8952_pdata __initdata = { | 84 | static struct max8952_platform_data universal_max8952_pdata __initdata = { |
85 | .gpio_vid0 = EXYNOS4_GPX0(3), | 85 | .gpio_vid0 = EXYNOS4_GPX0(3), |
@@ -105,7 +105,7 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = { | |||
105 | }; | 105 | }; |
106 | 106 | ||
107 | static struct regulator_consumer_supply lp3974_buck1_consumer = | 107 | static struct regulator_consumer_supply lp3974_buck1_consumer = |
108 | REGULATOR_SUPPLY("vddint", NULL); | 108 | REGULATOR_SUPPLY("vdd_int", NULL); |
109 | 109 | ||
110 | static struct regulator_consumer_supply lp3974_buck2_consumer = | 110 | static struct regulator_consumer_supply lp3974_buck2_consumer = |
111 | REGULATOR_SUPPLY("vddg3d", NULL); | 111 | REGULATOR_SUPPLY("vddg3d", NULL); |
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c index 0883c1b824b9..39aca045f660 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c | |||
@@ -82,7 +82,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev) | |||
82 | 82 | ||
83 | rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); | 83 | rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); |
84 | writel(rstcon, EXYNOS4_RSTCON); | 84 | writel(rstcon, EXYNOS4_RSTCON); |
85 | udelay(50); | 85 | udelay(80); |
86 | 86 | ||
87 | clk_disable(otg_clk); | 87 | clk_disable(otg_clk); |
88 | clk_put(otg_clk); | 88 | clk_put(otg_clk); |
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index dc26fff22cf0..c8e7afcf14ec 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig | |||
@@ -62,6 +62,7 @@ config ARCH_EBSA285_HOST | |||
62 | config ARCH_NETWINDER | 62 | config ARCH_NETWINDER |
63 | bool "NetWinder" | 63 | bool "NetWinder" |
64 | select CLKSRC_I8253 | 64 | select CLKSRC_I8253 |
65 | select CLKEVT_I8253 | ||
65 | select FOOTBRIDGE_HOST | 66 | select FOOTBRIDGE_HOST |
66 | select ISA | 67 | select ISA |
67 | select ISA_DMA | 68 | select ISA_DMA |
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 1331fff51ae2..18c32a5541d9 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
21 | #include <video/vga.h> | ||
21 | 22 | ||
22 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
23 | #include <asm/system.h> | 24 | #include <asm/system.h> |
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 881add0fbe5b..b1ec2cf53bb0 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c | |||
@@ -310,7 +310,7 @@ static struct sys_timer eukrea_cpuimx27_timer = { | |||
310 | .init = eukrea_cpuimx27_timer_init, | 310 | .init = eukrea_cpuimx27_timer_init, |
311 | }; | 311 | }; |
312 | 312 | ||
313 | MACHINE_START(CPUIMX27, "EUKREA CPUIMX27") | 313 | MACHINE_START(EUKREA_CPUIMX27, "EUKREA CPUIMX27") |
314 | .atag_offset = 0x100, | 314 | .atag_offset = 0x100, |
315 | .map_io = mx27_map_io, | 315 | .map_io = mx27_map_io, |
316 | .init_early = imx27_init_early, | 316 | .init_early = imx27_init_early, |
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 10b89139da48..470b654b0e6e 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c | |||
@@ -192,7 +192,7 @@ struct sys_timer eukrea_cpuimx35_timer = { | |||
192 | .init = eukrea_cpuimx35_timer_init, | 192 | .init = eukrea_cpuimx35_timer_init, |
193 | }; | 193 | }; |
194 | 194 | ||
195 | MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35") | 195 | MACHINE_START(EUKREA_CPUIMX35SD, "Eukrea CPUIMX35") |
196 | /* Maintainer: Eukrea Electromatique */ | 196 | /* Maintainer: Eukrea Electromatique */ |
197 | .atag_offset = 0x100, | 197 | .atag_offset = 0x100, |
198 | .map_io = mx35_map_io, | 198 | .map_io = mx35_map_io, |
diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c index d8699b54268d..9163318e95a2 100644 --- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c +++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c | |||
@@ -161,7 +161,7 @@ static struct sys_timer eukrea_cpuimx25_timer = { | |||
161 | .init = eukrea_cpuimx25_timer_init, | 161 | .init = eukrea_cpuimx25_timer_init, |
162 | }; | 162 | }; |
163 | 163 | ||
164 | MACHINE_START(EUKREA_CPUIMX25, "Eukrea CPUIMX25") | 164 | MACHINE_START(EUKREA_CPUIMX25SD, "Eukrea CPUIMX25") |
165 | /* Maintainer: Eukrea Electromatique */ | 165 | /* Maintainer: Eukrea Electromatique */ |
166 | .atag_offset = 0x100, | 166 | .atag_offset = 0x100, |
167 | .map_io = mx25_map_io, | 167 | .map_io = mx25_map_io, |
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index e25f60f5db8f..9e5c1663fc4f 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c | |||
@@ -77,7 +77,7 @@ static int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
77 | /* | 77 | /* |
78 | * Check for devices with hard-wired IRQs. | 78 | * Check for devices with hard-wired IRQs. |
79 | */ | 79 | */ |
80 | irq = orion5x_pci_map_irq(const dev, slot, pin); | 80 | irq = orion5x_pci_map_irq(dev, slot, pin); |
81 | if (irq != -1) | 81 | if (irq != -1) |
82 | return irq; | 82 | return irq; |
83 | 83 | ||
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 28b8760ab9fa..bc4a920e26ee 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/mbus.h> | 16 | #include <linux/mbus.h> |
17 | #include <video/vga.h> | ||
17 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
18 | #include <asm/mach/pci.h> | 19 | #include <asm/mach/pci.h> |
19 | #include <plat/pcie.h> | 20 | #include <plat/pcie.h> |
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h index a30f2e3ec178..6657ff231161 100644 --- a/arch/arm/mach-realview/include/mach/system.h +++ b/arch/arm/mach-realview/include/mach/system.h | |||
@@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd) | |||
44 | */ | 44 | */ |
45 | if (realview_reset) | 45 | if (realview_reset) |
46 | realview_reset(mode); | 46 | realview_reset(mode); |
47 | dsb(); | ||
47 | } | 48 | } |
48 | 49 | ||
49 | #endif | 50 | #endif |
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 8bad64370689..055e2858b0dd 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/suspend.h> | 16 | #include <linux/suspend.h> |
17 | #include <linux/serial_core.h> | 17 | #include <linux/serial_core.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/gpio.h> | ||
19 | 20 | ||
20 | #include <mach/map.h> | 21 | #include <mach/map.h> |
21 | #include <mach/irqs.h> | 22 | #include <mach/irqs.h> |
diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c index 69ed4545112b..fe7380f5c3cd 100644 --- a/arch/arm/mach-s5p64x0/irq-eint.c +++ b/arch/arm/mach-s5p64x0/irq-eint.c | |||
@@ -129,7 +129,7 @@ static int s5p64x0_alloc_gc(void) | |||
129 | } | 129 | } |
130 | 130 | ||
131 | ct = gc->chip_types; | 131 | ct = gc->chip_types; |
132 | ct->chip.irq_ack = irq_gc_ack; | 132 | ct->chip.irq_ack = irq_gc_ack_set_bit; |
133 | ct->chip.irq_mask = irq_gc_mask_set_bit; | 133 | ct->chip.irq_mask = irq_gc_mask_set_bit; |
134 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | 134 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; |
135 | ct->chip.irq_set_type = s5p64x0_irq_eint_set_type; | 135 | ct->chip.irq_set_type = s5p64x0_irq_eint_set_type; |
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 309e388a8a83..f149d278377b 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c | |||
@@ -88,7 +88,7 @@ static struct sleep_save s5pv210_core_save[] = { | |||
88 | SAVE_ITEM(S3C2410_TCNTO(0)), | 88 | SAVE_ITEM(S3C2410_TCNTO(0)), |
89 | }; | 89 | }; |
90 | 90 | ||
91 | void s5pv210_cpu_suspend(unsigned long arg) | 91 | static int s5pv210_cpu_suspend(unsigned long arg) |
92 | { | 92 | { |
93 | unsigned long tmp; | 93 | unsigned long tmp; |
94 | 94 | ||
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 167a67c5ca54..5fde49da399a 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c | |||
@@ -342,6 +342,7 @@ static struct platform_device mipidsi0_device = { | |||
342 | static struct sh_mobile_sdhi_info sdhi0_info = { | 342 | static struct sh_mobile_sdhi_info sdhi0_info = { |
343 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 343 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
344 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 344 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
345 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, | ||
345 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, | 346 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, |
346 | .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, | 347 | .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, |
347 | }; | 348 | }; |
@@ -383,7 +384,7 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) | |||
383 | } | 384 | } |
384 | 385 | ||
385 | static struct sh_mobile_sdhi_info sh_sdhi1_info = { | 386 | static struct sh_mobile_sdhi_info sh_sdhi1_info = { |
386 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, | 387 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, |
387 | .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, | 388 | .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, |
388 | .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 389 | .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
389 | .set_pwr = ag5evm_sdhi1_set_pwr, | 390 | .set_pwr = ag5evm_sdhi1_set_pwr, |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index e7c5379069ef..de2253d7f157 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -642,6 +642,8 @@ static struct usbhs_private usbhs0_private = { | |||
642 | }, | 642 | }, |
643 | .driver_param = { | 643 | .driver_param = { |
644 | .buswait_bwait = 4, | 644 | .buswait_bwait = 4, |
645 | .d0_tx_id = SHDMA_SLAVE_USB0_TX, | ||
646 | .d1_rx_id = SHDMA_SLAVE_USB0_RX, | ||
645 | }, | 647 | }, |
646 | }, | 648 | }, |
647 | }; | 649 | }; |
@@ -811,6 +813,8 @@ static struct usbhs_private usbhs1_private = { | |||
811 | .buswait_bwait = 4, | 813 | .buswait_bwait = 4, |
812 | .pipe_type = usbhs1_pipe_cfg, | 814 | .pipe_type = usbhs1_pipe_cfg, |
813 | .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg), | 815 | .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg), |
816 | .d0_tx_id = SHDMA_SLAVE_USB1_TX, | ||
817 | .d1_rx_id = SHDMA_SLAVE_USB1_RX, | ||
814 | }, | 818 | }, |
815 | }, | 819 | }, |
816 | }; | 820 | }; |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index e6e11e4e2d43..66975921e646 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -503,16 +503,17 @@ static struct clk *late_main_clks[] = { | |||
503 | &sh7372_fsidivb_clk, | 503 | &sh7372_fsidivb_clk, |
504 | }; | 504 | }; |
505 | 505 | ||
506 | enum { MSTP001, | 506 | enum { MSTP001, MSTP000, |
507 | MSTP131, MSTP130, | 507 | MSTP131, MSTP130, |
508 | MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, | 508 | MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, |
509 | MSTP118, MSTP117, MSTP116, MSTP113, | 509 | MSTP118, MSTP117, MSTP116, MSTP113, |
510 | MSTP106, MSTP101, MSTP100, | 510 | MSTP106, MSTP101, MSTP100, |
511 | MSTP223, | 511 | MSTP223, |
512 | MSTP218, MSTP217, MSTP216, | 512 | MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207, |
513 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 513 | MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
514 | MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, | 514 | MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, |
515 | MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, | 515 | MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406, |
516 | MSTP405, MSTP404, MSTP403, MSTP400, | ||
516 | MSTP_NR }; | 517 | MSTP_NR }; |
517 | 518 | ||
518 | #define MSTP(_parent, _reg, _bit, _flags) \ | 519 | #define MSTP(_parent, _reg, _bit, _flags) \ |
@@ -520,6 +521,7 @@ enum { MSTP001, | |||
520 | 521 | ||
521 | static struct clk mstp_clks[MSTP_NR] = { | 522 | static struct clk mstp_clks[MSTP_NR] = { |
522 | [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ | 523 | [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ |
524 | [MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */ | ||
523 | [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ | 525 | [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ |
524 | [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ | 526 | [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ |
525 | [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ | 527 | [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ |
@@ -538,14 +540,16 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
538 | [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ | 540 | [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ |
539 | [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ | 541 | [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ |
540 | [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ | 542 | [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ |
543 | [MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */ | ||
544 | [MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */ | ||
541 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | 545 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ |
542 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | 546 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ |
547 | [MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */ | ||
543 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | 548 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ |
544 | [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ | 549 | [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ |
545 | [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ | 550 | [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ |
546 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ | 551 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ |
547 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ | 552 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ |
548 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ | ||
549 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ | 553 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ |
550 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ | 554 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ |
551 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ | 555 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ |
@@ -557,8 +561,12 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
557 | [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */ | 561 | [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */ |
558 | [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ | 562 | [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ |
559 | [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ | 563 | [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ |
564 | [MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */ | ||
560 | [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ | 565 | [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ |
566 | [MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */ | ||
567 | [MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */ | ||
561 | [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ | 568 | [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ |
569 | [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */ | ||
562 | }; | 570 | }; |
563 | 571 | ||
564 | static struct clk_lookup lookups[] = { | 572 | static struct clk_lookup lookups[] = { |
@@ -609,6 +617,7 @@ static struct clk_lookup lookups[] = { | |||
609 | 617 | ||
610 | /* MSTP32 clocks */ | 618 | /* MSTP32 clocks */ |
611 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ | 619 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ |
620 | CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */ | ||
612 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ | 621 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ |
613 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ | 622 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ |
614 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ | 623 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ |
@@ -629,14 +638,16 @@ static struct clk_lookup lookups[] = { | |||
629 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */ | 638 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */ |
630 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */ | 639 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */ |
631 | CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */ | 640 | CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */ |
641 | CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */ | ||
642 | CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */ | ||
632 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ | 643 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ |
633 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ | 644 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ |
645 | CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */ | ||
634 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ | 646 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ |
635 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ | 647 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ |
636 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ | 648 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ |
637 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ | 649 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ |
638 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ | 650 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ |
639 | CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ | ||
640 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ | 651 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ |
641 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ | 652 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ |
642 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ | 653 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ |
@@ -650,10 +661,14 @@ static struct clk_lookup lookups[] = { | |||
650 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ | 661 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ |
651 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ | 662 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ |
652 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ | 663 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ |
664 | CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */ | ||
653 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ | 665 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ |
654 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ | 666 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ |
655 | CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */ | 667 | CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */ |
668 | CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */ | ||
669 | CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */ | ||
656 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ | 670 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ |
671 | CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */ | ||
657 | 672 | ||
658 | CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1", | 673 | CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1", |
659 | &div6_reparent_clks[DIV6_HDMI]), | 674 | &div6_reparent_clks[DIV6_HDMI]), |
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 6db2ccabc2bf..61a846bb30f2 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c | |||
@@ -365,7 +365,7 @@ void __init sh73a0_clock_init(void) | |||
365 | __raw_writel(0x108, SD2CKCR); | 365 | __raw_writel(0x108, SD2CKCR); |
366 | 366 | ||
367 | /* detect main clock parent */ | 367 | /* detect main clock parent */ |
368 | switch ((__raw_readl(CKSCR) >> 24) & 0x03) { | 368 | switch ((__raw_readl(CKSCR) >> 28) & 0x03) { |
369 | case 0: | 369 | case 0: |
370 | main_clk.parent = &sh73a0_extal1_clk; | 370 | main_clk.parent = &sh73a0_extal1_clk; |
371 | break; | 371 | break; |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index ce595cee86cd..24e63a85e669 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -459,6 +459,10 @@ enum { | |||
459 | SHDMA_SLAVE_SDHI2_TX, | 459 | SHDMA_SLAVE_SDHI2_TX, |
460 | SHDMA_SLAVE_MMCIF_RX, | 460 | SHDMA_SLAVE_MMCIF_RX, |
461 | SHDMA_SLAVE_MMCIF_TX, | 461 | SHDMA_SLAVE_MMCIF_TX, |
462 | SHDMA_SLAVE_USB0_TX, | ||
463 | SHDMA_SLAVE_USB0_RX, | ||
464 | SHDMA_SLAVE_USB1_TX, | ||
465 | SHDMA_SLAVE_USB1_RX, | ||
462 | }; | 466 | }; |
463 | 467 | ||
464 | extern struct clk sh7372_extal1_clk; | 468 | extern struct clk sh7372_extal1_clk; |
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 3b28743c77eb..739315e30eb9 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c | |||
@@ -379,7 +379,7 @@ enum { | |||
379 | /* BBIF2 */ | 379 | /* BBIF2 */ |
380 | VPU, | 380 | VPU, |
381 | TSIF1, | 381 | TSIF1, |
382 | _3DG_SGX530, | 382 | /* 3DG */ |
383 | _2DDMAC, | 383 | _2DDMAC, |
384 | IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, | 384 | IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, |
385 | IPMMU_IPMMUR, IPMMU_IPMMUR2, | 385 | IPMMU_IPMMUR, IPMMU_IPMMUR2, |
@@ -436,7 +436,7 @@ static struct intc_vect intcs_vectors[] = { | |||
436 | /* BBIF2 */ | 436 | /* BBIF2 */ |
437 | INTCS_VECT(VPU, 0x980), | 437 | INTCS_VECT(VPU, 0x980), |
438 | INTCS_VECT(TSIF1, 0x9a0), | 438 | INTCS_VECT(TSIF1, 0x9a0), |
439 | INTCS_VECT(_3DG_SGX530, 0x9e0), | 439 | /* 3DG */ |
440 | INTCS_VECT(_2DDMAC, 0xa00), | 440 | INTCS_VECT(_2DDMAC, 0xa00), |
441 | INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), | 441 | INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), |
442 | INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), | 442 | INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), |
@@ -521,7 +521,7 @@ static struct intc_mask_reg intcs_mask_registers[] = { | |||
521 | RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, | 521 | RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, |
522 | { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ | 522 | { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ |
523 | { 0, 0, MSIOF, 0, | 523 | { 0, 0, MSIOF, 0, |
524 | _3DG_SGX530, 0, 0, 0 } }, | 524 | 0, 0, 0, 0 } }, |
525 | { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ | 525 | { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ |
526 | { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, | 526 | { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, |
527 | 0, 0, 0, 0 } }, | 527 | 0, 0, 0, 0 } }, |
@@ -561,7 +561,6 @@ static struct intc_prio_reg intcs_prio_registers[] = { | |||
561 | TMU_TUNI2, TSIF1 } }, | 561 | TMU_TUNI2, TSIF1 } }, |
562 | { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } }, | 562 | { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } }, |
563 | { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } }, | 563 | { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } }, |
564 | { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } }, | ||
565 | { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } }, | 564 | { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } }, |
566 | { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } }, | 565 | { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } }, |
567 | { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, | 566 | { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, |
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 79f0413d8725..2d9b1b1a2538 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -169,35 +169,35 @@ static struct platform_device scif6_device = { | |||
169 | }; | 169 | }; |
170 | 170 | ||
171 | /* CMT */ | 171 | /* CMT */ |
172 | static struct sh_timer_config cmt10_platform_data = { | 172 | static struct sh_timer_config cmt2_platform_data = { |
173 | .name = "CMT10", | 173 | .name = "CMT2", |
174 | .channel_offset = 0x10, | 174 | .channel_offset = 0x40, |
175 | .timer_bit = 0, | 175 | .timer_bit = 5, |
176 | .clockevent_rating = 125, | 176 | .clockevent_rating = 125, |
177 | .clocksource_rating = 125, | 177 | .clocksource_rating = 125, |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static struct resource cmt10_resources[] = { | 180 | static struct resource cmt2_resources[] = { |
181 | [0] = { | 181 | [0] = { |
182 | .name = "CMT10", | 182 | .name = "CMT2", |
183 | .start = 0xe6138010, | 183 | .start = 0xe6130040, |
184 | .end = 0xe613801b, | 184 | .end = 0xe613004b, |
185 | .flags = IORESOURCE_MEM, | 185 | .flags = IORESOURCE_MEM, |
186 | }, | 186 | }, |
187 | [1] = { | 187 | [1] = { |
188 | .start = evt2irq(0x0b00), /* CMT1_CMT10 */ | 188 | .start = evt2irq(0x0b80), /* CMT2 */ |
189 | .flags = IORESOURCE_IRQ, | 189 | .flags = IORESOURCE_IRQ, |
190 | }, | 190 | }, |
191 | }; | 191 | }; |
192 | 192 | ||
193 | static struct platform_device cmt10_device = { | 193 | static struct platform_device cmt2_device = { |
194 | .name = "sh_cmt", | 194 | .name = "sh_cmt", |
195 | .id = 10, | 195 | .id = 2, |
196 | .dev = { | 196 | .dev = { |
197 | .platform_data = &cmt10_platform_data, | 197 | .platform_data = &cmt2_platform_data, |
198 | }, | 198 | }, |
199 | .resource = cmt10_resources, | 199 | .resource = cmt2_resources, |
200 | .num_resources = ARRAY_SIZE(cmt10_resources), | 200 | .num_resources = ARRAY_SIZE(cmt2_resources), |
201 | }; | 201 | }; |
202 | 202 | ||
203 | /* TMU */ | 203 | /* TMU */ |
@@ -602,6 +602,150 @@ static struct platform_device dma2_device = { | |||
602 | }, | 602 | }, |
603 | }; | 603 | }; |
604 | 604 | ||
605 | /* | ||
606 | * USB-DMAC | ||
607 | */ | ||
608 | |||
609 | unsigned int usbts_shift[] = {3, 4, 5}; | ||
610 | |||
611 | enum { | ||
612 | XMIT_SZ_8BYTE = 0, | ||
613 | XMIT_SZ_16BYTE = 1, | ||
614 | XMIT_SZ_32BYTE = 2, | ||
615 | }; | ||
616 | |||
617 | #define USBTS_INDEX2VAL(i) (((i) & 3) << 6) | ||
618 | |||
619 | static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = { | ||
620 | { | ||
621 | .offset = 0, | ||
622 | }, { | ||
623 | .offset = 0x20, | ||
624 | }, | ||
625 | }; | ||
626 | |||
627 | /* USB DMAC0 */ | ||
628 | static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = { | ||
629 | { | ||
630 | .slave_id = SHDMA_SLAVE_USB0_TX, | ||
631 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | ||
632 | }, { | ||
633 | .slave_id = SHDMA_SLAVE_USB0_RX, | ||
634 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | ||
635 | }, | ||
636 | }; | ||
637 | |||
638 | static struct sh_dmae_pdata usb_dma0_platform_data = { | ||
639 | .slave = sh7372_usb_dmae0_slaves, | ||
640 | .slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves), | ||
641 | .channel = sh7372_usb_dmae_channels, | ||
642 | .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), | ||
643 | .ts_low_shift = 6, | ||
644 | .ts_low_mask = 0xc0, | ||
645 | .ts_high_shift = 0, | ||
646 | .ts_high_mask = 0, | ||
647 | .ts_shift = usbts_shift, | ||
648 | .ts_shift_num = ARRAY_SIZE(usbts_shift), | ||
649 | .dmaor_init = DMAOR_DME, | ||
650 | .chcr_offset = 0x14, | ||
651 | .chcr_ie_bit = 1 << 5, | ||
652 | .dmaor_is_32bit = 1, | ||
653 | .needs_tend_set = 1, | ||
654 | .no_dmars = 1, | ||
655 | }; | ||
656 | |||
657 | static struct resource sh7372_usb_dmae0_resources[] = { | ||
658 | { | ||
659 | /* Channel registers and DMAOR */ | ||
660 | .start = 0xe68a0020, | ||
661 | .end = 0xe68a0064 - 1, | ||
662 | .flags = IORESOURCE_MEM, | ||
663 | }, | ||
664 | { | ||
665 | /* VCR/SWR/DMICR */ | ||
666 | .start = 0xe68a0000, | ||
667 | .end = 0xe68a0014 - 1, | ||
668 | .flags = IORESOURCE_MEM, | ||
669 | }, | ||
670 | { | ||
671 | /* IRQ for channels */ | ||
672 | .start = evt2irq(0x0a00), | ||
673 | .end = evt2irq(0x0a00), | ||
674 | .flags = IORESOURCE_IRQ, | ||
675 | }, | ||
676 | }; | ||
677 | |||
678 | static struct platform_device usb_dma0_device = { | ||
679 | .name = "sh-dma-engine", | ||
680 | .id = 3, | ||
681 | .resource = sh7372_usb_dmae0_resources, | ||
682 | .num_resources = ARRAY_SIZE(sh7372_usb_dmae0_resources), | ||
683 | .dev = { | ||
684 | .platform_data = &usb_dma0_platform_data, | ||
685 | }, | ||
686 | }; | ||
687 | |||
688 | /* USB DMAC1 */ | ||
689 | static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = { | ||
690 | { | ||
691 | .slave_id = SHDMA_SLAVE_USB1_TX, | ||
692 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | ||
693 | }, { | ||
694 | .slave_id = SHDMA_SLAVE_USB1_RX, | ||
695 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | ||
696 | }, | ||
697 | }; | ||
698 | |||
699 | static struct sh_dmae_pdata usb_dma1_platform_data = { | ||
700 | .slave = sh7372_usb_dmae1_slaves, | ||
701 | .slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves), | ||
702 | .channel = sh7372_usb_dmae_channels, | ||
703 | .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), | ||
704 | .ts_low_shift = 6, | ||
705 | .ts_low_mask = 0xc0, | ||
706 | .ts_high_shift = 0, | ||
707 | .ts_high_mask = 0, | ||
708 | .ts_shift = usbts_shift, | ||
709 | .ts_shift_num = ARRAY_SIZE(usbts_shift), | ||
710 | .dmaor_init = DMAOR_DME, | ||
711 | .chcr_offset = 0x14, | ||
712 | .chcr_ie_bit = 1 << 5, | ||
713 | .dmaor_is_32bit = 1, | ||
714 | .needs_tend_set = 1, | ||
715 | .no_dmars = 1, | ||
716 | }; | ||
717 | |||
718 | static struct resource sh7372_usb_dmae1_resources[] = { | ||
719 | { | ||
720 | /* Channel registers and DMAOR */ | ||
721 | .start = 0xe68c0020, | ||
722 | .end = 0xe68c0064 - 1, | ||
723 | .flags = IORESOURCE_MEM, | ||
724 | }, | ||
725 | { | ||
726 | /* VCR/SWR/DMICR */ | ||
727 | .start = 0xe68c0000, | ||
728 | .end = 0xe68c0014 - 1, | ||
729 | .flags = IORESOURCE_MEM, | ||
730 | }, | ||
731 | { | ||
732 | /* IRQ for channels */ | ||
733 | .start = evt2irq(0x1d00), | ||
734 | .end = evt2irq(0x1d00), | ||
735 | .flags = IORESOURCE_IRQ, | ||
736 | }, | ||
737 | }; | ||
738 | |||
739 | static struct platform_device usb_dma1_device = { | ||
740 | .name = "sh-dma-engine", | ||
741 | .id = 4, | ||
742 | .resource = sh7372_usb_dmae1_resources, | ||
743 | .num_resources = ARRAY_SIZE(sh7372_usb_dmae1_resources), | ||
744 | .dev = { | ||
745 | .platform_data = &usb_dma1_platform_data, | ||
746 | }, | ||
747 | }; | ||
748 | |||
605 | /* VPU */ | 749 | /* VPU */ |
606 | static struct uio_info vpu_platform_data = { | 750 | static struct uio_info vpu_platform_data = { |
607 | .name = "VPU5HG", | 751 | .name = "VPU5HG", |
@@ -818,7 +962,7 @@ static struct platform_device *sh7372_early_devices[] __initdata = { | |||
818 | &scif4_device, | 962 | &scif4_device, |
819 | &scif5_device, | 963 | &scif5_device, |
820 | &scif6_device, | 964 | &scif6_device, |
821 | &cmt10_device, | 965 | &cmt2_device, |
822 | &tmu00_device, | 966 | &tmu00_device, |
823 | &tmu01_device, | 967 | &tmu01_device, |
824 | }; | 968 | }; |
@@ -829,6 +973,8 @@ static struct platform_device *sh7372_late_devices[] __initdata = { | |||
829 | &dma0_device, | 973 | &dma0_device, |
830 | &dma1_device, | 974 | &dma1_device, |
831 | &dma2_device, | 975 | &dma2_device, |
976 | &usb_dma0_device, | ||
977 | &usb_dma1_device, | ||
832 | &vpu_device, | 978 | &vpu_device, |
833 | &veu0_device, | 979 | &veu0_device, |
834 | &veu1_device, | 980 | &veu1_device, |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index de72058180a6..1fafc3244607 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -318,6 +318,10 @@ static struct clk v2m_sp804_clk = { | |||
318 | .rate = 1000000, | 318 | .rate = 1000000, |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static struct clk v2m_ref_clk = { | ||
322 | .rate = 32768, | ||
323 | }; | ||
324 | |||
321 | static struct clk dummy_apb_pclk; | 325 | static struct clk dummy_apb_pclk; |
322 | 326 | ||
323 | static struct clk_lookup v2m_lookups[] = { | 327 | static struct clk_lookup v2m_lookups[] = { |
@@ -348,6 +352,9 @@ static struct clk_lookup v2m_lookups[] = { | |||
348 | }, { /* CLCD */ | 352 | }, { /* CLCD */ |
349 | .dev_id = "mb:clcd", | 353 | .dev_id = "mb:clcd", |
350 | .clk = &osc1_clk, | 354 | .clk = &osc1_clk, |
355 | }, { /* SP805 WDT */ | ||
356 | .dev_id = "mb:wdt", | ||
357 | .clk = &v2m_ref_clk, | ||
351 | }, { /* SP804 timers */ | 358 | }, { /* SP804 timers */ |
352 | .dev_id = "sp804", | 359 | .dev_id = "sp804", |
353 | .con_id = "v2m-timer0", | 360 | .con_id = "v2m-timer0", |
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 92bd102e3982..2e6849b41f66 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S | |||
@@ -379,7 +379,7 @@ ENTRY(cpu_arm920_set_pte_ext) | |||
379 | 379 | ||
380 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ | 380 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ |
381 | .globl cpu_arm920_suspend_size | 381 | .globl cpu_arm920_suspend_size |
382 | .equ cpu_arm920_suspend_size, 4 * 3 | 382 | .equ cpu_arm920_suspend_size, 4 * 4 |
383 | #ifdef CONFIG_PM_SLEEP | 383 | #ifdef CONFIG_PM_SLEEP |
384 | ENTRY(cpu_arm920_do_suspend) | 384 | ENTRY(cpu_arm920_do_suspend) |
385 | stmfd sp!, {r4 - r7, lr} | 385 | stmfd sp!, {r4 - r7, lr} |
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 2bbcf053dffd..cd8f79c3a282 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S | |||
@@ -394,7 +394,7 @@ ENTRY(cpu_arm926_set_pte_ext) | |||
394 | 394 | ||
395 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ | 395 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ |
396 | .globl cpu_arm926_suspend_size | 396 | .globl cpu_arm926_suspend_size |
397 | .equ cpu_arm926_suspend_size, 4 * 3 | 397 | .equ cpu_arm926_suspend_size, 4 * 4 |
398 | #ifdef CONFIG_PM_SLEEP | 398 | #ifdef CONFIG_PM_SLEEP |
399 | ENTRY(cpu_arm926_do_suspend) | 399 | ENTRY(cpu_arm926_do_suspend) |
400 | stmfd sp!, {r4 - r7, lr} | 400 | stmfd sp!, {r4 - r7, lr} |
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 07219c2ae114..69e7f2ef7384 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S | |||
@@ -182,11 +182,11 @@ ENDPROC(cpu_sa1100_do_suspend) | |||
182 | 182 | ||
183 | ENTRY(cpu_sa1100_do_resume) | 183 | ENTRY(cpu_sa1100_do_resume) |
184 | ldmia r0, {r4 - r7} @ load cp regs | 184 | ldmia r0, {r4 - r7} @ load cp regs |
185 | mov r1, #0 | 185 | mov ip, #0 |
186 | mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs | 186 | mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs |
187 | mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache | 187 | mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache |
188 | mcr p15, 0, r1, c9, c0, 0 @ invalidate RB | 188 | mcr p15, 0, ip, c9, c0, 0 @ invalidate RB |
189 | mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB | 189 | mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB |
190 | 190 | ||
191 | mcr p15, 0, r4, c3, c0, 0 @ domain ID | 191 | mcr p15, 0, r4, c3, c0, 0 @ domain ID |
192 | mcr p15, 0, r5, c2, c0, 0 @ translation table base addr | 192 | mcr p15, 0, r5, c2, c0, 0 @ translation table base addr |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 219138d2f158..a923aa0fd00d 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -223,6 +223,22 @@ __v6_setup: | |||
223 | mrc p15, 0, r0, c1, c0, 0 @ read control register | 223 | mrc p15, 0, r0, c1, c0, 0 @ read control register |
224 | bic r0, r0, r5 @ clear bits them | 224 | bic r0, r0, r5 @ clear bits them |
225 | orr r0, r0, r6 @ set them | 225 | orr r0, r0, r6 @ set them |
226 | #ifdef CONFIG_ARM_ERRATA_364296 | ||
227 | /* | ||
228 | * Workaround for the 364296 ARM1136 r0p2 erratum (possible cache data | ||
229 | * corruption with hit-under-miss enabled). The conditional code below | ||
230 | * (setting the undocumented bit 31 in the auxiliary control register | ||
231 | * and the FI bit in the control register) disables hit-under-miss | ||
232 | * without putting the processor into full low interrupt latency mode. | ||
233 | */ | ||
234 | ldr r6, =0x4107b362 @ id for ARM1136 r0p2 | ||
235 | mrc p15, 0, r5, c0, c0, 0 @ get processor id | ||
236 | teq r5, r6 @ check for the faulty core | ||
237 | mrceq p15, 0, r5, c1, c0, 1 @ load aux control reg | ||
238 | orreq r5, r5, #(1 << 31) @ set the undocumented bit 31 | ||
239 | mcreq p15, 0, r5, c1, c0, 1 @ write aux control reg | ||
240 | orreq r0, r0, #(1 << 21) @ low interrupt latency configuration | ||
241 | #endif | ||
226 | mov pc, lr @ return to head.S:__ret | 242 | mov pc, lr @ return to head.S:__ret |
227 | 243 | ||
228 | /* | 244 | /* |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index a30e78542ccf..9049c0764db2 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -66,6 +66,7 @@ ENDPROC(cpu_v7_proc_fin) | |||
66 | ENTRY(cpu_v7_reset) | 66 | ENTRY(cpu_v7_reset) |
67 | mrc p15, 0, r1, c1, c0, 0 @ ctrl register | 67 | mrc p15, 0, r1, c1, c0, 0 @ ctrl register |
68 | bic r1, r1, #0x1 @ ...............m | 68 | bic r1, r1, #0x1 @ ...............m |
69 | THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions) | ||
69 | mcr p15, 0, r1, c1, c0, 0 @ disable MMU | 70 | mcr p15, 0, r1, c1, c0, 0 @ disable MMU |
70 | isb | 71 | isb |
71 | mov pc, r0 | 72 | mov pc, r0 |
@@ -247,13 +248,16 @@ ENTRY(cpu_v7_do_resume) | |||
247 | mcr p15, 0, r7, c2, c0, 0 @ TTB 0 | 248 | mcr p15, 0, r7, c2, c0, 0 @ TTB 0 |
248 | mcr p15, 0, r8, c2, c0, 1 @ TTB 1 | 249 | mcr p15, 0, r8, c2, c0, 1 @ TTB 1 |
249 | mcr p15, 0, ip, c2, c0, 2 @ TTB control register | 250 | mcr p15, 0, ip, c2, c0, 2 @ TTB control register |
250 | mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register | 251 | mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register |
252 | teq r4, r10 @ Is it already set? | ||
253 | mcrne p15, 0, r10, c1, c0, 1 @ No, so write it | ||
251 | mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control | 254 | mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control |
252 | ldr r4, =PRRR @ PRRR | 255 | ldr r4, =PRRR @ PRRR |
253 | ldr r5, =NMRR @ NMRR | 256 | ldr r5, =NMRR @ NMRR |
254 | mcr p15, 0, r4, c10, c2, 0 @ write PRRR | 257 | mcr p15, 0, r4, c10, c2, 0 @ write PRRR |
255 | mcr p15, 0, r5, c10, c2, 1 @ write NMRR | 258 | mcr p15, 0, r5, c10, c2, 1 @ write NMRR |
256 | isb | 259 | isb |
260 | dsb | ||
257 | mov r0, r9 @ control register | 261 | mov r0, r9 @ control register |
258 | mov r2, r7, lsr #14 @ get TTB0 base | 262 | mov r2, r7, lsr #14 @ get TTB0 base |
259 | mov r2, r2, lsl #14 | 263 | mov r2, r2, lsl #14 |
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 28c72a2006a1..755e1bf22681 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S | |||
@@ -406,7 +406,7 @@ ENTRY(cpu_xsc3_set_pte_ext) | |||
406 | .align | 406 | .align |
407 | 407 | ||
408 | .globl cpu_xsc3_suspend_size | 408 | .globl cpu_xsc3_suspend_size |
409 | .equ cpu_xsc3_suspend_size, 4 * 8 | 409 | .equ cpu_xsc3_suspend_size, 4 * 7 |
410 | #ifdef CONFIG_PM_SLEEP | 410 | #ifdef CONFIG_PM_SLEEP |
411 | ENTRY(cpu_xsc3_do_suspend) | 411 | ENTRY(cpu_xsc3_do_suspend) |
412 | stmfd sp!, {r4 - r10, lr} | 412 | stmfd sp!, {r4 - r10, lr} |
@@ -418,12 +418,12 @@ ENTRY(cpu_xsc3_do_suspend) | |||
418 | mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg | 418 | mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg |
419 | mrc p15, 0, r10, c1, c0, 0 @ control reg | 419 | mrc p15, 0, r10, c1, c0, 0 @ control reg |
420 | bic r4, r4, #2 @ clear frequency change bit | 420 | bic r4, r4, #2 @ clear frequency change bit |
421 | stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs | 421 | stmia r0, {r4 - r10} @ store cp regs |
422 | ldmia sp!, {r4 - r10, pc} | 422 | ldmia sp!, {r4 - r10, pc} |
423 | ENDPROC(cpu_xsc3_do_suspend) | 423 | ENDPROC(cpu_xsc3_do_suspend) |
424 | 424 | ||
425 | ENTRY(cpu_xsc3_do_resume) | 425 | ENTRY(cpu_xsc3_do_resume) |
426 | ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs | 426 | ldmia r0, {r4 - r10} @ load cp regs |
427 | mov ip, #0 | 427 | mov ip, #0 |
428 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB | 428 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB |
429 | mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer | 429 | mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer |
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 02af235298e2..5f84a3f13ef9 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c | |||
@@ -192,7 +192,7 @@ unsigned long s5p_spdif_get_rate(struct clk *clk) | |||
192 | if (IS_ERR(pclk)) | 192 | if (IS_ERR(pclk)) |
193 | return -EINVAL; | 193 | return -EINVAL; |
194 | 194 | ||
195 | rate = pclk->ops->get_rate(clk); | 195 | rate = pclk->ops->get_rate(pclk); |
196 | clk_put(pclk); | 196 | clk_put(pclk); |
197 | 197 | ||
198 | return rate; | 198 | return rate; |
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 327ab9f662e8..f71078ef6bb5 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <plat/gpio-core.h> | 23 | #include <plat/gpio-core.h> |
24 | #include <plat/gpio-cfg.h> | 24 | #include <plat/gpio-cfg.h> |
25 | 25 | ||
26 | #include <asm/mach/irq.h> | ||
27 | |||
26 | #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) | 28 | #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) |
27 | 29 | ||
28 | #define CON_OFFSET 0x700 | 30 | #define CON_OFFSET 0x700 |
@@ -81,6 +83,9 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | |||
81 | int group, pend_offset, mask_offset; | 83 | int group, pend_offset, mask_offset; |
82 | unsigned int pend, mask; | 84 | unsigned int pend, mask; |
83 | 85 | ||
86 | struct irq_chip *chip = irq_get_chip(irq); | ||
87 | chained_irq_enter(chip, desc); | ||
88 | |||
84 | for (group = 0; group < bank->nr_groups; group++) { | 89 | for (group = 0; group < bank->nr_groups; group++) { |
85 | struct s3c_gpio_chip *chip = bank->chips[group]; | 90 | struct s3c_gpio_chip *chip = bank->chips[group]; |
86 | if (!chip) | 91 | if (!chip) |
@@ -102,6 +107,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | |||
102 | pend &= ~BIT(offset); | 107 | pend &= ~BIT(offset); |
103 | } | 108 | } |
104 | } | 109 | } |
110 | chained_irq_exit(chip, desc); | ||
105 | } | 111 | } |
106 | 112 | ||
107 | static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) | 113 | static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) |
diff --git a/arch/arm/plat-samsung/include/plat/backlight.h b/arch/arm/plat-samsung/include/plat/backlight.h index 51d8da846a62..ad530c78fe8c 100644 --- a/arch/arm/plat-samsung/include/plat/backlight.h +++ b/arch/arm/plat-samsung/include/plat/backlight.h | |||
@@ -20,7 +20,7 @@ struct samsung_bl_gpio_info { | |||
20 | int func; | 20 | int func; |
21 | }; | 21 | }; |
22 | 22 | ||
23 | extern void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, | 23 | extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, |
24 | struct platform_pwm_backlight_data *bl_data); | 24 | struct platform_pwm_backlight_data *bl_data); |
25 | 25 | ||
26 | #endif /* __ASM_PLAT_BACKLIGHT_H */ | 26 | #endif /* __ASM_PLAT_BACKLIGHT_H */ |
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index f714d060370d..51583cd30164 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c | |||
@@ -22,9 +22,14 @@ | |||
22 | #include <plat/irq-vic-timer.h> | 22 | #include <plat/irq-vic-timer.h> |
23 | #include <plat/regs-timer.h> | 23 | #include <plat/regs-timer.h> |
24 | 24 | ||
25 | #include <asm/mach/irq.h> | ||
26 | |||
25 | static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) | 27 | static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) |
26 | { | 28 | { |
29 | struct irq_chip *chip = irq_get_chip(irq); | ||
30 | chained_irq_enter(chip, desc); | ||
27 | generic_handle_irq((int)desc->irq_data.handler_data); | 31 | generic_handle_irq((int)desc->irq_data.handler_data); |
32 | chained_irq_exit(chip, desc); | ||
28 | } | 33 | } |
29 | 34 | ||
30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ | 35 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index fff68d0d521b..62cc8f981171 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -351,7 +351,7 @@ centro MACH_CENTRO CENTRO 1944 | |||
351 | nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955 | 351 | nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955 |
352 | omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967 | 352 | omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967 |
353 | cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 | 353 | cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 |
354 | eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 | 354 | eukrea_cpuimx27 MACH_EUKREA_CPUIMX27 EUKREA_CPUIMX27 1975 |
355 | acs5k MACH_ACS5K ACS5K 1982 | 355 | acs5k MACH_ACS5K ACS5K 1982 |
356 | snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987 | 356 | snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987 |
357 | dsm320 MACH_DSM320 DSM320 1988 | 357 | dsm320 MACH_DSM320 DSM320 1988 |
@@ -476,8 +476,8 @@ cns3420vb MACH_CNS3420VB CNS3420VB 2776 | |||
476 | omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791 | 476 | omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791 |
477 | ti8168evm MACH_TI8168EVM TI8168EVM 2800 | 477 | ti8168evm MACH_TI8168EVM TI8168EVM 2800 |
478 | teton_bga MACH_TETON_BGA TETON_BGA 2816 | 478 | teton_bga MACH_TETON_BGA TETON_BGA 2816 |
479 | eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820 | 479 | eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25SD EUKREA_CPUIMX25SD 2820 |
480 | eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821 | 480 | eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821 |
481 | eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822 | 481 | eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822 |
482 | eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823 | 482 | eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823 |
483 | smdkc210 MACH_SMDKC210 SMDKC210 2838 | 483 | smdkc210 MACH_SMDKC210 SMDKC210 2838 |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index e66366fd2abc..3735abd7f8f6 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -259,7 +259,7 @@ | |||
259 | ENTRY_SAME(ni_syscall) /* query_module */ | 259 | ENTRY_SAME(ni_syscall) /* query_module */ |
260 | ENTRY_SAME(poll) | 260 | ENTRY_SAME(poll) |
261 | /* structs contain pointers and an in_addr... */ | 261 | /* structs contain pointers and an in_addr... */ |
262 | ENTRY_COMP(nfsservctl) | 262 | ENTRY_SAME(ni_syscall) /* was nfsservctl */ |
263 | ENTRY_SAME(setresgid) /* 170 */ | 263 | ENTRY_SAME(setresgid) /* 170 */ |
264 | ENTRY_SAME(getresgid) | 264 | ENTRY_SAME(getresgid) |
265 | ENTRY_SAME(prctl) | 265 | ENTRY_SAME(prctl) |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index f6736b7da463..fa0d27a400de 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -171,7 +171,7 @@ SYSCALL_SPU(setresuid) | |||
171 | SYSCALL_SPU(getresuid) | 171 | SYSCALL_SPU(getresuid) |
172 | SYSCALL(ni_syscall) | 172 | SYSCALL(ni_syscall) |
173 | SYSCALL_SPU(poll) | 173 | SYSCALL_SPU(poll) |
174 | COMPAT_SYS(nfsservctl) | 174 | SYSCALL(ni_syscall) |
175 | SYSCALL_SPU(setresgid) | 175 | SYSCALL_SPU(setresgid) |
176 | SYSCALL_SPU(getresgid) | 176 | SYSCALL_SPU(getresgid) |
177 | COMPAT_SYS_SPU(prctl) | 177 | COMPAT_SYS_SPU(prctl) |
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index b97baf81a87b..2d3679b2447f 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h | |||
@@ -123,7 +123,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, | |||
123 | struct perf_event; | 123 | struct perf_event; |
124 | struct perf_sample_data; | 124 | struct perf_sample_data; |
125 | 125 | ||
126 | extern void ptrace_triggered(struct perf_event *bp, int nmi, | 126 | extern void ptrace_triggered(struct perf_event *bp, |
127 | struct perf_sample_data *data, struct pt_regs *regs); | 127 | struct perf_sample_data *data, struct pt_regs *regs); |
128 | 128 | ||
129 | #define task_pt_regs(task) \ | 129 | #define task_pt_regs(task) \ |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index e915deafac89..05559295d2ca 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/serial_sci.h> | 15 | #include <linux/serial_sci.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/sh_timer.h> | 19 | #include <linux/sh_timer.h> |
19 | #include <linux/sh_dma.h> | 20 | #include <linux/sh_dma.h> |
20 | 21 | ||
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 32114e0941ae..db4ecd731a00 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/atomic.h> | 22 | #include <linux/atomic.h> |
23 | #include <asm/smp.h> | 23 | #include <asm/smp.h> |
24 | 24 | ||
25 | static void (*pm_idle)(void); | 25 | void (*pm_idle)(void); |
26 | 26 | ||
27 | static int hlt_counter; | 27 | static int hlt_counter; |
28 | 28 | ||
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index d9006f8ffc14..7bbef95c9d1b 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c | |||
@@ -316,6 +316,35 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs, | |||
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | break; | 318 | break; |
319 | |||
320 | case 9: /* mov.w @(disp,PC),Rn */ | ||
321 | srcu = (unsigned char __user *)regs->pc; | ||
322 | srcu += 4; | ||
323 | srcu += (instruction & 0x00FF) << 1; | ||
324 | dst = (unsigned char *)rn; | ||
325 | *(unsigned long *)dst = 0; | ||
326 | |||
327 | #if !defined(__LITTLE_ENDIAN__) | ||
328 | dst += 2; | ||
329 | #endif | ||
330 | |||
331 | if (ma->from(dst, srcu, 2)) | ||
332 | goto fetch_fault; | ||
333 | sign_extend(2, dst); | ||
334 | ret = 0; | ||
335 | break; | ||
336 | |||
337 | case 0xd: /* mov.l @(disp,PC),Rn */ | ||
338 | srcu = (unsigned char __user *)(regs->pc & ~0x3); | ||
339 | srcu += 4; | ||
340 | srcu += (instruction & 0x00FF) << 2; | ||
341 | dst = (unsigned char *)rn; | ||
342 | *(unsigned long *)dst = 0; | ||
343 | |||
344 | if (ma->from(dst, srcu, 4)) | ||
345 | goto fetch_fault; | ||
346 | ret = 0; | ||
347 | break; | ||
319 | } | 348 | } |
320 | return ret; | 349 | return ret; |
321 | 350 | ||
@@ -466,6 +495,7 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, | |||
466 | case 0x0500: /* mov.w @(disp,Rm),R0 */ | 495 | case 0x0500: /* mov.w @(disp,Rm),R0 */ |
467 | goto simple; | 496 | goto simple; |
468 | case 0x0B00: /* bf lab - no delayslot*/ | 497 | case 0x0B00: /* bf lab - no delayslot*/ |
498 | ret = 0; | ||
469 | break; | 499 | break; |
470 | case 0x0F00: /* bf/s lab */ | 500 | case 0x0F00: /* bf/s lab */ |
471 | ret = handle_delayslot(regs, instruction, ma); | 501 | ret = handle_delayslot(regs, instruction, ma); |
@@ -479,6 +509,7 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, | |||
479 | } | 509 | } |
480 | break; | 510 | break; |
481 | case 0x0900: /* bt lab - no delayslot */ | 511 | case 0x0900: /* bt lab - no delayslot */ |
512 | ret = 0; | ||
482 | break; | 513 | break; |
483 | case 0x0D00: /* bt/s lab */ | 514 | case 0x0D00: /* bt/s lab */ |
484 | ret = handle_delayslot(regs, instruction, ma); | 515 | ret = handle_delayslot(regs, instruction, ma); |
@@ -494,6 +525,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, | |||
494 | } | 525 | } |
495 | break; | 526 | break; |
496 | 527 | ||
528 | case 0x9000: /* mov.w @(disp,Rm),Rn */ | ||
529 | goto simple; | ||
530 | |||
497 | case 0xA000: /* bra label */ | 531 | case 0xA000: /* bra label */ |
498 | ret = handle_delayslot(regs, instruction, ma); | 532 | ret = handle_delayslot(regs, instruction, ma); |
499 | if (ret==0) | 533 | if (ret==0) |
@@ -507,6 +541,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, | |||
507 | regs->pc += SH_PC_12BIT_OFFSET(instruction); | 541 | regs->pc += SH_PC_12BIT_OFFSET(instruction); |
508 | } | 542 | } |
509 | break; | 543 | break; |
544 | |||
545 | case 0xD000: /* mov.l @(disp,Rm),Rn */ | ||
546 | goto simple; | ||
510 | } | 547 | } |
511 | return ret; | 548 | return ret; |
512 | 549 | ||
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 100b9c204e78..42851122bbd9 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h | |||
@@ -88,7 +88,7 @@ BTFIXUPDEF_CALL(void, set_irq_udt, int) | |||
88 | #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) | 88 | #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) |
89 | 89 | ||
90 | /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ | 90 | /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ |
91 | #define SUN4D_IPI_IRQ 14 | 91 | #define SUN4D_IPI_IRQ 13 |
92 | 92 | ||
93 | extern void sun4d_ipi_interrupt(void); | 93 | extern void sun4d_ipi_interrupt(void); |
94 | 94 | ||
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index c9296ab0b1f4..edbec45d4688 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -68,7 +68,7 @@ sys_call_table32: | |||
68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall | 68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall |
69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler | 69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler |
70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep | 70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep |
71 | /*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl | 71 | /*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys_nis_syscall |
72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep | 72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep |
73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun | 73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun |
74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy | 74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 873e2e4ac55f..73b7b1a18fab 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -15,6 +15,7 @@ MODULE_LICENSE("GPL"); | |||
15 | static int bcma_bus_match(struct device *dev, struct device_driver *drv); | 15 | static int bcma_bus_match(struct device *dev, struct device_driver *drv); |
16 | static int bcma_device_probe(struct device *dev); | 16 | static int bcma_device_probe(struct device *dev); |
17 | static int bcma_device_remove(struct device *dev); | 17 | static int bcma_device_remove(struct device *dev); |
18 | static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env); | ||
18 | 19 | ||
19 | static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) | 20 | static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) |
20 | { | 21 | { |
@@ -49,6 +50,7 @@ static struct bus_type bcma_bus_type = { | |||
49 | .match = bcma_bus_match, | 50 | .match = bcma_bus_match, |
50 | .probe = bcma_device_probe, | 51 | .probe = bcma_device_probe, |
51 | .remove = bcma_device_remove, | 52 | .remove = bcma_device_remove, |
53 | .uevent = bcma_device_uevent, | ||
52 | .dev_attrs = bcma_device_attrs, | 54 | .dev_attrs = bcma_device_attrs, |
53 | }; | 55 | }; |
54 | 56 | ||
@@ -227,6 +229,16 @@ static int bcma_device_remove(struct device *dev) | |||
227 | return 0; | 229 | return 0; |
228 | } | 230 | } |
229 | 231 | ||
232 | static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
233 | { | ||
234 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); | ||
235 | |||
236 | return add_uevent_var(env, | ||
237 | "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X", | ||
238 | core->id.manuf, core->id.id, | ||
239 | core->id.rev, core->id.class); | ||
240 | } | ||
241 | |||
230 | static int __init bcma_modinit(void) | 242 | static int __init bcma_modinit(void) |
231 | { | 243 | { |
232 | int err; | 244 | int err; |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a5854735bb2e..db7cb8111fbe 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { | |||
63 | /* Atheros AR3011 with sflash firmware*/ | 63 | /* Atheros AR3011 with sflash firmware*/ |
64 | { USB_DEVICE(0x0CF3, 0x3002) }, | 64 | { USB_DEVICE(0x0CF3, 0x3002) }, |
65 | { USB_DEVICE(0x13d3, 0x3304) }, | 65 | { USB_DEVICE(0x13d3, 0x3304) }, |
66 | { USB_DEVICE(0x0930, 0x0215) }, | ||
66 | 67 | ||
67 | /* Atheros AR9285 Malbec with sflash firmware */ | 68 | /* Atheros AR9285 Malbec with sflash firmware */ |
68 | { USB_DEVICE(0x03F0, 0x311D) }, | 69 | { USB_DEVICE(0x03F0, 0x311D) }, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 91d13a9e8c65..3ef476070baf 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = { | |||
106 | /* Atheros 3011 with sflash firmware */ | 106 | /* Atheros 3011 with sflash firmware */ |
107 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | 107 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, |
108 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, | 108 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, |
109 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, | ||
109 | 110 | ||
110 | /* Atheros AR9285 Malbec with sflash firmware */ | 111 | /* Atheros AR9285 Malbec with sflash firmware */ |
111 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | 112 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
@@ -256,7 +257,9 @@ static void btusb_intr_complete(struct urb *urb) | |||
256 | 257 | ||
257 | err = usb_submit_urb(urb, GFP_ATOMIC); | 258 | err = usb_submit_urb(urb, GFP_ATOMIC); |
258 | if (err < 0) { | 259 | if (err < 0) { |
259 | if (err != -EPERM) | 260 | /* -EPERM: urb is being killed; |
261 | * -ENODEV: device got disconnected */ | ||
262 | if (err != -EPERM && err != -ENODEV) | ||
260 | BT_ERR("%s urb %p failed to resubmit (%d)", | 263 | BT_ERR("%s urb %p failed to resubmit (%d)", |
261 | hdev->name, urb, -err); | 264 | hdev->name, urb, -err); |
262 | usb_unanchor_urb(urb); | 265 | usb_unanchor_urb(urb); |
@@ -341,7 +344,9 @@ static void btusb_bulk_complete(struct urb *urb) | |||
341 | 344 | ||
342 | err = usb_submit_urb(urb, GFP_ATOMIC); | 345 | err = usb_submit_urb(urb, GFP_ATOMIC); |
343 | if (err < 0) { | 346 | if (err < 0) { |
344 | if (err != -EPERM) | 347 | /* -EPERM: urb is being killed; |
348 | * -ENODEV: device got disconnected */ | ||
349 | if (err != -EPERM && err != -ENODEV) | ||
345 | BT_ERR("%s urb %p failed to resubmit (%d)", | 350 | BT_ERR("%s urb %p failed to resubmit (%d)", |
346 | hdev->name, urb, -err); | 351 | hdev->name, urb, -err); |
347 | usb_unanchor_urb(urb); | 352 | usb_unanchor_urb(urb); |
@@ -431,7 +436,9 @@ static void btusb_isoc_complete(struct urb *urb) | |||
431 | 436 | ||
432 | err = usb_submit_urb(urb, GFP_ATOMIC); | 437 | err = usb_submit_urb(urb, GFP_ATOMIC); |
433 | if (err < 0) { | 438 | if (err < 0) { |
434 | if (err != -EPERM) | 439 | /* -EPERM: urb is being killed; |
440 | * -ENODEV: device got disconnected */ | ||
441 | if (err != -EPERM && err != -ENODEV) | ||
435 | BT_ERR("%s urb %p failed to resubmit (%d)", | 442 | BT_ERR("%s urb %p failed to resubmit (%d)", |
436 | hdev->name, urb, -err); | 443 | hdev->name, urb, -err); |
437 | usb_unanchor_urb(urb); | 444 | usb_unanchor_urb(urb); |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index dc7c033ef587..32a77becc098 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/delay.h> | ||
29 | #include <linux/clocksource.h> | 30 | #include <linux/clocksource.h> |
30 | #include <linux/clockchips.h> | 31 | #include <linux/clockchips.h> |
31 | #include <linux/sh_timer.h> | 32 | #include <linux/sh_timer.h> |
@@ -150,13 +151,13 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) | |||
150 | 151 | ||
151 | static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) | 152 | static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) |
152 | { | 153 | { |
153 | int ret; | 154 | int k, ret; |
154 | 155 | ||
155 | /* enable clock */ | 156 | /* enable clock */ |
156 | ret = clk_enable(p->clk); | 157 | ret = clk_enable(p->clk); |
157 | if (ret) { | 158 | if (ret) { |
158 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | 159 | dev_err(&p->pdev->dev, "cannot enable clock\n"); |
159 | return ret; | 160 | goto err0; |
160 | } | 161 | } |
161 | 162 | ||
162 | /* make sure channel is disabled */ | 163 | /* make sure channel is disabled */ |
@@ -174,9 +175,38 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) | |||
174 | sh_cmt_write(p, CMCOR, 0xffffffff); | 175 | sh_cmt_write(p, CMCOR, 0xffffffff); |
175 | sh_cmt_write(p, CMCNT, 0); | 176 | sh_cmt_write(p, CMCNT, 0); |
176 | 177 | ||
178 | /* | ||
179 | * According to the sh73a0 user's manual, as CMCNT can be operated | ||
180 | * only by the RCLK (Pseudo 32 KHz), there's one restriction on | ||
181 | * modifying CMCNT register; two RCLK cycles are necessary before | ||
182 | * this register is either read or any modification of the value | ||
183 | * it holds is reflected in the LSI's actual operation. | ||
184 | * | ||
185 | * While at it, we're supposed to clear out the CMCNT as of this | ||
186 | * moment, so make sure it's processed properly here. This will | ||
187 | * take RCLKx2 at maximum. | ||
188 | */ | ||
189 | for (k = 0; k < 100; k++) { | ||
190 | if (!sh_cmt_read(p, CMCNT)) | ||
191 | break; | ||
192 | udelay(1); | ||
193 | } | ||
194 | |||
195 | if (sh_cmt_read(p, CMCNT)) { | ||
196 | dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); | ||
197 | ret = -ETIMEDOUT; | ||
198 | goto err1; | ||
199 | } | ||
200 | |||
177 | /* enable channel */ | 201 | /* enable channel */ |
178 | sh_cmt_start_stop_ch(p, 1); | 202 | sh_cmt_start_stop_ch(p, 1); |
179 | return 0; | 203 | return 0; |
204 | err1: | ||
205 | /* stop clock */ | ||
206 | clk_disable(p->clk); | ||
207 | |||
208 | err0: | ||
209 | return ret; | ||
180 | } | 210 | } |
181 | 211 | ||
182 | static void sh_cmt_disable(struct sh_cmt_priv *p) | 212 | static void sh_cmt_disable(struct sh_cmt_priv *p) |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f7bbde9eb2cb..a81249246ece 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
@@ -503,9 +503,9 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
503 | spin_unlock_irqrestore(&priv->mbx_lock, flags); | 503 | spin_unlock_irqrestore(&priv->mbx_lock, flags); |
504 | 504 | ||
505 | /* Prepare mailbox for transmission */ | 505 | /* Prepare mailbox for transmission */ |
506 | data = cf->can_dlc | (get_tx_head_prio(priv) << 8); | ||
506 | if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */ | 507 | if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */ |
507 | data |= HECC_CANMCF_RTR; | 508 | data |= HECC_CANMCF_RTR; |
508 | data |= get_tx_head_prio(priv) << 8; | ||
509 | hecc_write_mbx(priv, mbxno, HECC_CANMCF, data); | 509 | hecc_write_mbx(priv, mbxno, HECC_CANMCF, data); |
510 | 510 | ||
511 | if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ | 511 | if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ |
@@ -923,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev) | |||
923 | priv->can.do_get_state = ti_hecc_get_state; | 923 | priv->can.do_get_state = ti_hecc_get_state; |
924 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 924 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; |
925 | 925 | ||
926 | spin_lock_init(&priv->mbx_lock); | ||
926 | ndev->irq = irq->start; | 927 | ndev->irq = irq->start; |
927 | ndev->flags |= IFF_ECHO; | 928 | ndev->flags |= IFF_ECHO; |
928 | platform_set_drvdata(pdev, ndev); | 929 | platform_set_drvdata(pdev, ndev); |
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 646c86bcc545..fdb7a1756409 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
@@ -2452,14 +2452,13 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id) | |||
2452 | struct net_device *dev = dev_id; | 2452 | struct net_device *dev = dev_id; |
2453 | struct cas *cp = netdev_priv(dev); | 2453 | struct cas *cp = netdev_priv(dev); |
2454 | unsigned long flags; | 2454 | unsigned long flags; |
2455 | int ring; | 2455 | int ring = (irq == cp->pci_irq_INTC) ? 2 : 3; |
2456 | u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring)); | 2456 | u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring)); |
2457 | 2457 | ||
2458 | /* check for shared irq */ | 2458 | /* check for shared irq */ |
2459 | if (status == 0) | 2459 | if (status == 0) |
2460 | return IRQ_NONE; | 2460 | return IRQ_NONE; |
2461 | 2461 | ||
2462 | ring = (irq == cp->pci_irq_INTC) ? 2 : 3; | ||
2463 | spin_lock_irqsave(&cp->lock, flags); | 2462 | spin_lock_irqsave(&cp->lock, flags); |
2464 | if (status & INTR_RX_DONE_ALT) { /* handle rx separately */ | 2463 | if (status & INTR_RX_DONE_ALT) { /* handle rx separately */ |
2465 | #ifdef USE_NAPI | 2464 | #ifdef USE_NAPI |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ba99af05bf62..3e6679269400 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -395,7 +395,7 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada | |||
395 | } | 395 | } |
396 | 396 | ||
397 | /* recycle the current buffer on the rx queue */ | 397 | /* recycle the current buffer on the rx queue */ |
398 | static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) | 398 | static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) |
399 | { | 399 | { |
400 | u32 q_index = adapter->rx_queue.index; | 400 | u32 q_index = adapter->rx_queue.index; |
401 | u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator; | 401 | u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator; |
@@ -403,6 +403,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) | |||
403 | unsigned int index = correlator & 0xffffffffUL; | 403 | unsigned int index = correlator & 0xffffffffUL; |
404 | union ibmveth_buf_desc desc; | 404 | union ibmveth_buf_desc desc; |
405 | unsigned long lpar_rc; | 405 | unsigned long lpar_rc; |
406 | int ret = 1; | ||
406 | 407 | ||
407 | BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); | 408 | BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); |
408 | BUG_ON(index >= adapter->rx_buff_pool[pool].size); | 409 | BUG_ON(index >= adapter->rx_buff_pool[pool].size); |
@@ -410,7 +411,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) | |||
410 | if (!adapter->rx_buff_pool[pool].active) { | 411 | if (!adapter->rx_buff_pool[pool].active) { |
411 | ibmveth_rxq_harvest_buffer(adapter); | 412 | ibmveth_rxq_harvest_buffer(adapter); |
412 | ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); | 413 | ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); |
413 | return; | 414 | goto out; |
414 | } | 415 | } |
415 | 416 | ||
416 | desc.fields.flags_len = IBMVETH_BUF_VALID | | 417 | desc.fields.flags_len = IBMVETH_BUF_VALID | |
@@ -423,12 +424,16 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) | |||
423 | netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " | 424 | netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " |
424 | "during recycle rc=%ld", lpar_rc); | 425 | "during recycle rc=%ld", lpar_rc); |
425 | ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); | 426 | ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); |
427 | ret = 0; | ||
426 | } | 428 | } |
427 | 429 | ||
428 | if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { | 430 | if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { |
429 | adapter->rx_queue.index = 0; | 431 | adapter->rx_queue.index = 0; |
430 | adapter->rx_queue.toggle = !adapter->rx_queue.toggle; | 432 | adapter->rx_queue.toggle = !adapter->rx_queue.toggle; |
431 | } | 433 | } |
434 | |||
435 | out: | ||
436 | return ret; | ||
432 | } | 437 | } |
433 | 438 | ||
434 | static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) | 439 | static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) |
@@ -1084,8 +1089,9 @@ restart_poll: | |||
1084 | if (rx_flush) | 1089 | if (rx_flush) |
1085 | ibmveth_flush_buffer(skb->data, | 1090 | ibmveth_flush_buffer(skb->data, |
1086 | length + offset); | 1091 | length + offset); |
1092 | if (!ibmveth_rxq_recycle_buffer(adapter)) | ||
1093 | kfree_skb(skb); | ||
1087 | skb = new_skb; | 1094 | skb = new_skb; |
1088 | ibmveth_rxq_recycle_buffer(adapter); | ||
1089 | } else { | 1095 | } else { |
1090 | ibmveth_rxq_harvest_buffer(adapter); | 1096 | ibmveth_rxq_harvest_buffer(adapter); |
1091 | skb_reserve(skb, offset); | 1097 | skb_reserve(skb, offset); |
diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index 0620ba963508..04bb8fcc0cb5 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c | |||
@@ -25,8 +25,9 @@ | |||
25 | /* DP83865 phy identifier values */ | 25 | /* DP83865 phy identifier values */ |
26 | #define DP83865_PHY_ID 0x20005c7a | 26 | #define DP83865_PHY_ID 0x20005c7a |
27 | 27 | ||
28 | #define DP83865_INT_MASK_REG 0x15 | 28 | #define DP83865_INT_STATUS 0x14 |
29 | #define DP83865_INT_MASK_STATUS 0x14 | 29 | #define DP83865_INT_MASK 0x15 |
30 | #define DP83865_INT_CLEAR 0x17 | ||
30 | 31 | ||
31 | #define DP83865_INT_REMOTE_FAULT 0x0008 | 32 | #define DP83865_INT_REMOTE_FAULT 0x0008 |
32 | #define DP83865_INT_ANE_COMPLETED 0x0010 | 33 | #define DP83865_INT_ANE_COMPLETED 0x0010 |
@@ -68,21 +69,25 @@ static int ns_config_intr(struct phy_device *phydev) | |||
68 | int err; | 69 | int err; |
69 | 70 | ||
70 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | 71 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
71 | err = phy_write(phydev, DP83865_INT_MASK_REG, | 72 | err = phy_write(phydev, DP83865_INT_MASK, |
72 | DP83865_INT_MASK_DEFAULT); | 73 | DP83865_INT_MASK_DEFAULT); |
73 | else | 74 | else |
74 | err = phy_write(phydev, DP83865_INT_MASK_REG, 0); | 75 | err = phy_write(phydev, DP83865_INT_MASK, 0); |
75 | 76 | ||
76 | return err; | 77 | return err; |
77 | } | 78 | } |
78 | 79 | ||
79 | static int ns_ack_interrupt(struct phy_device *phydev) | 80 | static int ns_ack_interrupt(struct phy_device *phydev) |
80 | { | 81 | { |
81 | int ret = phy_read(phydev, DP83865_INT_MASK_STATUS); | 82 | int ret = phy_read(phydev, DP83865_INT_STATUS); |
82 | if (ret < 0) | 83 | if (ret < 0) |
83 | return ret; | 84 | return ret; |
84 | 85 | ||
85 | return 0; | 86 | /* Clear the interrupt status bit by writing a “1” |
87 | * to the corresponding bit in INT_CLEAR (2:0 are reserved) */ | ||
88 | ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7); | ||
89 | |||
90 | return ret; | ||
86 | } | 91 | } |
87 | 92 | ||
88 | static void ns_giga_speed_fallback(struct phy_device *phydev, int mode) | 93 | static void ns_giga_speed_fallback(struct phy_device *phydev, int mode) |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 190f619e4215..1c1666e99106 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/phy.h> | 31 | #include <linux/phy.h> |
32 | #include <linux/cache.h> | 32 | #include <linux/cache.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/interrupt.h> | ||
34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
35 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
36 | #include <linux/ethtool.h> | 37 | #include <linux/ethtool.h> |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c34bef1bf2b0..1b9400371eaf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(int32_t x, | |||
69 | static const struct ar9300_eeprom ar9300_default = { | 69 | static const struct ar9300_eeprom ar9300_default = { |
70 | .eepromVersion = 2, | 70 | .eepromVersion = 2, |
71 | .templateVersion = 2, | 71 | .templateVersion = 2, |
72 | .macAddr = {1, 2, 3, 4, 5, 6}, | 72 | .macAddr = {0, 2, 3, 4, 5, 6}, |
73 | .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 73 | .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
74 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | 74 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
75 | .baseEepHeader = { | 75 | .baseEepHeader = { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9098aaad97a9..6530694a59ae 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -2283,7 +2283,11 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
2283 | 2283 | ||
2284 | mutex_lock(&sc->mutex); | 2284 | mutex_lock(&sc->mutex); |
2285 | ah->coverage_class = coverage_class; | 2285 | ah->coverage_class = coverage_class; |
2286 | |||
2287 | ath9k_ps_wakeup(sc); | ||
2286 | ath9k_hw_init_global_settings(ah); | 2288 | ath9k_hw_init_global_settings(ah); |
2289 | ath9k_ps_restore(sc); | ||
2290 | |||
2287 | mutex_unlock(&sc->mutex); | 2291 | mutex_unlock(&sc->mutex); |
2288 | } | 2292 | } |
2289 | 2293 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 0122930b14c7..0474e6638d21 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1066,8 +1066,10 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1066 | * the high througput speed in 802.11n networks. | 1066 | * the high througput speed in 802.11n networks. |
1067 | */ | 1067 | */ |
1068 | 1068 | ||
1069 | if (!is_main_vif(ar, vif)) | 1069 | if (!is_main_vif(ar, vif)) { |
1070 | mutex_lock(&ar->mutex); | ||
1070 | goto err_softw; | 1071 | goto err_softw; |
1072 | } | ||
1071 | 1073 | ||
1072 | /* | 1074 | /* |
1073 | * While the hardware supports *catch-all* key, for offloading | 1075 | * While the hardware supports *catch-all* key, for offloading |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 7fbb55c9da82..1e31050dafc9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -871,18 +871,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state) | |||
871 | { | 871 | { |
872 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); | 872 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); |
873 | struct rt2x00_dev *rt2x00dev = hw->priv; | 873 | struct rt2x00_dev *rt2x00dev = hw->priv; |
874 | int retval; | ||
875 | |||
876 | retval = rt2x00lib_suspend(rt2x00dev, state); | ||
877 | if (retval) | ||
878 | return retval; | ||
879 | 874 | ||
880 | /* | 875 | return rt2x00lib_suspend(rt2x00dev, state); |
881 | * Decrease usbdev refcount. | ||
882 | */ | ||
883 | usb_put_dev(interface_to_usbdev(usb_intf)); | ||
884 | |||
885 | return 0; | ||
886 | } | 876 | } |
887 | EXPORT_SYMBOL_GPL(rt2x00usb_suspend); | 877 | EXPORT_SYMBOL_GPL(rt2x00usb_suspend); |
888 | 878 | ||
@@ -891,8 +881,6 @@ int rt2x00usb_resume(struct usb_interface *usb_intf) | |||
891 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); | 881 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); |
892 | struct rt2x00_dev *rt2x00dev = hw->priv; | 882 | struct rt2x00_dev *rt2x00dev = hw->priv; |
893 | 883 | ||
894 | usb_get_dev(interface_to_usbdev(usb_intf)); | ||
895 | |||
896 | return rt2x00lib_resume(rt2x00dev); | 884 | return rt2x00lib_resume(rt2x00dev); |
897 | } | 885 | } |
898 | EXPORT_SYMBOL_GPL(rt2x00usb_resume); | 886 | EXPORT_SYMBOL_GPL(rt2x00usb_resume); |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e58c22d21e39..b70ae40ad660 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -4283,6 +4283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
4283 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 4283 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
4284 | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); | 4284 | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); |
4285 | wl->hw->wiphy->max_scan_ssids = 1; | 4285 | wl->hw->wiphy->max_scan_ssids = 1; |
4286 | wl->hw->wiphy->max_sched_scan_ssids = 1; | ||
4286 | /* | 4287 | /* |
4287 | * Maximum length of elements in scanning probe request templates | 4288 | * Maximum length of elements in scanning probe request templates |
4288 | * should be the maximum length possible for a template, without | 4289 | * should be the maximum length possible for a template, without |
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 5cf18c2c23f0..fb1fd5af75ea 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c | |||
@@ -164,7 +164,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) | |||
164 | /* If enabled, tell runtime PM not to power off the card */ | 164 | /* If enabled, tell runtime PM not to power off the card */ |
165 | if (pm_runtime_enabled(&func->dev)) { | 165 | if (pm_runtime_enabled(&func->dev)) { |
166 | ret = pm_runtime_get_sync(&func->dev); | 166 | ret = pm_runtime_get_sync(&func->dev); |
167 | if (ret) | 167 | if (ret < 0) |
168 | goto out; | 168 | goto out; |
169 | } else { | 169 | } else { |
170 | /* Runtime PM is disabled: power up the card manually */ | 170 | /* Runtime PM is disabled: power up the card manually */ |
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 88add68bd9ac..4ae8effaee22 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c | |||
@@ -36,7 +36,6 @@ enum wl1271_tm_commands { | |||
36 | WL1271_TM_CMD_TEST, | 36 | WL1271_TM_CMD_TEST, |
37 | WL1271_TM_CMD_INTERROGATE, | 37 | WL1271_TM_CMD_INTERROGATE, |
38 | WL1271_TM_CMD_CONFIGURE, | 38 | WL1271_TM_CMD_CONFIGURE, |
39 | WL1271_TM_CMD_NVS_PUSH, | ||
40 | WL1271_TM_CMD_SET_PLT_MODE, | 39 | WL1271_TM_CMD_SET_PLT_MODE, |
41 | WL1271_TM_CMD_RECOVER, | 40 | WL1271_TM_CMD_RECOVER, |
42 | 41 | ||
@@ -190,48 +189,6 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) | |||
190 | return 0; | 189 | return 0; |
191 | } | 190 | } |
192 | 191 | ||
193 | static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) | ||
194 | { | ||
195 | int ret = 0; | ||
196 | size_t len; | ||
197 | void *buf; | ||
198 | |||
199 | wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); | ||
200 | |||
201 | if (!tb[WL1271_TM_ATTR_DATA]) | ||
202 | return -EINVAL; | ||
203 | |||
204 | buf = nla_data(tb[WL1271_TM_ATTR_DATA]); | ||
205 | len = nla_len(tb[WL1271_TM_ATTR_DATA]); | ||
206 | |||
207 | mutex_lock(&wl->mutex); | ||
208 | |||
209 | kfree(wl->nvs); | ||
210 | |||
211 | if ((wl->chip.id == CHIP_ID_1283_PG20) && | ||
212 | (len != sizeof(struct wl128x_nvs_file))) | ||
213 | return -EINVAL; | ||
214 | else if (len != sizeof(struct wl1271_nvs_file)) | ||
215 | return -EINVAL; | ||
216 | |||
217 | wl->nvs = kzalloc(len, GFP_KERNEL); | ||
218 | if (!wl->nvs) { | ||
219 | wl1271_error("could not allocate memory for the nvs file"); | ||
220 | ret = -ENOMEM; | ||
221 | goto out; | ||
222 | } | ||
223 | |||
224 | memcpy(wl->nvs, buf, len); | ||
225 | wl->nvs_len = len; | ||
226 | |||
227 | wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); | ||
228 | |||
229 | out: | ||
230 | mutex_unlock(&wl->mutex); | ||
231 | |||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) | 192 | static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) |
236 | { | 193 | { |
237 | u32 val; | 194 | u32 val; |
@@ -288,8 +245,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
288 | return wl1271_tm_cmd_interrogate(wl, tb); | 245 | return wl1271_tm_cmd_interrogate(wl, tb); |
289 | case WL1271_TM_CMD_CONFIGURE: | 246 | case WL1271_TM_CMD_CONFIGURE: |
290 | return wl1271_tm_cmd_configure(wl, tb); | 247 | return wl1271_tm_cmd_configure(wl, tb); |
291 | case WL1271_TM_CMD_NVS_PUSH: | ||
292 | return wl1271_tm_cmd_nvs_push(wl, tb); | ||
293 | case WL1271_TM_CMD_SET_PLT_MODE: | 248 | case WL1271_TM_CMD_SET_PLT_MODE: |
294 | return wl1271_tm_cmd_set_plt_mode(wl, tb); | 249 | return wl1271_tm_cmd_set_plt_mode(wl, tb); |
295 | case WL1271_TM_CMD_RECOVER: | 250 | case WL1271_TM_CMD_RECOVER: |
diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index f33e2dd97934..33b2ed451e09 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c | |||
@@ -186,6 +186,9 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { | |||
186 | !defined(CONFIG_CPU_SUBTYPE_SH7709) | 186 | !defined(CONFIG_CPU_SUBTYPE_SH7709) |
187 | [IRQ_TYPE_LEVEL_HIGH] = VALID(3), | 187 | [IRQ_TYPE_LEVEL_HIGH] = VALID(3), |
188 | #endif | 188 | #endif |
189 | #if defined(CONFIG_ARCH_SH7372) | ||
190 | [IRQ_TYPE_EDGE_BOTH] = VALID(4), | ||
191 | #endif | ||
189 | }; | 192 | }; |
190 | 193 | ||
191 | static int intc_set_type(struct irq_data *data, unsigned int type) | 194 | static int intc_set_type(struct irq_data *data, unsigned int type) |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a9414facda47..5ea6ec3442e6 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/ctype.h> | 47 | #include <linux/ctype.h> |
48 | #include <linux/err.h> | 48 | #include <linux/err.h> |
49 | #include <linux/dmaengine.h> | 49 | #include <linux/dmaengine.h> |
50 | #include <linux/dma-mapping.h> | ||
50 | #include <linux/scatterlist.h> | 51 | #include <linux/scatterlist.h> |
51 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
52 | 53 | ||
@@ -95,6 +96,12 @@ struct sci_port { | |||
95 | #endif | 96 | #endif |
96 | 97 | ||
97 | struct notifier_block freq_transition; | 98 | struct notifier_block freq_transition; |
99 | |||
100 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
101 | unsigned short saved_smr; | ||
102 | unsigned short saved_fcr; | ||
103 | unsigned char saved_brr; | ||
104 | #endif | ||
98 | }; | 105 | }; |
99 | 106 | ||
100 | /* Function prototypes */ | 107 | /* Function prototypes */ |
@@ -1076,7 +1083,7 @@ static unsigned int sci_get_mctrl(struct uart_port *port) | |||
1076 | /* This routine is used for getting signals of: DTR, DCD, DSR, RI, | 1083 | /* This routine is used for getting signals of: DTR, DCD, DSR, RI, |
1077 | and CTS/RTS */ | 1084 | and CTS/RTS */ |
1078 | 1085 | ||
1079 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; | 1086 | return TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; |
1080 | } | 1087 | } |
1081 | 1088 | ||
1082 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1089 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
@@ -1633,11 +1640,25 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | |||
1633 | return ((freq + 16 * bps) / (32 * bps) - 1); | 1640 | return ((freq + 16 * bps) / (32 * bps) - 1); |
1634 | } | 1641 | } |
1635 | 1642 | ||
1643 | static void sci_reset(struct uart_port *port) | ||
1644 | { | ||
1645 | unsigned int status; | ||
1646 | |||
1647 | do { | ||
1648 | status = sci_in(port, SCxSR); | ||
1649 | } while (!(status & SCxSR_TEND(port))); | ||
1650 | |||
1651 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ | ||
1652 | |||
1653 | if (port->type != PORT_SCI) | ||
1654 | sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); | ||
1655 | } | ||
1656 | |||
1636 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 1657 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
1637 | struct ktermios *old) | 1658 | struct ktermios *old) |
1638 | { | 1659 | { |
1639 | struct sci_port *s = to_sci_port(port); | 1660 | struct sci_port *s = to_sci_port(port); |
1640 | unsigned int status, baud, smr_val, max_baud; | 1661 | unsigned int baud, smr_val, max_baud; |
1641 | int t = -1; | 1662 | int t = -1; |
1642 | u16 scfcr = 0; | 1663 | u16 scfcr = 0; |
1643 | 1664 | ||
@@ -1657,14 +1678,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1657 | 1678 | ||
1658 | sci_port_enable(s); | 1679 | sci_port_enable(s); |
1659 | 1680 | ||
1660 | do { | 1681 | sci_reset(port); |
1661 | status = sci_in(port, SCxSR); | ||
1662 | } while (!(status & SCxSR_TEND(port))); | ||
1663 | |||
1664 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ | ||
1665 | |||
1666 | if (port->type != PORT_SCI) | ||
1667 | sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); | ||
1668 | 1682 | ||
1669 | smr_val = sci_in(port, SCSMR) & 3; | 1683 | smr_val = sci_in(port, SCSMR) & 3; |
1670 | 1684 | ||
@@ -2037,7 +2051,8 @@ static int __devinit serial_console_setup(struct console *co, char *options) | |||
2037 | if (options) | 2051 | if (options) |
2038 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 2052 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
2039 | 2053 | ||
2040 | /* TODO: disable clock */ | 2054 | sci_port_disable(sci_port); |
2055 | |||
2041 | return uart_set_options(port, co, baud, parity, bits, flow); | 2056 | return uart_set_options(port, co, baud, parity, bits, flow); |
2042 | } | 2057 | } |
2043 | 2058 | ||
@@ -2080,6 +2095,36 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | |||
2080 | return 0; | 2095 | return 0; |
2081 | } | 2096 | } |
2082 | 2097 | ||
2098 | #define uart_console(port) ((port)->cons->index == (port)->line) | ||
2099 | |||
2100 | static int sci_runtime_suspend(struct device *dev) | ||
2101 | { | ||
2102 | struct sci_port *sci_port = dev_get_drvdata(dev); | ||
2103 | struct uart_port *port = &sci_port->port; | ||
2104 | |||
2105 | if (uart_console(port)) { | ||
2106 | sci_port->saved_smr = sci_in(port, SCSMR); | ||
2107 | sci_port->saved_brr = sci_in(port, SCBRR); | ||
2108 | sci_port->saved_fcr = sci_in(port, SCFCR); | ||
2109 | } | ||
2110 | return 0; | ||
2111 | } | ||
2112 | |||
2113 | static int sci_runtime_resume(struct device *dev) | ||
2114 | { | ||
2115 | struct sci_port *sci_port = dev_get_drvdata(dev); | ||
2116 | struct uart_port *port = &sci_port->port; | ||
2117 | |||
2118 | if (uart_console(port)) { | ||
2119 | sci_reset(port); | ||
2120 | sci_out(port, SCSMR, sci_port->saved_smr); | ||
2121 | sci_out(port, SCBRR, sci_port->saved_brr); | ||
2122 | sci_out(port, SCFCR, sci_port->saved_fcr); | ||
2123 | sci_out(port, SCSCR, sci_port->cfg->scscr); | ||
2124 | } | ||
2125 | return 0; | ||
2126 | } | ||
2127 | |||
2083 | #define SCI_CONSOLE (&serial_console) | 2128 | #define SCI_CONSOLE (&serial_console) |
2084 | 2129 | ||
2085 | #else | 2130 | #else |
@@ -2089,6 +2134,8 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | |||
2089 | } | 2134 | } |
2090 | 2135 | ||
2091 | #define SCI_CONSOLE NULL | 2136 | #define SCI_CONSOLE NULL |
2137 | #define sci_runtime_suspend NULL | ||
2138 | #define sci_runtime_resume NULL | ||
2092 | 2139 | ||
2093 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 2140 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
2094 | 2141 | ||
@@ -2204,6 +2251,8 @@ static int sci_resume(struct device *dev) | |||
2204 | } | 2251 | } |
2205 | 2252 | ||
2206 | static const struct dev_pm_ops sci_dev_pm_ops = { | 2253 | static const struct dev_pm_ops sci_dev_pm_ops = { |
2254 | .runtime_suspend = sci_runtime_suspend, | ||
2255 | .runtime_resume = sci_runtime_resume, | ||
2207 | .suspend = sci_suspend, | 2256 | .suspend = sci_suspend, |
2208 | .resume = sci_resume, | 2257 | .resume = sci_resume, |
2209 | }; | 2258 | }; |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d17f47fc9e31..408ae4882d22 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1865,6 +1865,9 @@ struct wiphy { | |||
1865 | * you need use set_wiphy_dev() (see below) */ | 1865 | * you need use set_wiphy_dev() (see below) */ |
1866 | struct device dev; | 1866 | struct device dev; |
1867 | 1867 | ||
1868 | /* protects ->resume, ->suspend sysfs callbacks against unregister hw */ | ||
1869 | bool registered; | ||
1870 | |||
1868 | /* dir in debugfs: ieee80211/<wiphyname> */ | 1871 | /* dir in debugfs: ieee80211/<wiphyname> */ |
1869 | struct dentry *debugfsdir; | 1872 | struct dentry *debugfsdir; |
1870 | 1873 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index b8785e26ee1c..68c8017de969 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -5715,6 +5715,7 @@ struct pmu *perf_init_event(struct perf_event *event) | |||
5715 | pmu = idr_find(&pmu_idr, event->attr.type); | 5715 | pmu = idr_find(&pmu_idr, event->attr.type); |
5716 | rcu_read_unlock(); | 5716 | rcu_read_unlock(); |
5717 | if (pmu) { | 5717 | if (pmu) { |
5718 | event->pmu = pmu; | ||
5718 | ret = pmu->event_init(event); | 5719 | ret = pmu->event_init(event); |
5719 | if (ret) | 5720 | if (ret) |
5720 | pmu = ERR_PTR(ret); | 5721 | pmu = ERR_PTR(ret); |
@@ -5722,6 +5723,7 @@ struct pmu *perf_init_event(struct perf_event *event) | |||
5722 | } | 5723 | } |
5723 | 5724 | ||
5724 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 5725 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
5726 | event->pmu = pmu; | ||
5725 | ret = pmu->event_init(event); | 5727 | ret = pmu->event_init(event); |
5726 | if (!ret) | 5728 | if (!ret) |
5727 | goto unlock; | 5729 | goto unlock; |
@@ -5848,8 +5850,6 @@ done: | |||
5848 | return ERR_PTR(err); | 5850 | return ERR_PTR(err); |
5849 | } | 5851 | } |
5850 | 5852 | ||
5851 | event->pmu = pmu; | ||
5852 | |||
5853 | if (!event->parent) { | 5853 | if (!event->parent) { |
5854 | if (event->attach_state & PERF_ATTACH_TASK) | 5854 | if (event->attach_state & PERF_ATTACH_TASK) |
5855 | jump_label_inc(&perf_sched_events); | 5855 | jump_label_inc(&perf_sched_events); |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8add9b499912..117e0d161780 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
494 | BT_DBG("sk %p", sk); | 494 | BT_DBG("sk %p", sk); |
495 | 495 | ||
496 | add_wait_queue(sk_sleep(sk), &wait); | 496 | add_wait_queue(sk_sleep(sk), &wait); |
497 | set_current_state(TASK_INTERRUPTIBLE); | ||
497 | while (sk->sk_state != state) { | 498 | while (sk->sk_state != state) { |
498 | set_current_state(TASK_INTERRUPTIBLE); | ||
499 | |||
500 | if (!timeo) { | 499 | if (!timeo) { |
501 | err = -EINPROGRESS; | 500 | err = -EINPROGRESS; |
502 | break; | 501 | break; |
@@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
510 | release_sock(sk); | 509 | release_sock(sk); |
511 | timeo = schedule_timeout(timeo); | 510 | timeo = schedule_timeout(timeo); |
512 | lock_sock(sk); | 511 | lock_sock(sk); |
512 | set_current_state(TASK_INTERRUPTIBLE); | ||
513 | 513 | ||
514 | err = sock_error(sk); | 514 | err = sock_error(sk); |
515 | if (err) | 515 | if (err) |
516 | break; | 516 | break; |
517 | } | 517 | } |
518 | set_current_state(TASK_RUNNING); | 518 | __set_current_state(TASK_RUNNING); |
519 | remove_wait_queue(sk_sleep(sk), &wait); | 519 | remove_wait_queue(sk_sleep(sk), &wait); |
520 | return err; | 520 | return err; |
521 | } | 521 | } |
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 8e6c06158f8e..e7ee5314f39a 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h | |||
@@ -155,6 +155,7 @@ struct bnep_session { | |||
155 | unsigned int role; | 155 | unsigned int role; |
156 | unsigned long state; | 156 | unsigned long state; |
157 | unsigned long flags; | 157 | unsigned long flags; |
158 | atomic_t terminate; | ||
158 | struct task_struct *task; | 159 | struct task_struct *task; |
159 | 160 | ||
160 | struct ethhdr eh; | 161 | struct ethhdr eh; |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ca39fcf010ce..d9edfe8bf9d6 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -484,9 +484,11 @@ static int bnep_session(void *arg) | |||
484 | 484 | ||
485 | init_waitqueue_entry(&wait, current); | 485 | init_waitqueue_entry(&wait, current); |
486 | add_wait_queue(sk_sleep(sk), &wait); | 486 | add_wait_queue(sk_sleep(sk), &wait); |
487 | while (!kthread_should_stop()) { | 487 | while (1) { |
488 | set_current_state(TASK_INTERRUPTIBLE); | 488 | set_current_state(TASK_INTERRUPTIBLE); |
489 | 489 | ||
490 | if (atomic_read(&s->terminate)) | ||
491 | break; | ||
490 | /* RX */ | 492 | /* RX */ |
491 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | 493 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { |
492 | skb_orphan(skb); | 494 | skb_orphan(skb); |
@@ -504,7 +506,7 @@ static int bnep_session(void *arg) | |||
504 | 506 | ||
505 | schedule(); | 507 | schedule(); |
506 | } | 508 | } |
507 | set_current_state(TASK_RUNNING); | 509 | __set_current_state(TASK_RUNNING); |
508 | remove_wait_queue(sk_sleep(sk), &wait); | 510 | remove_wait_queue(sk_sleep(sk), &wait); |
509 | 511 | ||
510 | /* Cleanup session */ | 512 | /* Cleanup session */ |
@@ -640,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req) | |||
640 | down_read(&bnep_session_sem); | 642 | down_read(&bnep_session_sem); |
641 | 643 | ||
642 | s = __bnep_get_session(req->dst); | 644 | s = __bnep_get_session(req->dst); |
643 | if (s) | 645 | if (s) { |
644 | kthread_stop(s->task); | 646 | atomic_inc(&s->terminate); |
645 | else | 647 | wake_up_process(s->task); |
648 | } else | ||
646 | err = -ENOENT; | 649 | err = -ENOENT; |
647 | 650 | ||
648 | up_read(&bnep_session_sem); | 651 | up_read(&bnep_session_sem); |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 040f67b12978..50f0d135eb8f 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
@@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) | |||
386 | 386 | ||
387 | capi_ctr_down(ctrl); | 387 | capi_ctr_down(ctrl); |
388 | 388 | ||
389 | kthread_stop(session->task); | 389 | atomic_inc(&session->terminate); |
390 | wake_up_process(session->task); | ||
390 | } | 391 | } |
391 | 392 | ||
392 | static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) | 393 | static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) |
diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index db43b54ac9af..c32638dddbf9 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h | |||
@@ -81,6 +81,7 @@ struct cmtp_session { | |||
81 | 81 | ||
82 | char name[BTNAMSIZ]; | 82 | char name[BTNAMSIZ]; |
83 | 83 | ||
84 | atomic_t terminate; | ||
84 | struct task_struct *task; | 85 | struct task_struct *task; |
85 | 86 | ||
86 | wait_queue_head_t wait; | 87 | wait_queue_head_t wait; |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index c5b11af908be..521baa4fe835 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -292,9 +292,11 @@ static int cmtp_session(void *arg) | |||
292 | 292 | ||
293 | init_waitqueue_entry(&wait, current); | 293 | init_waitqueue_entry(&wait, current); |
294 | add_wait_queue(sk_sleep(sk), &wait); | 294 | add_wait_queue(sk_sleep(sk), &wait); |
295 | while (!kthread_should_stop()) { | 295 | while (1) { |
296 | set_current_state(TASK_INTERRUPTIBLE); | 296 | set_current_state(TASK_INTERRUPTIBLE); |
297 | 297 | ||
298 | if (atomic_read(&session->terminate)) | ||
299 | break; | ||
298 | if (sk->sk_state != BT_CONNECTED) | 300 | if (sk->sk_state != BT_CONNECTED) |
299 | break; | 301 | break; |
300 | 302 | ||
@@ -307,7 +309,7 @@ static int cmtp_session(void *arg) | |||
307 | 309 | ||
308 | schedule(); | 310 | schedule(); |
309 | } | 311 | } |
310 | set_current_state(TASK_RUNNING); | 312 | __set_current_state(TASK_RUNNING); |
311 | remove_wait_queue(sk_sleep(sk), &wait); | 313 | remove_wait_queue(sk_sleep(sk), &wait); |
312 | 314 | ||
313 | down_write(&cmtp_session_sem); | 315 | down_write(&cmtp_session_sem); |
@@ -380,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
380 | 382 | ||
381 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { | 383 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { |
382 | err = cmtp_attach_device(session); | 384 | err = cmtp_attach_device(session); |
383 | if (err < 0) | 385 | if (err < 0) { |
384 | goto detach; | 386 | atomic_inc(&session->terminate); |
387 | wake_up_process(session->task); | ||
388 | up_write(&cmtp_session_sem); | ||
389 | return err; | ||
390 | } | ||
385 | } | 391 | } |
386 | 392 | ||
387 | up_write(&cmtp_session_sem); | 393 | up_write(&cmtp_session_sem); |
388 | return 0; | 394 | return 0; |
389 | 395 | ||
390 | detach: | ||
391 | cmtp_detach_device(session); | ||
392 | |||
393 | unlink: | 396 | unlink: |
394 | __cmtp_unlink_session(session); | 397 | __cmtp_unlink_session(session); |
395 | 398 | ||
@@ -414,7 +417,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) | |||
414 | skb_queue_purge(&session->transmit); | 417 | skb_queue_purge(&session->transmit); |
415 | 418 | ||
416 | /* Stop session thread */ | 419 | /* Stop session thread */ |
417 | kthread_stop(session->task); | 420 | atomic_inc(&session->terminate); |
421 | wake_up_process(session->task); | ||
418 | } else | 422 | } else |
419 | err = -ENOENT; | 423 | err = -ENOENT; |
420 | 424 | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ec0bc3f60f2e..56943add45cc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg) | |||
1209 | 1209 | ||
1210 | BT_ERR("%s command tx timeout", hdev->name); | 1210 | BT_ERR("%s command tx timeout", hdev->name); |
1211 | atomic_set(&hdev->cmd_cnt, 1); | 1211 | atomic_set(&hdev->cmd_cnt, 1); |
1212 | clear_bit(HCI_RESET, &hdev->flags); | ||
1213 | tasklet_schedule(&hdev->cmd_task); | 1212 | tasklet_schedule(&hdev->cmd_task); |
1214 | } | 1213 | } |
1215 | 1214 | ||
@@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1327 | 1326 | ||
1328 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | 1327 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); |
1329 | if (!entry) { | 1328 | if (!entry) { |
1330 | return -ENOMEM; | 1329 | err = -ENOMEM; |
1331 | goto err; | 1330 | goto err; |
1332 | } | 1331 | } |
1333 | 1332 | ||
@@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg) | |||
2408 | if (hdev->sent_cmd) { | 2407 | if (hdev->sent_cmd) { |
2409 | atomic_dec(&hdev->cmd_cnt); | 2408 | atomic_dec(&hdev->cmd_cnt); |
2410 | hci_send_frame(skb); | 2409 | hci_send_frame(skb); |
2411 | mod_timer(&hdev->cmd_timer, | 2410 | if (test_bit(HCI_RESET, &hdev->flags)) |
2411 | del_timer(&hdev->cmd_timer); | ||
2412 | else | ||
2413 | mod_timer(&hdev->cmd_timer, | ||
2412 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); | 2414 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); |
2413 | } else { | 2415 | } else { |
2414 | skb_queue_head(&hdev->cmd_q, skb); | 2416 | skb_queue_head(&hdev->cmd_q, skb); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 43b4c2deb7cc..fb68f344c34a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -764,6 +764,7 @@ static int hidp_session(void *arg) | |||
764 | 764 | ||
765 | up_write(&hidp_session_sem); | 765 | up_write(&hidp_session_sem); |
766 | 766 | ||
767 | kfree(session->rd_data); | ||
767 | kfree(session); | 768 | kfree(session); |
768 | return 0; | 769 | return 0; |
769 | } | 770 | } |
@@ -841,7 +842,8 @@ static int hidp_setup_input(struct hidp_session *session, | |||
841 | 842 | ||
842 | err = input_register_device(input); | 843 | err = input_register_device(input); |
843 | if (err < 0) { | 844 | if (err < 0) { |
844 | hci_conn_put_device(session->conn); | 845 | input_free_device(input); |
846 | session->input = NULL; | ||
845 | return err; | 847 | return err; |
846 | } | 848 | } |
847 | 849 | ||
@@ -1044,8 +1046,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1044 | } | 1046 | } |
1045 | 1047 | ||
1046 | err = hid_add_device(session->hid); | 1048 | err = hid_add_device(session->hid); |
1047 | if (err < 0) | 1049 | if (err < 0) { |
1048 | goto err_add_device; | 1050 | atomic_inc(&session->terminate); |
1051 | wake_up_process(session->task); | ||
1052 | up_write(&hidp_session_sem); | ||
1053 | return err; | ||
1054 | } | ||
1049 | 1055 | ||
1050 | if (session->input) { | 1056 | if (session->input) { |
1051 | hidp_send_ctrl_message(session, | 1057 | hidp_send_ctrl_message(session, |
@@ -1059,12 +1065,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1059 | up_write(&hidp_session_sem); | 1065 | up_write(&hidp_session_sem); |
1060 | return 0; | 1066 | return 0; |
1061 | 1067 | ||
1062 | err_add_device: | ||
1063 | hid_destroy_device(session->hid); | ||
1064 | session->hid = NULL; | ||
1065 | atomic_inc(&session->terminate); | ||
1066 | wake_up_process(session->task); | ||
1067 | |||
1068 | unlink: | 1068 | unlink: |
1069 | hidp_del_timer(session); | 1069 | hidp_del_timer(session); |
1070 | 1070 | ||
@@ -1090,7 +1090,6 @@ purge: | |||
1090 | failed: | 1090 | failed: |
1091 | up_write(&hidp_session_sem); | 1091 | up_write(&hidp_session_sem); |
1092 | 1092 | ||
1093 | input_free_device(session->input); | ||
1094 | kfree(session); | 1093 | kfree(session); |
1095 | return err; | 1094 | return err; |
1096 | } | 1095 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3204ba8a701c..b3bdb482bbe6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1159 | int timeo = HZ/5; | 1159 | int timeo = HZ/5; |
1160 | 1160 | ||
1161 | add_wait_queue(sk_sleep(sk), &wait); | 1161 | add_wait_queue(sk_sleep(sk), &wait); |
1162 | while ((chan->unacked_frames > 0 && chan->conn)) { | 1162 | set_current_state(TASK_INTERRUPTIBLE); |
1163 | set_current_state(TASK_INTERRUPTIBLE); | 1163 | while (chan->unacked_frames > 0 && chan->conn) { |
1164 | |||
1165 | if (!timeo) | 1164 | if (!timeo) |
1166 | timeo = HZ/5; | 1165 | timeo = HZ/5; |
1167 | 1166 | ||
@@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1173 | release_sock(sk); | 1172 | release_sock(sk); |
1174 | timeo = schedule_timeout(timeo); | 1173 | timeo = schedule_timeout(timeo); |
1175 | lock_sock(sk); | 1174 | lock_sock(sk); |
1175 | set_current_state(TASK_INTERRUPTIBLE); | ||
1176 | 1176 | ||
1177 | err = sock_error(sk); | 1177 | err = sock_error(sk); |
1178 | if (err) | 1178 | if (err) |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c36b3e8739c..61f1f623091d 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
235 | 235 | ||
236 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | 236 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); |
237 | 237 | ||
238 | if (sk->sk_state != BT_LISTEN) { | ||
239 | err = -EBADFD; | ||
240 | goto done; | ||
241 | } | ||
242 | |||
243 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 238 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
244 | 239 | ||
245 | BT_DBG("sk %p timeo %ld", sk, timeo); | 240 | BT_DBG("sk %p timeo %ld", sk, timeo); |
246 | 241 | ||
247 | /* Wait for an incoming connection. (wake-one). */ | 242 | /* Wait for an incoming connection. (wake-one). */ |
248 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 243 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
249 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 244 | while (1) { |
250 | set_current_state(TASK_INTERRUPTIBLE); | 245 | set_current_state(TASK_INTERRUPTIBLE); |
251 | if (!timeo) { | 246 | |
252 | err = -EAGAIN; | 247 | if (sk->sk_state != BT_LISTEN) { |
248 | err = -EBADFD; | ||
253 | break; | 249 | break; |
254 | } | 250 | } |
255 | 251 | ||
256 | release_sock(sk); | 252 | nsk = bt_accept_dequeue(sk, newsock); |
257 | timeo = schedule_timeout(timeo); | 253 | if (nsk) |
258 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | 254 | break; |
259 | 255 | ||
260 | if (sk->sk_state != BT_LISTEN) { | 256 | if (!timeo) { |
261 | err = -EBADFD; | 257 | err = -EAGAIN; |
262 | break; | 258 | break; |
263 | } | 259 | } |
264 | 260 | ||
@@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
266 | err = sock_intr_errno(timeo); | 262 | err = sock_intr_errno(timeo); |
267 | break; | 263 | break; |
268 | } | 264 | } |
265 | |||
266 | release_sock(sk); | ||
267 | timeo = schedule_timeout(timeo); | ||
268 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
269 | } | 269 | } |
270 | set_current_state(TASK_RUNNING); | 270 | __set_current_state(TASK_RUNNING); |
271 | remove_wait_queue(sk_sleep(sk), &wait); | 271 | remove_wait_queue(sk_sleep(sk), &wait); |
272 | 272 | ||
273 | if (err) | 273 | if (err) |
@@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
993 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); | 993 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); |
994 | 994 | ||
995 | sk->sk_destruct = l2cap_sock_destruct; | 995 | sk->sk_destruct = l2cap_sock_destruct; |
996 | sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); | 996 | sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; |
997 | 997 | ||
998 | sock_reset_flag(sk, SOCK_ZAPPED); | 998 | sock_reset_flag(sk, SOCK_ZAPPED); |
999 | 999 | ||
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5759bb7054f7..5ba3f6df665c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) | 62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) |
63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) | 63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) |
64 | 64 | ||
65 | static unsigned long rfcomm_event; | ||
66 | 65 | ||
67 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
68 | 67 | ||
@@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) | |||
120 | { | 119 | { |
121 | if (!rfcomm_thread) | 120 | if (!rfcomm_thread) |
122 | return; | 121 | return; |
123 | set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
124 | wake_up_process(rfcomm_thread); | 122 | wake_up_process(rfcomm_thread); |
125 | } | 123 | } |
126 | 124 | ||
@@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused) | |||
2038 | 2036 | ||
2039 | rfcomm_add_listener(BDADDR_ANY); | 2037 | rfcomm_add_listener(BDADDR_ANY); |
2040 | 2038 | ||
2041 | while (!kthread_should_stop()) { | 2039 | while (1) { |
2042 | set_current_state(TASK_INTERRUPTIBLE); | 2040 | set_current_state(TASK_INTERRUPTIBLE); |
2043 | if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { | 2041 | |
2044 | /* No pending events. Let's sleep. | 2042 | if (kthread_should_stop()) |
2045 | * Incoming connections and data will wake us up. */ | 2043 | break; |
2046 | schedule(); | ||
2047 | } | ||
2048 | set_current_state(TASK_RUNNING); | ||
2049 | 2044 | ||
2050 | /* Process stuff */ | 2045 | /* Process stuff */ |
2051 | clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
2052 | rfcomm_process_sessions(); | 2046 | rfcomm_process_sessions(); |
2047 | |||
2048 | schedule(); | ||
2053 | } | 2049 | } |
2050 | __set_current_state(TASK_RUNNING); | ||
2054 | 2051 | ||
2055 | rfcomm_kill_listener(); | 2052 | rfcomm_kill_listener(); |
2056 | 2053 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8f01e6b11a70..482722bbc7a0 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
485 | 485 | ||
486 | lock_sock(sk); | 486 | lock_sock(sk); |
487 | 487 | ||
488 | if (sk->sk_state != BT_LISTEN) { | ||
489 | err = -EBADFD; | ||
490 | goto done; | ||
491 | } | ||
492 | |||
493 | if (sk->sk_type != SOCK_STREAM) { | 488 | if (sk->sk_type != SOCK_STREAM) { |
494 | err = -EINVAL; | 489 | err = -EINVAL; |
495 | goto done; | 490 | goto done; |
@@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
501 | 496 | ||
502 | /* Wait for an incoming connection. (wake-one). */ | 497 | /* Wait for an incoming connection. (wake-one). */ |
503 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 498 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
504 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 499 | while (1) { |
505 | set_current_state(TASK_INTERRUPTIBLE); | 500 | set_current_state(TASK_INTERRUPTIBLE); |
506 | if (!timeo) { | 501 | |
507 | err = -EAGAIN; | 502 | if (sk->sk_state != BT_LISTEN) { |
503 | err = -EBADFD; | ||
508 | break; | 504 | break; |
509 | } | 505 | } |
510 | 506 | ||
511 | release_sock(sk); | 507 | nsk = bt_accept_dequeue(sk, newsock); |
512 | timeo = schedule_timeout(timeo); | 508 | if (nsk) |
513 | lock_sock(sk); | 509 | break; |
514 | 510 | ||
515 | if (sk->sk_state != BT_LISTEN) { | 511 | if (!timeo) { |
516 | err = -EBADFD; | 512 | err = -EAGAIN; |
517 | break; | 513 | break; |
518 | } | 514 | } |
519 | 515 | ||
@@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
521 | err = sock_intr_errno(timeo); | 517 | err = sock_intr_errno(timeo); |
522 | break; | 518 | break; |
523 | } | 519 | } |
520 | |||
521 | release_sock(sk); | ||
522 | timeo = schedule_timeout(timeo); | ||
523 | lock_sock(sk); | ||
524 | } | 524 | } |
525 | set_current_state(TASK_RUNNING); | 525 | __set_current_state(TASK_RUNNING); |
526 | remove_wait_queue(sk_sleep(sk), &wait); | 526 | remove_wait_queue(sk_sleep(sk), &wait); |
527 | 527 | ||
528 | if (err) | 528 | if (err) |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 4c3621b5e0aa..8270f05e3f1f 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
564 | 564 | ||
565 | lock_sock(sk); | 565 | lock_sock(sk); |
566 | 566 | ||
567 | if (sk->sk_state != BT_LISTEN) { | ||
568 | err = -EBADFD; | ||
569 | goto done; | ||
570 | } | ||
571 | |||
572 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 567 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
573 | 568 | ||
574 | BT_DBG("sk %p timeo %ld", sk, timeo); | 569 | BT_DBG("sk %p timeo %ld", sk, timeo); |
575 | 570 | ||
576 | /* Wait for an incoming connection. (wake-one). */ | 571 | /* Wait for an incoming connection. (wake-one). */ |
577 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 572 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
578 | while (!(ch = bt_accept_dequeue(sk, newsock))) { | 573 | while (1) { |
579 | set_current_state(TASK_INTERRUPTIBLE); | 574 | set_current_state(TASK_INTERRUPTIBLE); |
580 | if (!timeo) { | 575 | |
581 | err = -EAGAIN; | 576 | if (sk->sk_state != BT_LISTEN) { |
577 | err = -EBADFD; | ||
582 | break; | 578 | break; |
583 | } | 579 | } |
584 | 580 | ||
585 | release_sock(sk); | 581 | ch = bt_accept_dequeue(sk, newsock); |
586 | timeo = schedule_timeout(timeo); | 582 | if (ch) |
587 | lock_sock(sk); | 583 | break; |
588 | 584 | ||
589 | if (sk->sk_state != BT_LISTEN) { | 585 | if (!timeo) { |
590 | err = -EBADFD; | 586 | err = -EAGAIN; |
591 | break; | 587 | break; |
592 | } | 588 | } |
593 | 589 | ||
@@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
595 | err = sock_intr_errno(timeo); | 591 | err = sock_intr_errno(timeo); |
596 | break; | 592 | break; |
597 | } | 593 | } |
594 | |||
595 | release_sock(sk); | ||
596 | timeo = schedule_timeout(timeo); | ||
597 | lock_sock(sk); | ||
598 | } | 598 | } |
599 | set_current_state(TASK_RUNNING); | 599 | __set_current_state(TASK_RUNNING); |
600 | remove_wait_queue(sk_sleep(sk), &wait); | 600 | remove_wait_queue(sk_sleep(sk), &wait); |
601 | 601 | ||
602 | if (err) | 602 | if (err) |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2d85ca7111d3..995cbe0ac0b2 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1456,7 +1456,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1456 | { | 1456 | { |
1457 | struct sk_buff *skb2; | 1457 | struct sk_buff *skb2; |
1458 | const struct ipv6hdr *ip6h; | 1458 | const struct ipv6hdr *ip6h; |
1459 | struct icmp6hdr *icmp6h; | 1459 | u8 icmp6_type; |
1460 | u8 nexthdr; | 1460 | u8 nexthdr; |
1461 | unsigned len; | 1461 | unsigned len; |
1462 | int offset; | 1462 | int offset; |
@@ -1502,9 +1502,9 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1502 | __skb_pull(skb2, offset); | 1502 | __skb_pull(skb2, offset); |
1503 | skb_reset_transport_header(skb2); | 1503 | skb_reset_transport_header(skb2); |
1504 | 1504 | ||
1505 | icmp6h = icmp6_hdr(skb2); | 1505 | icmp6_type = icmp6_hdr(skb2)->icmp6_type; |
1506 | 1506 | ||
1507 | switch (icmp6h->icmp6_type) { | 1507 | switch (icmp6_type) { |
1508 | case ICMPV6_MGM_QUERY: | 1508 | case ICMPV6_MGM_QUERY: |
1509 | case ICMPV6_MGM_REPORT: | 1509 | case ICMPV6_MGM_REPORT: |
1510 | case ICMPV6_MGM_REDUCTION: | 1510 | case ICMPV6_MGM_REDUCTION: |
@@ -1520,16 +1520,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1520 | err = pskb_trim_rcsum(skb2, len); | 1520 | err = pskb_trim_rcsum(skb2, len); |
1521 | if (err) | 1521 | if (err) |
1522 | goto out; | 1522 | goto out; |
1523 | err = -EINVAL; | ||
1523 | } | 1524 | } |
1524 | 1525 | ||
1526 | ip6h = ipv6_hdr(skb2); | ||
1527 | |||
1525 | switch (skb2->ip_summed) { | 1528 | switch (skb2->ip_summed) { |
1526 | case CHECKSUM_COMPLETE: | 1529 | case CHECKSUM_COMPLETE: |
1527 | if (!csum_fold(skb2->csum)) | 1530 | if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len, |
1531 | IPPROTO_ICMPV6, skb2->csum)) | ||
1528 | break; | 1532 | break; |
1529 | /*FALLTHROUGH*/ | 1533 | /*FALLTHROUGH*/ |
1530 | case CHECKSUM_NONE: | 1534 | case CHECKSUM_NONE: |
1531 | skb2->csum = 0; | 1535 | skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr, |
1532 | if (skb_checksum_complete(skb2)) | 1536 | &ip6h->daddr, |
1537 | skb2->len, | ||
1538 | IPPROTO_ICMPV6, 0)); | ||
1539 | if (__skb_checksum_complete(skb2)) | ||
1533 | goto out; | 1540 | goto out; |
1534 | } | 1541 | } |
1535 | 1542 | ||
@@ -1537,7 +1544,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1537 | 1544 | ||
1538 | BR_INPUT_SKB_CB(skb)->igmp = 1; | 1545 | BR_INPUT_SKB_CB(skb)->igmp = 1; |
1539 | 1546 | ||
1540 | switch (icmp6h->icmp6_type) { | 1547 | switch (icmp6_type) { |
1541 | case ICMPV6_MGM_REPORT: | 1548 | case ICMPV6_MGM_REPORT: |
1542 | { | 1549 | { |
1543 | struct mld_msg *mld; | 1550 | struct mld_msg *mld; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8fab9b0bb203..1334d7e56f02 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1319,11 +1319,15 @@ static void neigh_proxy_process(unsigned long arg) | |||
1319 | 1319 | ||
1320 | if (tdif <= 0) { | 1320 | if (tdif <= 0) { |
1321 | struct net_device *dev = skb->dev; | 1321 | struct net_device *dev = skb->dev; |
1322 | |||
1322 | __skb_unlink(skb, &tbl->proxy_queue); | 1323 | __skb_unlink(skb, &tbl->proxy_queue); |
1323 | if (tbl->proxy_redo && netif_running(dev)) | 1324 | if (tbl->proxy_redo && netif_running(dev)) { |
1325 | rcu_read_lock(); | ||
1324 | tbl->proxy_redo(skb); | 1326 | tbl->proxy_redo(skb); |
1325 | else | 1327 | rcu_read_unlock(); |
1328 | } else { | ||
1326 | kfree_skb(skb); | 1329 | kfree_skb(skb); |
1330 | } | ||
1327 | 1331 | ||
1328 | dev_put(dev); | 1332 | dev_put(dev); |
1329 | } else if (!sched_next || tdif < sched_next) | 1333 | } else if (!sched_next || tdif < sched_next) |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index adf84dd8c7b5..52622517e0d8 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -558,13 +558,14 @@ int __netpoll_rx(struct sk_buff *skb) | |||
558 | if (skb_shared(skb)) | 558 | if (skb_shared(skb)) |
559 | goto out; | 559 | goto out; |
560 | 560 | ||
561 | iph = (struct iphdr *)skb->data; | ||
562 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 561 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
563 | goto out; | 562 | goto out; |
563 | iph = (struct iphdr *)skb->data; | ||
564 | if (iph->ihl < 5 || iph->version != 4) | 564 | if (iph->ihl < 5 || iph->version != 4) |
565 | goto out; | 565 | goto out; |
566 | if (!pskb_may_pull(skb, iph->ihl*4)) | 566 | if (!pskb_may_pull(skb, iph->ihl*4)) |
567 | goto out; | 567 | goto out; |
568 | iph = (struct iphdr *)skb->data; | ||
568 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) | 569 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) |
569 | goto out; | 570 | goto out; |
570 | 571 | ||
@@ -579,6 +580,7 @@ int __netpoll_rx(struct sk_buff *skb) | |||
579 | if (pskb_trim_rcsum(skb, len)) | 580 | if (pskb_trim_rcsum(skb, len)) |
580 | goto out; | 581 | goto out; |
581 | 582 | ||
583 | iph = (struct iphdr *)skb->data; | ||
582 | if (iph->protocol != IPPROTO_UDP) | 584 | if (iph->protocol != IPPROTO_UDP) |
583 | goto out; | 585 | goto out; |
584 | 586 | ||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 283c0a26e03f..d577199eabd5 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -767,7 +767,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) | |||
767 | break; | 767 | break; |
768 | for (i=0; i<nsrcs; i++) { | 768 | for (i=0; i<nsrcs; i++) { |
769 | /* skip inactive filters */ | 769 | /* skip inactive filters */ |
770 | if (pmc->sfcount[MCAST_INCLUDE] || | 770 | if (psf->sf_count[MCAST_INCLUDE] || |
771 | pmc->sfcount[MCAST_EXCLUDE] != | 771 | pmc->sfcount[MCAST_EXCLUDE] != |
772 | psf->sf_count[MCAST_EXCLUDE]) | 772 | psf->sf_count[MCAST_EXCLUDE]) |
773 | continue; | 773 | continue; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 3e6ebcdb4779..ee7839f4d6e3 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1059,7 +1059,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
1059 | break; | 1059 | break; |
1060 | for (i=0; i<nsrcs; i++) { | 1060 | for (i=0; i<nsrcs; i++) { |
1061 | /* skip inactive filters */ | 1061 | /* skip inactive filters */ |
1062 | if (pmc->mca_sfcount[MCAST_INCLUDE] || | 1062 | if (psf->sf_count[MCAST_INCLUDE] || |
1063 | pmc->mca_sfcount[MCAST_EXCLUDE] != | 1063 | pmc->mca_sfcount[MCAST_EXCLUDE] != |
1064 | psf->sf_count[MCAST_EXCLUDE]) | 1064 | psf->sf_count[MCAST_EXCLUDE]) |
1065 | continue; | 1065 | continue; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 866f269183cf..acb44230b251 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1012,7 +1012,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1012 | cancel_work_sync(&local->reconfig_filter); | 1012 | cancel_work_sync(&local->reconfig_filter); |
1013 | 1013 | ||
1014 | ieee80211_clear_tx_pending(local); | 1014 | ieee80211_clear_tx_pending(local); |
1015 | sta_info_stop(local); | ||
1016 | rate_control_deinitialize(local); | 1015 | rate_control_deinitialize(local); |
1017 | 1016 | ||
1018 | if (skb_queue_len(&local->skb_queue) || | 1017 | if (skb_queue_len(&local->skb_queue) || |
@@ -1024,6 +1023,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1024 | 1023 | ||
1025 | destroy_workqueue(local->workqueue); | 1024 | destroy_workqueue(local->workqueue); |
1026 | wiphy_unregister(local->hw.wiphy); | 1025 | wiphy_unregister(local->hw.wiphy); |
1026 | sta_info_stop(local); | ||
1027 | ieee80211_wep_free(local); | 1027 | ieee80211_wep_free(local); |
1028 | ieee80211_led_exit(local); | 1028 | ieee80211_led_exit(local); |
1029 | kfree(local->int_scan_req); | 1029 | kfree(local->int_scan_req); |
diff --git a/net/socket.c b/net/socket.c index 24a77400b65e..ffe92ca32f2a 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1965,8 +1965,9 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
1965 | * used_address->name_len is initialized to UINT_MAX so that the first | 1965 | * used_address->name_len is initialized to UINT_MAX so that the first |
1966 | * destination address never matches. | 1966 | * destination address never matches. |
1967 | */ | 1967 | */ |
1968 | if (used_address && used_address->name_len == msg_sys->msg_namelen && | 1968 | if (used_address && msg_sys->msg_name && |
1969 | !memcmp(&used_address->name, msg->msg_name, | 1969 | used_address->name_len == msg_sys->msg_namelen && |
1970 | !memcmp(&used_address->name, msg_sys->msg_name, | ||
1970 | used_address->name_len)) { | 1971 | used_address->name_len)) { |
1971 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); | 1972 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); |
1972 | goto out_freectl; | 1973 | goto out_freectl; |
@@ -1978,8 +1979,9 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
1978 | */ | 1979 | */ |
1979 | if (used_address && err >= 0) { | 1980 | if (used_address && err >= 0) { |
1980 | used_address->name_len = msg_sys->msg_namelen; | 1981 | used_address->name_len = msg_sys->msg_namelen; |
1981 | memcpy(&used_address->name, msg->msg_name, | 1982 | if (msg_sys->msg_name) |
1982 | used_address->name_len); | 1983 | memcpy(&used_address->name, msg_sys->msg_name, |
1984 | used_address->name_len); | ||
1983 | } | 1985 | } |
1984 | 1986 | ||
1985 | out_freectl: | 1987 | out_freectl: |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 645437cfc464..c14865172da7 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -616,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy) | |||
616 | if (res) | 616 | if (res) |
617 | goto out_rm_dev; | 617 | goto out_rm_dev; |
618 | 618 | ||
619 | rtnl_lock(); | ||
620 | rdev->wiphy.registered = true; | ||
621 | rtnl_unlock(); | ||
619 | return 0; | 622 | return 0; |
620 | 623 | ||
621 | out_rm_dev: | 624 | out_rm_dev: |
@@ -647,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
647 | { | 650 | { |
648 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 651 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
649 | 652 | ||
653 | rtnl_lock(); | ||
654 | rdev->wiphy.registered = false; | ||
655 | rtnl_unlock(); | ||
656 | |||
650 | rfkill_unregister(rdev->rfkill); | 657 | rfkill_unregister(rdev->rfkill); |
651 | 658 | ||
652 | /* protect the device list */ | 659 | /* protect the device list */ |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index c6e4ca6a7d2e..ff574597a854 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) | |||
93 | 93 | ||
94 | if (rdev->ops->suspend) { | 94 | if (rdev->ops->suspend) { |
95 | rtnl_lock(); | 95 | rtnl_lock(); |
96 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | 96 | if (rdev->wiphy.registered) |
97 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | ||
97 | rtnl_unlock(); | 98 | rtnl_unlock(); |
98 | } | 99 | } |
99 | 100 | ||
@@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev) | |||
112 | 113 | ||
113 | if (rdev->ops->resume) { | 114 | if (rdev->ops->resume) { |
114 | rtnl_lock(); | 115 | rtnl_lock(); |
115 | ret = rdev->ops->resume(&rdev->wiphy); | 116 | if (rdev->wiphy.registered) |
117 | ret = rdev->ops->resume(&rdev->wiphy); | ||
116 | rtnl_unlock(); | 118 | rtnl_unlock(); |
117 | } | 119 | } |
118 | 120 | ||
diff --git a/tools/perf/arch/arm/util/dwarf-regs.c b/tools/perf/arch/arm/util/dwarf-regs.c index fff6450c8c99..e8d5c551c69c 100644 --- a/tools/perf/arch/arm/util/dwarf-regs.c +++ b/tools/perf/arch/arm/util/dwarf-regs.c | |||
@@ -8,7 +8,10 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <stdlib.h> | ||
12 | #ifndef __UCLIBC__ | ||
11 | #include <libio.h> | 13 | #include <libio.h> |
14 | #endif | ||
12 | #include <dwarf-regs.h> | 15 | #include <dwarf-regs.h> |
13 | 16 | ||
14 | struct pt_regs_dwarfnum { | 17 | struct pt_regs_dwarfnum { |