aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-event_source-devices-events517
-rw-r--r--Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x723
-rw-r--r--Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci43
-rw-r--r--MAINTAINERS3
-rw-r--r--arch/powerpc/configs/ppc64_defconfig70
-rw-r--r--arch/powerpc/configs/ppc64e_defconfig70
-rw-r--r--arch/powerpc/configs/pseries_defconfig55
-rw-r--r--arch/powerpc/configs/pseries_le_defconfig53
-rw-r--r--arch/powerpc/include/asm/compat.h4
-rw-r--r--arch/powerpc/include/asm/cputable.h6
-rw-r--r--arch/powerpc/include/asm/exception-64s.h8
-rw-r--r--arch/powerpc/include/asm/hvcall.h5
-rw-r--r--arch/powerpc/include/asm/opal.h32
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h1
-rw-r--r--arch/powerpc/include/asm/reg.h3
-rw-r--r--arch/powerpc/kernel/cputable.c2
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S5
-rw-r--r--arch/powerpc/kernel/rtas.c22
-rw-r--r--arch/powerpc/kernel/traps.c5
-rw-r--r--arch/powerpc/mm/pgtable_64.c5
-rw-r--r--arch/powerpc/perf/Makefile2
-rw-r--r--arch/powerpc/perf/core-book3s.c172
-rw-r--r--arch/powerpc/perf/hv-24x7-catalog.h33
-rw-r--r--arch/powerpc/perf/hv-24x7.c510
-rw-r--r--arch/powerpc/perf/hv-24x7.h109
-rw-r--r--arch/powerpc/perf/hv-common.c39
-rw-r--r--arch/powerpc/perf/hv-common.h36
-rw-r--r--arch/powerpc/perf/hv-gpci.c294
-rw-r--r--arch/powerpc/perf/hv-gpci.h73
-rw-r--r--arch/powerpc/perf/power7-events-list.h10
-rw-r--r--arch/powerpc/perf/power8-pmu.c78
-rw-r--r--arch/powerpc/platforms/powernv/Makefile4
-rw-r--r--arch/powerpc/platforms/powernv/opal-async.c203
-rw-r--r--arch/powerpc/platforms/powernv/opal-sensor.c64
-rw-r--r--arch/powerpc/platforms/powernv/opal-sysparam.c290
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S3
-rw-r--r--arch/powerpc/platforms/powernv/opal.c2
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig12
-rw-r--r--drivers/hwmon/Kconfig8
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ibmpowernv.c529
-rw-r--r--fs/sysfs/group.c7
42 files changed, 3122 insertions, 289 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
index 3c1cc24361bd..7b40a3cbc26a 100644
--- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
@@ -57,6 +57,523 @@ What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
57 /sys/devices/cpu/events/PM_LD_REF_L1 57 /sys/devices/cpu/events/PM_LD_REF_L1
58 /sys/devices/cpu/events/PM_RUN_CYC 58 /sys/devices/cpu/events/PM_RUN_CYC
59 /sys/devices/cpu/events/PM_RUN_INST_CMPL 59 /sys/devices/cpu/events/PM_RUN_INST_CMPL
60 /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_ALL
61 /sys/devices/cpu/events/PM_GCT_UTIL_7_TO_10_SLOTS
62 /sys/devices/cpu/events/PM_PMC2_SAVED
63 /sys/devices/cpu/events/PM_VSU0_16FLOP
64 /sys/devices/cpu/events/PM_MRK_LSU_DERAT_MISS
65 /sys/devices/cpu/events/PM_MRK_ST_CMPL
66 /sys/devices/cpu/events/PM_NEST_PAIR3_ADD
67 /sys/devices/cpu/events/PM_L2_ST_DISP
68 /sys/devices/cpu/events/PM_L2_CASTOUT_MOD
69 /sys/devices/cpu/events/PM_ISEG
70 /sys/devices/cpu/events/PM_MRK_INST_TIMEO
71 /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_ADDR
72 /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM
73 /sys/devices/cpu/events/PM_IERAT_WR_64K
74 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16M
75 /sys/devices/cpu/events/PM_IERAT_MISS
76 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_LMEM
77 /sys/devices/cpu/events/PM_FLOP
78 /sys/devices/cpu/events/PM_THRD_PRIO_4_5_CYC
79 /sys/devices/cpu/events/PM_BR_PRED_TA
80 /sys/devices/cpu/events/PM_EXT_INT
81 /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV
82 /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC
83 /sys/devices/cpu/events/PM_LSU1_LDF
84 /sys/devices/cpu/events/PM_IC_WRITE_ALL
85 /sys/devices/cpu/events/PM_LSU0_SRQ_STFWD
86 /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_MOD
87 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR
88 /sys/devices/cpu/events/PM_DATA_FROM_L21_MOD
89 /sys/devices/cpu/events/PM_VSU1_SCAL_DOUBLE_ISSUED
90 /sys/devices/cpu/events/PM_VSU0_8FLOP
91 /sys/devices/cpu/events/PM_POWER_EVENT1
92 /sys/devices/cpu/events/PM_DISP_CLB_HELD_BAL
93 /sys/devices/cpu/events/PM_VSU1_2FLOP
94 /sys/devices/cpu/events/PM_LWSYNC_HELD
95 /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_SHR
96 /sys/devices/cpu/events/PM_INST_FROM_L21_MOD
97 /sys/devices/cpu/events/PM_IERAT_XLATE_WR_16MPLUS
98 /sys/devices/cpu/events/PM_IC_REQ_ALL
99 /sys/devices/cpu/events/PM_DSLB_MISS
100 /sys/devices/cpu/events/PM_L3_MISS
101 /sys/devices/cpu/events/PM_LSU0_L1_PREF
102 /sys/devices/cpu/events/PM_VSU_SCALAR_SINGLE_ISSUED
103 /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM_STRIDE
104 /sys/devices/cpu/events/PM_L2_INST
105 /sys/devices/cpu/events/PM_VSU0_FRSP
106 /sys/devices/cpu/events/PM_FLUSH_DISP
107 /sys/devices/cpu/events/PM_PTEG_FROM_L2MISS
108 /sys/devices/cpu/events/PM_VSU1_DQ_ISSUED
109 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM
110 /sys/devices/cpu/events/PM_LSU_FLUSH_ULD
111 /sys/devices/cpu/events/PM_PTEG_FROM_LMEM
112 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16M
113 /sys/devices/cpu/events/PM_THRD_ALL_RUN_CYC
114 /sys/devices/cpu/events/PM_MEM0_PREFETCH_DISP
115 /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC_COUNT
116 /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_MOD
117 /sys/devices/cpu/events/PM_VSU_FRSP
118 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD
119 /sys/devices/cpu/events/PM_PMC1_OVERFLOW
120 /sys/devices/cpu/events/PM_VSU0_SINGLE
121 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3MISS
122 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_SHR
123 /sys/devices/cpu/events/PM_VSU0_VECTOR_SP_ISSUED
124 /sys/devices/cpu/events/PM_VSU1_FEST
125 /sys/devices/cpu/events/PM_MRK_INST_DISP
126 /sys/devices/cpu/events/PM_VSU0_COMPLEX_ISSUED
127 /sys/devices/cpu/events/PM_LSU1_FLUSH_UST
128 /sys/devices/cpu/events/PM_FXU_IDLE
129 /sys/devices/cpu/events/PM_LSU0_FLUSH_ULD
130 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD
131 /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_ALL_CYC
132 /sys/devices/cpu/events/PM_LSU1_REJECT_LMQ_FULL
133 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_MOD
134 /sys/devices/cpu/events/PM_INST_FROM_RL2L3_MOD
135 /sys/devices/cpu/events/PM_SHL_CREATED
136 /sys/devices/cpu/events/PM_L2_ST_HIT
137 /sys/devices/cpu/events/PM_DATA_FROM_DMEM
138 /sys/devices/cpu/events/PM_L3_LD_MISS
139 /sys/devices/cpu/events/PM_FXU1_BUSY_FXU0_IDLE
140 /sys/devices/cpu/events/PM_DISP_CLB_HELD_RES
141 /sys/devices/cpu/events/PM_L2_SN_SX_I_DONE
142 /sys/devices/cpu/events/PM_STCX_CMPL
143 /sys/devices/cpu/events/PM_VSU0_2FLOP
144 /sys/devices/cpu/events/PM_L3_PREF_MISS
145 /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_CYC
146 /sys/devices/cpu/events/PM_LSU_REJECT_ERAT_MISS
147 /sys/devices/cpu/events/PM_L1_ICACHE_MISS
148 /sys/devices/cpu/events/PM_LSU1_FLUSH_SRQ
149 /sys/devices/cpu/events/PM_LD_REF_L1_LSU0
150 /sys/devices/cpu/events/PM_VSU0_FEST
151 /sys/devices/cpu/events/PM_VSU_VECTOR_SINGLE_ISSUED
152 /sys/devices/cpu/events/PM_FREQ_UP
153 /sys/devices/cpu/events/PM_DATA_FROM_LMEM
154 /sys/devices/cpu/events/PM_LSU1_LDX
155 /sys/devices/cpu/events/PM_PMC3_OVERFLOW
156 /sys/devices/cpu/events/PM_MRK_BR_MPRED
157 /sys/devices/cpu/events/PM_SHL_MATCH
158 /sys/devices/cpu/events/PM_MRK_BR_TAKEN
159 /sys/devices/cpu/events/PM_ISLB_MISS
160 /sys/devices/cpu/events/PM_DISP_HELD_THERMAL
161 /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_SHR
162 /sys/devices/cpu/events/PM_LSU1_SRQ_STFWD
163 /sys/devices/cpu/events/PM_PTEG_FROM_DMEM
164 /sys/devices/cpu/events/PM_VSU_2FLOP
165 /sys/devices/cpu/events/PM_GCT_FULL_CYC
166 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3_CYC
167 /sys/devices/cpu/events/PM_LSU_SRQ_S0_ALLOC
168 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_4K
169 /sys/devices/cpu/events/PM_BR_MPRED_TA
170 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2MISS
171 /sys/devices/cpu/events/PM_DPU_HELD_POWER
172 /sys/devices/cpu/events/PM_MRK_VSU_FIN
173 /sys/devices/cpu/events/PM_LSU_SRQ_S0_VALID
174 /sys/devices/cpu/events/PM_GCT_EMPTY_CYC
175 /sys/devices/cpu/events/PM_IOPS_DISP
176 /sys/devices/cpu/events/PM_RUN_SPURR
177 /sys/devices/cpu/events/PM_PTEG_FROM_L21_MOD
178 /sys/devices/cpu/events/PM_VSU0_1FLOP
179 /sys/devices/cpu/events/PM_SNOOP_TLBIE
180 /sys/devices/cpu/events/PM_DATA_FROM_L3MISS
181 /sys/devices/cpu/events/PM_VSU_SINGLE
182 /sys/devices/cpu/events/PM_DTLB_MISS_16G
183 /sys/devices/cpu/events/PM_FLUSH
184 /sys/devices/cpu/events/PM_L2_LD_HIT
185 /sys/devices/cpu/events/PM_NEST_PAIR2_AND
186 /sys/devices/cpu/events/PM_VSU1_1FLOP
187 /sys/devices/cpu/events/PM_IC_PREF_REQ
188 /sys/devices/cpu/events/PM_L3_LD_HIT
189 /sys/devices/cpu/events/PM_DISP_HELD
190 /sys/devices/cpu/events/PM_L2_LD
191 /sys/devices/cpu/events/PM_LSU_FLUSH_SRQ
192 /sys/devices/cpu/events/PM_BC_PLUS_8_CONV
193 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD_CYC
194 /sys/devices/cpu/events/PM_L2_RCST_BUSY_RC_FULL
195 /sys/devices/cpu/events/PM_TB_BIT_TRANS
196 /sys/devices/cpu/events/PM_THERMAL_MAX
197 /sys/devices/cpu/events/PM_LSU1_FLUSH_ULD
198 /sys/devices/cpu/events/PM_LSU1_REJECT_LHS
199 /sys/devices/cpu/events/PM_LSU_LRQ_S0_ALLOC
200 /sys/devices/cpu/events/PM_L3_CO_L31
201 /sys/devices/cpu/events/PM_POWER_EVENT4
202 /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
203 /sys/devices/cpu/events/PM_BR_UNCOND
204 /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_ALLOC
205 /sys/devices/cpu/events/PM_PMC4_REWIND
206 /sys/devices/cpu/events/PM_L2_RCLD_DISP
207 /sys/devices/cpu/events/PM_THRD_PRIO_2_3_CYC
208 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2MISS
209 /sys/devices/cpu/events/PM_IC_DEMAND_L2_BHT_REDIRECT
210 /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
211 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_L2
212 /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC_COUNT
213 /sys/devices/cpu/events/PM_BR_PRED_CCACHE
214 /sys/devices/cpu/events/PM_GCT_UTIL_1_TO_2_SLOTS
215 /sys/devices/cpu/events/PM_MRK_ST_CMPL_INT
216 /sys/devices/cpu/events/PM_LSU_TWO_TABLEWALK_CYC
217 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3MISS
218 /sys/devices/cpu/events/PM_LSU_SET_MPRED
219 /sys/devices/cpu/events/PM_FLUSH_DISP_TLBIE
220 /sys/devices/cpu/events/PM_VSU1_FCONV
221 /sys/devices/cpu/events/PM_DERAT_MISS_16G
222 /sys/devices/cpu/events/PM_INST_FROM_LMEM
223 /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_REDIRECT
224 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2
225 /sys/devices/cpu/events/PM_PTEG_FROM_L2
226 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR_CYC
227 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_4K
228 /sys/devices/cpu/events/PM_VSU0_FPSCR
229 /sys/devices/cpu/events/PM_VSU1_VECT_DOUBLE_ISSUED
230 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_MOD
231 /sys/devices/cpu/events/PM_MEM0_RQ_DISP
232 /sys/devices/cpu/events/PM_L2_LD_MISS
233 /sys/devices/cpu/events/PM_VMX_RESULT_SAT_1
234 /sys/devices/cpu/events/PM_L1_PREF
235 /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM_CYC
236 /sys/devices/cpu/events/PM_GRP_IC_MISS_NONSPEC
237 /sys/devices/cpu/events/PM_PB_NODE_PUMP
238 /sys/devices/cpu/events/PM_SHL_MERGED
239 /sys/devices/cpu/events/PM_NEST_PAIR1_ADD
240 /sys/devices/cpu/events/PM_DATA_FROM_L3
241 /sys/devices/cpu/events/PM_LSU_FLUSH
242 /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_COUNT
243 /sys/devices/cpu/events/PM_PMC2_OVERFLOW
244 /sys/devices/cpu/events/PM_LSU_LDF
245 /sys/devices/cpu/events/PM_POWER_EVENT3
246 /sys/devices/cpu/events/PM_DISP_WT
247 /sys/devices/cpu/events/PM_IC_BANK_CONFLICT
248 /sys/devices/cpu/events/PM_BR_MPRED_CR_TA
249 /sys/devices/cpu/events/PM_L2_INST_MISS
250 /sys/devices/cpu/events/PM_NEST_PAIR2_ADD
251 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH
252 /sys/devices/cpu/events/PM_L2_LDST
253 /sys/devices/cpu/events/PM_INST_FROM_L31_SHR
254 /sys/devices/cpu/events/PM_VSU0_FIN
255 /sys/devices/cpu/events/PM_VSU1_FCONV
256 /sys/devices/cpu/events/PM_INST_FROM_RMEM
257 /sys/devices/cpu/events/PM_DISP_CLB_HELD_TLBIE
258 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM_CYC
259 /sys/devices/cpu/events/PM_BR_PRED_CR
260 /sys/devices/cpu/events/PM_LSU_REJECT
261 /sys/devices/cpu/events/PM_GCT_UTIL_3_TO_6_SLOTS
262 /sys/devices/cpu/events/PM_CMPLU_STALL_END_GCT_NOSLOT
263 /sys/devices/cpu/events/PM_LSU0_REJECT_LMQ_FULL
264 /sys/devices/cpu/events/PM_VSU_FEST
265 /sys/devices/cpu/events/PM_NEST_PAIR0_AND
266 /sys/devices/cpu/events/PM_PTEG_FROM_L3
267 /sys/devices/cpu/events/PM_POWER_EVENT2
268 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_PAGE
269 /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV
270 /sys/devices/cpu/events/PM_MRK_GRP_CMPL
271 /sys/devices/cpu/events/PM_VSU0_SCAL_DOUBLE_ISSUED
272 /sys/devices/cpu/events/PM_GRP_DISP
273 /sys/devices/cpu/events/PM_LSU0_LDX
274 /sys/devices/cpu/events/PM_DATA_FROM_L2
275 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD
276 /sys/devices/cpu/events/PM_VSU0_VECT_DOUBLE_ISSUED
277 /sys/devices/cpu/events/PM_VSU1_2FLOP_DOUBLE
278 /sys/devices/cpu/events/PM_THRD_PRIO_6_7_CYC
279 /sys/devices/cpu/events/PM_BC_PLUS_8_RSLV_TAKEN
280 /sys/devices/cpu/events/PM_BR_MPRED_CR
281 /sys/devices/cpu/events/PM_L3_CO_MEM
282 /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_MOD
283 /sys/devices/cpu/events/PM_LSU_SRQ_FULL_CYC
284 /sys/devices/cpu/events/PM_TABLEWALK_CYC
285 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RMEM
286 /sys/devices/cpu/events/PM_LSU_SRQ_STFWD
287 /sys/devices/cpu/events/PM_INST_PTEG_FROM_RMEM
288 /sys/devices/cpu/events/PM_FXU0_FIN
289 /sys/devices/cpu/events/PM_LSU1_L1_SW_PREF
290 /sys/devices/cpu/events/PM_PTEG_FROM_L31_MOD
291 /sys/devices/cpu/events/PM_PMC5_OVERFLOW
292 /sys/devices/cpu/events/PM_LD_REF_L1_LSU1
293 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_SHR
294 /sys/devices/cpu/events/PM_DATA_FROM_RMEM
295 /sys/devices/cpu/events/PM_VSU0_SCAL_SINGLE_ISSUED
296 /sys/devices/cpu/events/PM_BR_MPRED_LSTACK
297 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD_CYC
298 /sys/devices/cpu/events/PM_LSU0_FLUSH_UST
299 /sys/devices/cpu/events/PM_LSU_NCST
300 /sys/devices/cpu/events/PM_BR_TAKEN
301 /sys/devices/cpu/events/PM_INST_PTEG_FROM_LMEM
302 /sys/devices/cpu/events/PM_DTLB_MISS_4K
303 /sys/devices/cpu/events/PM_PMC4_SAVED
304 /sys/devices/cpu/events/PM_VSU1_PERMUTE_ISSUED
305 /sys/devices/cpu/events/PM_SLB_MISS
306 /sys/devices/cpu/events/PM_LSU1_FLUSH_LRQ
307 /sys/devices/cpu/events/PM_DTLB_MISS
308 /sys/devices/cpu/events/PM_VSU1_FRSP
309 /sys/devices/cpu/events/PM_VSU_VECTOR_DOUBLE_ISSUED
310 /sys/devices/cpu/events/PM_L2_CASTOUT_SHR
311 /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_SHR
312 /sys/devices/cpu/events/PM_VSU1_STF
313 /sys/devices/cpu/events/PM_ST_FIN
314 /sys/devices/cpu/events/PM_PTEG_FROM_L21_SHR
315 /sys/devices/cpu/events/PM_L2_LOC_GUESS_WRONG
316 /sys/devices/cpu/events/PM_MRK_STCX_FAIL
317 /sys/devices/cpu/events/PM_LSU0_REJECT_LHS
318 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_HIT
319 /sys/devices/cpu/events/PM_L3_PREF_BUSY
320 /sys/devices/cpu/events/PM_MRK_BRU_FIN
321 /sys/devices/cpu/events/PM_LSU1_NCLD
322 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_MOD
323 /sys/devices/cpu/events/PM_LSU_NCLD
324 /sys/devices/cpu/events/PM_LSU_LDX
325 /sys/devices/cpu/events/PM_L2_LOC_GUESS_CORRECT
326 /sys/devices/cpu/events/PM_THRESH_TIMEO
327 /sys/devices/cpu/events/PM_L3_PREF_ST
328 /sys/devices/cpu/events/PM_DISP_CLB_HELD_SYNC
329 /sys/devices/cpu/events/PM_VSU_SIMPLE_ISSUED
330 /sys/devices/cpu/events/PM_VSU1_SINGLE
331 /sys/devices/cpu/events/PM_DATA_TABLEWALK_CYC
332 /sys/devices/cpu/events/PM_L2_RC_ST_DONE
333 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_MOD
334 /sys/devices/cpu/events/PM_LARX_LSU1
335 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM
336 /sys/devices/cpu/events/PM_DISP_CLB_HELD
337 /sys/devices/cpu/events/PM_DERAT_MISS_4K
338 /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_ADDR
339 /sys/devices/cpu/events/PM_SEG_EXCEPTION
340 /sys/devices/cpu/events/PM_FLUSH_DISP_SB
341 /sys/devices/cpu/events/PM_L2_DC_INV
342 /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_MOD
343 /sys/devices/cpu/events/PM_DSEG
344 /sys/devices/cpu/events/PM_BR_PRED_LSTACK
345 /sys/devices/cpu/events/PM_VSU0_STF
346 /sys/devices/cpu/events/PM_LSU_FX_FIN
347 /sys/devices/cpu/events/PM_DERAT_MISS_16M
348 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_MOD
349 /sys/devices/cpu/events/PM_GCT_UTIL_11_PLUS_SLOTS
350 /sys/devices/cpu/events/PM_INST_FROM_L3
351 /sys/devices/cpu/events/PM_MRK_IFU_FIN
352 /sys/devices/cpu/events/PM_ITLB_MISS
353 /sys/devices/cpu/events/PM_VSU_STF
354 /sys/devices/cpu/events/PM_LSU_FLUSH_UST
355 /sys/devices/cpu/events/PM_L2_LDST_MISS
356 /sys/devices/cpu/events/PM_FXU1_FIN
357 /sys/devices/cpu/events/PM_SHL_DEALLOCATED
358 /sys/devices/cpu/events/PM_L2_SN_M_WR_DONE
359 /sys/devices/cpu/events/PM_LSU_REJECT_SET_MPRED
360 /sys/devices/cpu/events/PM_L3_PREF_LD
361 /sys/devices/cpu/events/PM_L2_SN_M_RD_DONE
362 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16G
363 /sys/devices/cpu/events/PM_VSU_FCONV
364 /sys/devices/cpu/events/PM_ANY_THRD_RUN_CYC
365 /sys/devices/cpu/events/PM_LSU_LMQ_FULL_CYC
366 /sys/devices/cpu/events/PM_MRK_LSU_REJECT_LHS
367 /sys/devices/cpu/events/PM_MRK_LD_MISS_L1_CYC
368 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2_CYC
369 /sys/devices/cpu/events/PM_INST_IMC_MATCH_DISP
370 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM_CYC
371 /sys/devices/cpu/events/PM_VSU0_SIMPLE_ISSUED
372 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_SHR
373 /sys/devices/cpu/events/PM_VSU_FMA_DOUBLE
374 /sys/devices/cpu/events/PM_VSU_4FLOP
375 /sys/devices/cpu/events/PM_VSU1_FIN
376 /sys/devices/cpu/events/PM_NEST_PAIR1_AND
377 /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_MOD
378 /sys/devices/cpu/events/PM_PTEG_FROM_RMEM
379 /sys/devices/cpu/events/PM_LSU_LRQ_S0_VALID
380 /sys/devices/cpu/events/PM_LSU0_LDF
381 /sys/devices/cpu/events/PM_FLUSH_COMPLETION
382 /sys/devices/cpu/events/PM_ST_MISS_L1
383 /sys/devices/cpu/events/PM_L2_NODE_PUMP
384 /sys/devices/cpu/events/PM_INST_FROM_DL2L3_SHR
385 /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC
386 /sys/devices/cpu/events/PM_VSU1_DENORM
387 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR_CYC
388 /sys/devices/cpu/events/PM_NEST_PAIR0_ADD
389 /sys/devices/cpu/events/PM_INST_FROM_L3MISS
390 /sys/devices/cpu/events/PM_EE_OFF_EXT_INT
391 /sys/devices/cpu/events/PM_INST_PTEG_FROM_DMEM
392 /sys/devices/cpu/events/PM_INST_FROM_DL2L3_MOD
393 /sys/devices/cpu/events/PM_PMC6_OVERFLOW
394 /sys/devices/cpu/events/PM_VSU_2FLOP_DOUBLE
395 /sys/devices/cpu/events/PM_TLB_MISS
396 /sys/devices/cpu/events/PM_FXU_BUSY
397 /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_OTHER
398 /sys/devices/cpu/events/PM_LSU_REJECT_LMQ_FULL
399 /sys/devices/cpu/events/PM_IC_RELOAD_SHR
400 /sys/devices/cpu/events/PM_GRP_MRK
401 /sys/devices/cpu/events/PM_MRK_ST_NEST
402 /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV
403 /sys/devices/cpu/events/PM_LSU0_FLUSH_LRQ
404 /sys/devices/cpu/events/PM_LARX_LSU0
405 /sys/devices/cpu/events/PM_IBUF_FULL_CYC
406 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR_CYC
407 /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_ALLOC
408 /sys/devices/cpu/events/PM_GRP_MRK_CYC
409 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR_CYC
410 /sys/devices/cpu/events/PM_L2_GLOB_GUESS_CORRECT
411 /sys/devices/cpu/events/PM_LSU_REJECT_LHS
412 /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM
413 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3
414 /sys/devices/cpu/events/PM_FREQ_DOWN
415 /sys/devices/cpu/events/PM_PB_RETRY_NODE_PUMP
416 /sys/devices/cpu/events/PM_INST_FROM_RL2L3_SHR
417 /sys/devices/cpu/events/PM_MRK_INST_ISSUED
418 /sys/devices/cpu/events/PM_PTEG_FROM_L3MISS
419 /sys/devices/cpu/events/PM_RUN_PURR
420 /sys/devices/cpu/events/PM_MRK_GRP_IC_MISS
421 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3
422 /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_SHR
423 /sys/devices/cpu/events/PM_LSU_FLUSH_LRQ
424 /sys/devices/cpu/events/PM_MRK_DERAT_MISS_64K
425 /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_MOD
426 /sys/devices/cpu/events/PM_L2_ST_MISS
427 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_SHR
428 /sys/devices/cpu/events/PM_LWSYNC
429 /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM_STRIDE
430 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_LRQ
431 /sys/devices/cpu/events/PM_INST_IMC_MATCH_CMPL
432 /sys/devices/cpu/events/PM_NEST_PAIR3_AND
433 /sys/devices/cpu/events/PM_PB_RETRY_SYS_PUMP
434 /sys/devices/cpu/events/PM_MRK_INST_FIN
435 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_SHR
436 /sys/devices/cpu/events/PM_INST_FROM_L31_MOD
437 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_64K
438 /sys/devices/cpu/events/PM_LSU_FIN
439 /sys/devices/cpu/events/PM_MRK_LSU_REJECT
440 /sys/devices/cpu/events/PM_L2_CO_FAIL_BUSY
441 /sys/devices/cpu/events/PM_MEM0_WQ_DISP
442 /sys/devices/cpu/events/PM_DATA_FROM_L31_MOD
443 /sys/devices/cpu/events/PM_THERMAL_WARN
444 /sys/devices/cpu/events/PM_VSU0_4FLOP
445 /sys/devices/cpu/events/PM_BR_MPRED_CCACHE
446 /sys/devices/cpu/events/PM_L1_DEMAND_WRITE
447 /sys/devices/cpu/events/PM_FLUSH_BR_MPRED
448 /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16G
449 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DMEM
450 /sys/devices/cpu/events/PM_L2_RCST_DISP
451 /sys/devices/cpu/events/PM_LSU_PARTIAL_CDF
452 /sys/devices/cpu/events/PM_DISP_CLB_HELD_SB
453 /sys/devices/cpu/events/PM_VSU0_FMA_DOUBLE
454 /sys/devices/cpu/events/PM_FXU0_BUSY_FXU1_IDLE
455 /sys/devices/cpu/events/PM_IC_DEMAND_CYC
456 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR
457 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_UST
458 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3MISS
459 /sys/devices/cpu/events/PM_VSU_DENORM
460 /sys/devices/cpu/events/PM_MRK_LSU_PARTIAL_CDF
461 /sys/devices/cpu/events/PM_INST_FROM_L21_SHR
462 /sys/devices/cpu/events/PM_IC_PREF_WRITE
463 /sys/devices/cpu/events/PM_BR_PRED
464 /sys/devices/cpu/events/PM_INST_FROM_DMEM
465 /sys/devices/cpu/events/PM_IC_PREF_CANCEL_ALL
466 /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_CONFIRM
467 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_SRQ
468 /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC
469 /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_OTHER
470 /sys/devices/cpu/events/PM_VSU1_DD_ISSUED
471 /sys/devices/cpu/events/PM_PTEG_FROM_L31_SHR
472 /sys/devices/cpu/events/PM_DATA_FROM_L21_SHR
473 /sys/devices/cpu/events/PM_LSU0_NCLD
474 /sys/devices/cpu/events/PM_VSU1_4FLOP
475 /sys/devices/cpu/events/PM_VSU1_8FLOP
476 /sys/devices/cpu/events/PM_VSU_8FLOP
477 /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_CYC
478 /sys/devices/cpu/events/PM_DTLB_MISS_64K
479 /sys/devices/cpu/events/PM_THRD_CONC_RUN_INST
480 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2
481 /sys/devices/cpu/events/PM_PB_SYS_PUMP
482 /sys/devices/cpu/events/PM_VSU_FIN
483 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD
484 /sys/devices/cpu/events/PM_THRD_PRIO_0_1_CYC
485 /sys/devices/cpu/events/PM_DERAT_MISS_64K
486 /sys/devices/cpu/events/PM_PMC2_REWIND
487 /sys/devices/cpu/events/PM_INST_FROM_L2
488 /sys/devices/cpu/events/PM_GRP_BR_MPRED_NONSPEC
489 /sys/devices/cpu/events/PM_INST_DISP
490 /sys/devices/cpu/events/PM_MEM0_RD_CANCEL_TOTAL
491 /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM
492 /sys/devices/cpu/events/PM_L1_DCACHE_RELOAD_VALID
493 /sys/devices/cpu/events/PM_VSU_SCALAR_DOUBLE_ISSUED
494 /sys/devices/cpu/events/PM_L3_PREF_HIT
495 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_MOD
496 /sys/devices/cpu/events/PM_MRK_FXU_FIN
497 /sys/devices/cpu/events/PM_PMC4_OVERFLOW
498 /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3
499 /sys/devices/cpu/events/PM_LSU0_LMQ_LHR_MERGE
500 /sys/devices/cpu/events/PM_BTAC_HIT
501 /sys/devices/cpu/events/PM_L3_RD_BUSY
502 /sys/devices/cpu/events/PM_LSU0_L1_SW_PREF
503 /sys/devices/cpu/events/PM_INST_FROM_L2MISS
504 /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_ALLOC
505 /sys/devices/cpu/events/PM_L2_ST
506 /sys/devices/cpu/events/PM_VSU0_DENORM
507 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR
508 /sys/devices/cpu/events/PM_BR_PRED_CR_TA
509 /sys/devices/cpu/events/PM_VSU0_FCONV
510 /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_ULD
511 /sys/devices/cpu/events/PM_BTAC_MISS
512 /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC_COUNT
513 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2
514 /sys/devices/cpu/events/PM_LSU_DCACHE_RELOAD_VALID
515 /sys/devices/cpu/events/PM_VSU_FMA
516 /sys/devices/cpu/events/PM_LSU0_FLUSH_SRQ
517 /sys/devices/cpu/events/PM_LSU1_L1_PREF
518 /sys/devices/cpu/events/PM_IOPS_CMPL
519 /sys/devices/cpu/events/PM_L2_SYS_PUMP
520 /sys/devices/cpu/events/PM_L2_RCLD_BUSY_RC_FULL
521 /sys/devices/cpu/events/PM_LSU_LMQ_S0_ALLOC
522 /sys/devices/cpu/events/PM_FLUSH_DISP_SYNC
523 /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD_CYC
524 /sys/devices/cpu/events/PM_L2_IC_INV
525 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD_CYC
526 /sys/devices/cpu/events/PM_L3_PREF_LDST
527 /sys/devices/cpu/events/PM_LSU_SRQ_EMPTY_CYC
528 /sys/devices/cpu/events/PM_LSU_LMQ_S0_VALID
529 /sys/devices/cpu/events/PM_FLUSH_PARTIAL
530 /sys/devices/cpu/events/PM_VSU1_FMA_DOUBLE
531 /sys/devices/cpu/events/PM_1PLUS_PPC_DISP
532 /sys/devices/cpu/events/PM_DATA_FROM_L2MISS
533 /sys/devices/cpu/events/PM_SUSPENDED
534 /sys/devices/cpu/events/PM_VSU0_FMA
535 /sys/devices/cpu/events/PM_STCX_FAIL
536 /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV_DOUBLE
537 /sys/devices/cpu/events/PM_DC_PREF_DST
538 /sys/devices/cpu/events/PM_VSU1_SCAL_SINGLE_ISSUED
539 /sys/devices/cpu/events/PM_L3_HIT
540 /sys/devices/cpu/events/PM_L2_GLOB_GUESS_WRONG
541 /sys/devices/cpu/events/PM_MRK_DFU_FIN
542 /sys/devices/cpu/events/PM_INST_FROM_L1
543 /sys/devices/cpu/events/PM_IC_DEMAND_REQ
544 /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV_DOUBLE
545 /sys/devices/cpu/events/PM_VSU1_FMA
546 /sys/devices/cpu/events/PM_MRK_LD_MISS_L1
547 /sys/devices/cpu/events/PM_VSU0_2FLOP_DOUBLE
548 /sys/devices/cpu/events/PM_LSU_DC_PREF_STRIDED_STREAM_CONFIRM
549 /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_SHR
550 /sys/devices/cpu/events/PM_MRK_LSU_REJECT_ERAT_MISS
551 /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2MISS
552 /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_SHR
553 /sys/devices/cpu/events/PM_INST_FROM_PREF
554 /sys/devices/cpu/events/PM_VSU1_SQ
555 /sys/devices/cpu/events/PM_L2_LD_DISP
556 /sys/devices/cpu/events/PM_L2_DISP_ALL
557 /sys/devices/cpu/events/PM_THRD_GRP_CMPL_BOTH_CYC
558 /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV_DOUBLE
559 /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_SHR
560 /sys/devices/cpu/events/PM_VSU_1FLOP
561 /sys/devices/cpu/events/PM_HV_CYC
562 /sys/devices/cpu/events/PM_MRK_LSU_FIN
563 /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR
564 /sys/devices/cpu/events/PM_DTLB_MISS_16M
565 /sys/devices/cpu/events/PM_LSU1_LMQ_LHR_MERGE
566 /sys/devices/cpu/events/PM_IFU_FIN
567 /sys/devices/cpu/events/PM_1THRD_CON_RUN_INSTR
568 /sys/devices/cpu/events/PM_CMPLU_STALL_COUNT
569 /sys/devices/cpu/events/PM_MEM0_PB_RD_CL
570 /sys/devices/cpu/events/PM_THRD_1_RUN_CYC
571 /sys/devices/cpu/events/PM_THRD_2_CONC_RUN_INSTR
572 /sys/devices/cpu/events/PM_THRD_2_RUN_CYC
573 /sys/devices/cpu/events/PM_THRD_3_CONC_RUN_INST
574 /sys/devices/cpu/events/PM_THRD_3_RUN_CYC
575 /sys/devices/cpu/events/PM_THRD_4_CONC_RUN_INST
576 /sys/devices/cpu/events/PM_THRD_4_RUN_CYC
60 577
61Date: 2013/01/08 578Date: 2013/01/08
62 579
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
new file mode 100644
index 000000000000..e78ee798d7bd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
@@ -0,0 +1,23 @@
1What: /sys/bus/event_source/devices/hv_24x7/interface/catalog
2Date: February 2014
3Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
4Description:
5 Provides access to the binary "24x7 catalog" provided by the
6 hypervisor on POWER7 and 8 systems. This catalog lists events
7 avaliable from the powerpc "hv_24x7" pmu. Its format is
8 documented here:
9 https://raw.githubusercontent.com/jmesmon/catalog-24x7/master/hv-24x7-catalog.h
10
11What: /sys/bus/event_source/devices/hv_24x7/interface/catalog_length
12Date: February 2014
13Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
14Description:
15 A number equal to the length in bytes of the catalog. This is
16 also extractable from the provided binary "catalog" sysfs entry.
17
18What: /sys/bus/event_source/devices/hv_24x7/interface/catalog_version
19Date: February 2014
20Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
21Description:
22 Exposes the "version" field of the 24x7 catalog. This is also
23 extractable from the provided binary "catalog" sysfs entry.
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
new file mode 100644
index 000000000000..3fa58c23f13b
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
@@ -0,0 +1,43 @@
1What: /sys/bus/event_source/devices/hv_gpci/interface/collect_privileged
2Date: February 2014
3Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
4Description:
5 '0' if the hypervisor is configured to forbid access to event
6 counters being accumulated by other guests and to physical
7 domain event counters.
8 '1' if that access is allowed.
9
10What: /sys/bus/event_source/devices/hv_gpci/interface/ga
11Date: February 2014
12Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
13Description:
14 0 or 1. Indicates whether we have access to "GA" events (listed
15 in arch/powerpc/perf/hv-gpci.h).
16
17What: /sys/bus/event_source/devices/hv_gpci/interface/expanded
18Date: February 2014
19Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
20Description:
21 0 or 1. Indicates whether we have access to "EXPANDED" events (listed
22 in arch/powerpc/perf/hv-gpci.h).
23
24What: /sys/bus/event_source/devices/hv_gpci/interface/lab
25Date: February 2014
26Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
27Description:
28 0 or 1. Indicates whether we have access to "LAB" events (listed
29 in arch/powerpc/perf/hv-gpci.h).
30
31What: /sys/bus/event_source/devices/hv_gpci/interface/version
32Date: February 2014
33Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
34Description:
35 A number indicating the version of the gpci interface that the
36 hypervisor reports supporting.
37
38What: /sys/bus/event_source/devices/hv_gpci/interface/kernel_version
39Date: February 2014
40Contact: Cody P Schafer <cody@linux.vnet.ibm.com>
41Description:
42 A number indicating the latest version of the gpci interface
43 that the kernel is aware of.
diff --git a/MAINTAINERS b/MAINTAINERS
index b2cf5cfb4d29..27030d573d88 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5216,11 +5216,10 @@ F: arch/powerpc/platforms/512x/
5216F: arch/powerpc/platforms/52xx/ 5216F: arch/powerpc/platforms/52xx/
5217 5217
5218LINUX FOR POWERPC EMBEDDED PPC4XX 5218LINUX FOR POWERPC EMBEDDED PPC4XX
5219M: Josh Boyer <jwboyer@gmail.com> 5219M: Alistair Popple <alistair@popple.id.au>
5220M: Matt Porter <mporter@kernel.crashing.org> 5220M: Matt Porter <mporter@kernel.crashing.org>
5221W: http://www.penguinppc.org/ 5221W: http://www.penguinppc.org/
5222L: linuxppc-dev@lists.ozlabs.org 5222L: linuxppc-dev@lists.ozlabs.org
5223T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git
5224S: Maintained 5223S: Maintained
5225F: arch/powerpc/platforms/40x/ 5224F: arch/powerpc/platforms/40x/
5226F: arch/powerpc/platforms/44x/ 5225F: arch/powerpc/platforms/44x/
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index e015896b7e5c..f26b267eb71f 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -73,74 +73,8 @@ CONFIG_INET_ESP=m
73CONFIG_INET_IPCOMP=m 73CONFIG_INET_IPCOMP=m
74# CONFIG_IPV6 is not set 74# CONFIG_IPV6 is not set
75CONFIG_NETFILTER=y 75CONFIG_NETFILTER=y
76CONFIG_NF_CONNTRACK=m 76# CONFIG_NETFILTER_ADVANCED is not set
77CONFIG_NF_CONNTRACK_EVENTS=y 77CONFIG_BRIDGE=m
78CONFIG_NF_CT_PROTO_SCTP=m
79CONFIG_NF_CONNTRACK_AMANDA=m
80CONFIG_NF_CONNTRACK_FTP=m
81CONFIG_NF_CONNTRACK_H323=m
82CONFIG_NF_CONNTRACK_IRC=m
83CONFIG_NF_CONNTRACK_NETBIOS_NS=m
84CONFIG_NF_CONNTRACK_PPTP=m
85CONFIG_NF_CONNTRACK_SIP=m
86CONFIG_NF_CONNTRACK_TFTP=m
87CONFIG_NF_CT_NETLINK=m
88CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
89CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
90CONFIG_NETFILTER_XT_TARGET_DSCP=m
91CONFIG_NETFILTER_XT_TARGET_MARK=m
92CONFIG_NETFILTER_XT_TARGET_NFLOG=m
93CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
94CONFIG_NETFILTER_XT_TARGET_TPROXY=m
95CONFIG_NETFILTER_XT_TARGET_TRACE=m
96CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
97CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
98CONFIG_NETFILTER_XT_MATCH_COMMENT=m
99CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
100CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
101CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
102CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
103CONFIG_NETFILTER_XT_MATCH_DCCP=m
104CONFIG_NETFILTER_XT_MATCH_DSCP=m
105CONFIG_NETFILTER_XT_MATCH_ESP=m
106CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
107CONFIG_NETFILTER_XT_MATCH_HELPER=m
108CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
109CONFIG_NETFILTER_XT_MATCH_LENGTH=m
110CONFIG_NETFILTER_XT_MATCH_LIMIT=m
111CONFIG_NETFILTER_XT_MATCH_MAC=m
112CONFIG_NETFILTER_XT_MATCH_MARK=m
113CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
114CONFIG_NETFILTER_XT_MATCH_OWNER=m
115CONFIG_NETFILTER_XT_MATCH_POLICY=m
116CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
117CONFIG_NETFILTER_XT_MATCH_QUOTA=m
118CONFIG_NETFILTER_XT_MATCH_RATEEST=m
119CONFIG_NETFILTER_XT_MATCH_REALM=m
120CONFIG_NETFILTER_XT_MATCH_RECENT=m
121CONFIG_NETFILTER_XT_MATCH_SCTP=m
122CONFIG_NETFILTER_XT_MATCH_SOCKET=m
123CONFIG_NETFILTER_XT_MATCH_STATE=m
124CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
125CONFIG_NETFILTER_XT_MATCH_STRING=m
126CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
127CONFIG_NETFILTER_XT_MATCH_U32=m
128CONFIG_NF_CONNTRACK_IPV4=m
129CONFIG_IP_NF_IPTABLES=m
130CONFIG_IP_NF_MATCH_AH=m
131CONFIG_IP_NF_MATCH_ECN=m
132CONFIG_IP_NF_MATCH_TTL=m
133CONFIG_IP_NF_FILTER=m
134CONFIG_IP_NF_TARGET_REJECT=m
135CONFIG_IP_NF_TARGET_ULOG=m
136CONFIG_IP_NF_MANGLE=m
137CONFIG_IP_NF_TARGET_CLUSTERIP=m
138CONFIG_IP_NF_TARGET_ECN=m
139CONFIG_IP_NF_TARGET_TTL=m
140CONFIG_IP_NF_RAW=m
141CONFIG_IP_NF_ARPTABLES=m
142CONFIG_IP_NF_ARPFILTER=m
143CONFIG_IP_NF_ARP_MANGLE=m
144CONFIG_BPF_JIT=y 78CONFIG_BPF_JIT=y
145CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 79CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
146CONFIG_DEVTMPFS=y 80CONFIG_DEVTMPFS=y
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig
index f627fda08953..438e813dc9cb 100644
--- a/arch/powerpc/configs/ppc64e_defconfig
+++ b/arch/powerpc/configs/ppc64e_defconfig
@@ -48,74 +48,8 @@ CONFIG_INET_ESP=m
48CONFIG_INET_IPCOMP=m 48CONFIG_INET_IPCOMP=m
49# CONFIG_IPV6 is not set 49# CONFIG_IPV6 is not set
50CONFIG_NETFILTER=y 50CONFIG_NETFILTER=y
51CONFIG_NF_CONNTRACK=m 51# CONFIG_NETFILTER_ADVANCED is not set
52CONFIG_NF_CONNTRACK_EVENTS=y 52CONFIG_BRIDGE=m
53CONFIG_NF_CT_PROTO_SCTP=m
54CONFIG_NF_CONNTRACK_AMANDA=m
55CONFIG_NF_CONNTRACK_FTP=m
56CONFIG_NF_CONNTRACK_H323=m
57CONFIG_NF_CONNTRACK_IRC=m
58CONFIG_NF_CONNTRACK_NETBIOS_NS=m
59CONFIG_NF_CONNTRACK_PPTP=m
60CONFIG_NF_CONNTRACK_SIP=m
61CONFIG_NF_CONNTRACK_TFTP=m
62CONFIG_NF_CT_NETLINK=m
63CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
64CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
65CONFIG_NETFILTER_XT_TARGET_DSCP=m
66CONFIG_NETFILTER_XT_TARGET_MARK=m
67CONFIG_NETFILTER_XT_TARGET_NFLOG=m
68CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
69CONFIG_NETFILTER_XT_TARGET_TPROXY=m
70CONFIG_NETFILTER_XT_TARGET_TRACE=m
71CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
72CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
73CONFIG_NETFILTER_XT_MATCH_COMMENT=m
74CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
75CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
76CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
77CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
78CONFIG_NETFILTER_XT_MATCH_DCCP=m
79CONFIG_NETFILTER_XT_MATCH_DSCP=m
80CONFIG_NETFILTER_XT_MATCH_ESP=m
81CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
82CONFIG_NETFILTER_XT_MATCH_HELPER=m
83CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
84CONFIG_NETFILTER_XT_MATCH_LENGTH=m
85CONFIG_NETFILTER_XT_MATCH_LIMIT=m
86CONFIG_NETFILTER_XT_MATCH_MAC=m
87CONFIG_NETFILTER_XT_MATCH_MARK=m
88CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
89CONFIG_NETFILTER_XT_MATCH_OWNER=m
90CONFIG_NETFILTER_XT_MATCH_POLICY=m
91CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
92CONFIG_NETFILTER_XT_MATCH_QUOTA=m
93CONFIG_NETFILTER_XT_MATCH_RATEEST=m
94CONFIG_NETFILTER_XT_MATCH_REALM=m
95CONFIG_NETFILTER_XT_MATCH_RECENT=m
96CONFIG_NETFILTER_XT_MATCH_SCTP=m
97CONFIG_NETFILTER_XT_MATCH_SOCKET=m
98CONFIG_NETFILTER_XT_MATCH_STATE=m
99CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
100CONFIG_NETFILTER_XT_MATCH_STRING=m
101CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
102CONFIG_NETFILTER_XT_MATCH_U32=m
103CONFIG_NF_CONNTRACK_IPV4=m
104CONFIG_IP_NF_IPTABLES=m
105CONFIG_IP_NF_MATCH_AH=m
106CONFIG_IP_NF_MATCH_ECN=m
107CONFIG_IP_NF_MATCH_TTL=m
108CONFIG_IP_NF_FILTER=m
109CONFIG_IP_NF_TARGET_REJECT=m
110CONFIG_IP_NF_TARGET_ULOG=m
111CONFIG_IP_NF_MANGLE=m
112CONFIG_IP_NF_TARGET_CLUSTERIP=m
113CONFIG_IP_NF_TARGET_ECN=m
114CONFIG_IP_NF_TARGET_TTL=m
115CONFIG_IP_NF_RAW=m
116CONFIG_IP_NF_ARPTABLES=m
117CONFIG_IP_NF_ARPFILTER=m
118CONFIG_IP_NF_ARP_MANGLE=m
119CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 53CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
120CONFIG_DEVTMPFS=y 54CONFIG_DEVTMPFS=y
121CONFIG_DEVTMPFS_MOUNT=y 55CONFIG_DEVTMPFS_MOUNT=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index e9a8b4e0a0f6..9ea8342bd219 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -65,57 +65,8 @@ CONFIG_INET_ESP=m
65CONFIG_INET_IPCOMP=m 65CONFIG_INET_IPCOMP=m
66# CONFIG_IPV6 is not set 66# CONFIG_IPV6 is not set
67CONFIG_NETFILTER=y 67CONFIG_NETFILTER=y
68CONFIG_NF_CONNTRACK=m 68# CONFIG_NETFILTER_ADVANCED is not set
69CONFIG_NF_CONNTRACK_EVENTS=y 69CONFIG_BRIDGE=m
70CONFIG_NF_CT_PROTO_UDPLITE=m
71CONFIG_NF_CONNTRACK_FTP=m
72CONFIG_NF_CONNTRACK_IRC=m
73CONFIG_NF_CONNTRACK_TFTP=m
74CONFIG_NF_CT_NETLINK=m
75CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
76CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
77CONFIG_NETFILTER_XT_TARGET_MARK=m
78CONFIG_NETFILTER_XT_TARGET_NFLOG=m
79CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
80CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
81CONFIG_NETFILTER_XT_MATCH_COMMENT=m
82CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
83CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
84CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
85CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
86CONFIG_NETFILTER_XT_MATCH_DCCP=m
87CONFIG_NETFILTER_XT_MATCH_DSCP=m
88CONFIG_NETFILTER_XT_MATCH_ESP=m
89CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
90CONFIG_NETFILTER_XT_MATCH_HELPER=m
91CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
92CONFIG_NETFILTER_XT_MATCH_LENGTH=m
93CONFIG_NETFILTER_XT_MATCH_LIMIT=m
94CONFIG_NETFILTER_XT_MATCH_MAC=m
95CONFIG_NETFILTER_XT_MATCH_MARK=m
96CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
97CONFIG_NETFILTER_XT_MATCH_OWNER=m
98CONFIG_NETFILTER_XT_MATCH_POLICY=m
99CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
100CONFIG_NETFILTER_XT_MATCH_QUOTA=m
101CONFIG_NETFILTER_XT_MATCH_RATEEST=m
102CONFIG_NETFILTER_XT_MATCH_REALM=m
103CONFIG_NETFILTER_XT_MATCH_RECENT=m
104CONFIG_NETFILTER_XT_MATCH_SCTP=m
105CONFIG_NETFILTER_XT_MATCH_STATE=m
106CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
107CONFIG_NETFILTER_XT_MATCH_STRING=m
108CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
109CONFIG_NETFILTER_XT_MATCH_TIME=m
110CONFIG_NETFILTER_XT_MATCH_U32=m
111CONFIG_NF_CONNTRACK_IPV4=m
112CONFIG_IP_NF_IPTABLES=m
113CONFIG_IP_NF_MATCH_AH=m
114CONFIG_IP_NF_MATCH_ECN=m
115CONFIG_IP_NF_MATCH_TTL=m
116CONFIG_IP_NF_FILTER=m
117CONFIG_IP_NF_TARGET_REJECT=m
118CONFIG_IP_NF_TARGET_ULOG=m
119CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 70CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
120CONFIG_DEVTMPFS=y 71CONFIG_DEVTMPFS=y
121CONFIG_DEVTMPFS_MOUNT=y 72CONFIG_DEVTMPFS_MOUNT=y
@@ -353,3 +304,5 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
353CONFIG_VIRTUALIZATION=y 304CONFIG_VIRTUALIZATION=y
354CONFIG_KVM_BOOK3S_64=m 305CONFIG_KVM_BOOK3S_64=m
355CONFIG_KVM_BOOK3S_64_HV=y 306CONFIG_KVM_BOOK3S_64_HV=y
307CONFIG_TRANSPARENT_HUGEPAGE=y
308CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
diff --git a/arch/powerpc/configs/pseries_le_defconfig b/arch/powerpc/configs/pseries_le_defconfig
index 62771e0adb7c..3c84f9d87980 100644
--- a/arch/powerpc/configs/pseries_le_defconfig
+++ b/arch/powerpc/configs/pseries_le_defconfig
@@ -67,57 +67,8 @@ CONFIG_INET_ESP=m
67CONFIG_INET_IPCOMP=m 67CONFIG_INET_IPCOMP=m
68# CONFIG_IPV6 is not set 68# CONFIG_IPV6 is not set
69CONFIG_NETFILTER=y 69CONFIG_NETFILTER=y
70CONFIG_NF_CONNTRACK=m 70# CONFIG_NETFILTER_ADVANCED is not set
71CONFIG_NF_CONNTRACK_EVENTS=y 71CONFIG_BRIDGE=m
72CONFIG_NF_CT_PROTO_UDPLITE=m
73CONFIG_NF_CONNTRACK_FTP=m
74CONFIG_NF_CONNTRACK_IRC=m
75CONFIG_NF_CONNTRACK_TFTP=m
76CONFIG_NF_CT_NETLINK=m
77CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
78CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
79CONFIG_NETFILTER_XT_TARGET_MARK=m
80CONFIG_NETFILTER_XT_TARGET_NFLOG=m
81CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
82CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
83CONFIG_NETFILTER_XT_MATCH_COMMENT=m
84CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
85CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
86CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
87CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
88CONFIG_NETFILTER_XT_MATCH_DCCP=m
89CONFIG_NETFILTER_XT_MATCH_DSCP=m
90CONFIG_NETFILTER_XT_MATCH_ESP=m
91CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
92CONFIG_NETFILTER_XT_MATCH_HELPER=m
93CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
94CONFIG_NETFILTER_XT_MATCH_LENGTH=m
95CONFIG_NETFILTER_XT_MATCH_LIMIT=m
96CONFIG_NETFILTER_XT_MATCH_MAC=m
97CONFIG_NETFILTER_XT_MATCH_MARK=m
98CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
99CONFIG_NETFILTER_XT_MATCH_OWNER=m
100CONFIG_NETFILTER_XT_MATCH_POLICY=m
101CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
102CONFIG_NETFILTER_XT_MATCH_QUOTA=m
103CONFIG_NETFILTER_XT_MATCH_RATEEST=m
104CONFIG_NETFILTER_XT_MATCH_REALM=m
105CONFIG_NETFILTER_XT_MATCH_RECENT=m
106CONFIG_NETFILTER_XT_MATCH_SCTP=m
107CONFIG_NETFILTER_XT_MATCH_STATE=m
108CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
109CONFIG_NETFILTER_XT_MATCH_STRING=m
110CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
111CONFIG_NETFILTER_XT_MATCH_TIME=m
112CONFIG_NETFILTER_XT_MATCH_U32=m
113CONFIG_NF_CONNTRACK_IPV4=m
114CONFIG_IP_NF_IPTABLES=m
115CONFIG_IP_NF_MATCH_AH=m
116CONFIG_IP_NF_MATCH_ECN=m
117CONFIG_IP_NF_MATCH_TTL=m
118CONFIG_IP_NF_FILTER=m
119CONFIG_IP_NF_TARGET_REJECT=m
120CONFIG_IP_NF_TARGET_ULOG=m
121CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 72CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
122CONFIG_DEVTMPFS=y 73CONFIG_DEVTMPFS=y
123CONFIG_DEVTMPFS_MOUNT=y 74CONFIG_DEVTMPFS_MOUNT=y
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index a613d2c82fd9..b142b8e0ed9e 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -8,7 +8,11 @@
8#include <linux/sched.h> 8#include <linux/sched.h>
9 9
10#define COMPAT_USER_HZ 100 10#define COMPAT_USER_HZ 100
11#ifdef __BIG_ENDIAN__
11#define COMPAT_UTS_MACHINE "ppc\0\0" 12#define COMPAT_UTS_MACHINE "ppc\0\0"
13#else
14#define COMPAT_UTS_MACHINE "ppcle\0\0"
15#endif
12 16
13typedef u32 compat_size_t; 17typedef u32 compat_size_t;
14typedef s32 compat_ssize_t; 18typedef s32 compat_ssize_t;
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 617cc767c076..bc2347774f0a 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -189,6 +189,7 @@ extern const char *powerpc_base_platform;
189#define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000) 189#define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000)
190#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) 190#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000)
191#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) 191#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000)
192#define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000)
192 193
193#ifndef __ASSEMBLY__ 194#ifndef __ASSEMBLY__
194 195
@@ -445,6 +446,7 @@ extern const char *powerpc_base_platform;
445 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ 446 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
446 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ 447 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
447 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP) 448 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
449#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
448#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 450#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
449 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 451 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
450 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 452 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -466,8 +468,8 @@ extern const char *powerpc_base_platform;
466#define CPU_FTRS_POSSIBLE \ 468#define CPU_FTRS_POSSIBLE \
467 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \ 469 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
468 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \ 470 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
469 CPU_FTRS_POWER7 | CPU_FTRS_POWER8 | CPU_FTRS_CELL | \ 471 CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
470 CPU_FTRS_PA6T | CPU_FTR_VSX) 472 CPU_FTRS_CELL | CPU_FTRS_PA6T | CPU_FTR_VSX)
471#endif 473#endif
472#else 474#else
473enum { 475enum {
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 66830618cc19..aeaa56cd9b54 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -147,6 +147,14 @@ BEGIN_FTR_SECTION_NESTED(943) \
147END_FTR_SECTION_NESTED(ftr,ftr,943) 147END_FTR_SECTION_NESTED(ftr,ftr,943)
148 148
149/* 149/*
150 * Set an SPR from a register if the CPU has the given feature
151 */
152#define OPT_SET_SPR(ra, spr, ftr) \
153BEGIN_FTR_SECTION_NESTED(943) \
154 mtspr spr,ra; \
155END_FTR_SECTION_NESTED(ftr,ftr,943)
156
157/*
150 * Save a register to the PACA if the CPU has the given feature 158 * Save a register to the PACA if the CPU has the given feature
151 */ 159 */
152#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr) \ 160#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr) \
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index d8b600b3f058..5dbbb29f5c3e 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -274,6 +274,11 @@
274/* Platform specific hcalls, used by KVM */ 274/* Platform specific hcalls, used by KVM */
275#define H_RTAS 0xf000 275#define H_RTAS 0xf000
276 276
277/* "Platform specific hcalls", provided by PHYP */
278#define H_GET_24X7_CATALOG_PAGE 0xF078
279#define H_GET_24X7_DATA 0xF07C
280#define H_GET_PERF_COUNTER_INFO 0xF080
281
277#ifndef __ASSEMBLY__ 282#ifndef __ASSEMBLY__
278 283
279/** 284/**
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 2636acfcd340..ffafab037ba8 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -83,6 +83,8 @@ extern int opal_enter_rtas(struct rtas_args *args,
83#define OPAL_INTERNAL_ERROR -11 83#define OPAL_INTERNAL_ERROR -11
84#define OPAL_BUSY_EVENT -12 84#define OPAL_BUSY_EVENT -12
85#define OPAL_HARDWARE_FROZEN -13 85#define OPAL_HARDWARE_FROZEN -13
86#define OPAL_WRONG_STATE -14
87#define OPAL_ASYNC_COMPLETION -15
86 88
87/* API Tokens (in r0) */ 89/* API Tokens (in r0) */
88#define OPAL_CONSOLE_WRITE 1 90#define OPAL_CONSOLE_WRITE 1
@@ -165,8 +167,11 @@ extern int opal_enter_rtas(struct rtas_args *args,
165#define OPAL_DUMP_ACK 84 167#define OPAL_DUMP_ACK 84
166#define OPAL_GET_MSG 85 168#define OPAL_GET_MSG 85
167#define OPAL_CHECK_ASYNC_COMPLETION 86 169#define OPAL_CHECK_ASYNC_COMPLETION 86
168#define OPAL_DUMP_RESEND 91
169#define OPAL_SYNC_HOST_REBOOT 87 170#define OPAL_SYNC_HOST_REBOOT 87
171#define OPAL_SENSOR_READ 88
172#define OPAL_GET_PARAM 89
173#define OPAL_SET_PARAM 90
174#define OPAL_DUMP_RESEND 91
170#define OPAL_DUMP_INFO2 94 175#define OPAL_DUMP_INFO2 94
171 176
172#ifndef __ASSEMBLY__ 177#ifndef __ASSEMBLY__
@@ -253,7 +258,9 @@ enum OpalPendingState {
253}; 258};
254 259
255enum OpalMessageType { 260enum OpalMessageType {
256 OPAL_MSG_ASYNC_COMP = 0, 261 OPAL_MSG_ASYNC_COMP = 0, /* params[0] = token, params[1] = rc,
262 * additional params function-specific
263 */
257 OPAL_MSG_MEM_ERR, 264 OPAL_MSG_MEM_ERR,
258 OPAL_MSG_EPOW, 265 OPAL_MSG_EPOW,
259 OPAL_MSG_SHUTDOWN, 266 OPAL_MSG_SHUTDOWN,
@@ -406,6 +413,13 @@ enum OpalLPCAddressType {
406 OPAL_LPC_FW = 2, 413 OPAL_LPC_FW = 2,
407}; 414};
408 415
416/* System parameter permission */
417enum OpalSysparamPerm {
418 OPAL_SYSPARAM_READ = 0x1,
419 OPAL_SYSPARAM_WRITE = 0x2,
420 OPAL_SYSPARAM_RW = (OPAL_SYSPARAM_READ | OPAL_SYSPARAM_WRITE),
421};
422
409struct opal_msg { 423struct opal_msg {
410 uint32_t msg_type; 424 uint32_t msg_type;
411 uint32_t reserved; 425 uint32_t reserved;
@@ -855,6 +869,12 @@ int64_t opal_dump_resend_notification(void);
855int64_t opal_get_msg(uint64_t buffer, size_t size); 869int64_t opal_get_msg(uint64_t buffer, size_t size);
856int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); 870int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
857int64_t opal_sync_host_reboot(void); 871int64_t opal_sync_host_reboot(void);
872int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
873 size_t length);
874int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
875 size_t length);
876int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
877 uint32_t *sensor_data);
858 878
859/* Internal functions */ 879/* Internal functions */
860extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); 880extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
@@ -880,6 +900,13 @@ extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val);
880extern int opal_get_chars(uint32_t vtermno, char *buf, int count); 900extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
881extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); 901extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
882 902
903extern int __opal_async_get_token(void);
904extern int opal_async_get_token_interruptible(void);
905extern int __opal_async_release_token(int token);
906extern int opal_async_release_token(int token);
907extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg);
908extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
909
883extern void hvc_opal_init_early(void); 910extern void hvc_opal_init_early(void);
884 911
885struct rtc_time; 912struct rtc_time;
@@ -890,6 +917,7 @@ extern void opal_nvram_init(void);
890extern void opal_flash_init(void); 917extern void opal_flash_init(void);
891extern int opal_elog_init(void); 918extern int opal_elog_init(void);
892extern void opal_platform_dump_init(void); 919extern void opal_platform_dump_init(void);
920extern void opal_sys_param_init(void);
893 921
894extern int opal_machine_check(struct pt_regs *regs); 922extern int opal_machine_check(struct pt_regs *regs);
895extern bool opal_mce_check_early_recovery(struct pt_regs *regs); 923extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 3fd2f1b6f906..9ed737146dbb 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -14,6 +14,7 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <uapi/asm/perf_event.h> 15#include <uapi/asm/perf_event.h>
16 16
17/* Update perf_event_print_debug() if this changes */
17#define MAX_HWEVENTS 8 18#define MAX_HWEVENTS 8
18#define MAX_EVENT_ALTERNATIVES 8 19#define MAX_EVENT_ALTERNATIVES 8
19#define MAX_LIMITED_HWCOUNTERS 2 20#define MAX_LIMITED_HWCOUNTERS 2
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index f7251c2dc049..1a36b8ede417 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -668,12 +668,14 @@
668#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */ 668#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
669#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */ 669#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */
670#define MMCR0_TBEE 0x00400000UL /* time base exception enable */ 670#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
671#define MMCR0_BHRBA 0x00200000UL /* BHRB Access allowed in userspace */
671#define MMCR0_EBE 0x00100000UL /* Event based branch enable */ 672#define MMCR0_EBE 0x00100000UL /* Event based branch enable */
672#define MMCR0_PMCC 0x000c0000UL /* PMC control */ 673#define MMCR0_PMCC 0x000c0000UL /* PMC control */
673#define MMCR0_PMCC_U6 0x00080000UL /* PMC1-6 are R/W by user (PR) */ 674#define MMCR0_PMCC_U6 0x00080000UL /* PMC1-6 are R/W by user (PR) */
674#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/ 675#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
675#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/ 676#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/
676#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */ 677#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
678#define MMCR0_PMAO_SYNC 0x00000800UL /* PMU interrupt is synchronous */
677#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */ 679#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
678#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */ 680#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */
679#define MMCR0_FC56 0x00000010UL /* freeze counters 5 and 6 */ 681#define MMCR0_FC56 0x00000010UL /* freeze counters 5 and 6 */
@@ -707,6 +709,7 @@
707#define SPRN_EBBHR 804 /* Event based branch handler register */ 709#define SPRN_EBBHR 804 /* Event based branch handler register */
708#define SPRN_EBBRR 805 /* Event based branch return register */ 710#define SPRN_EBBRR 805 /* Event based branch return register */
709#define SPRN_BESCR 806 /* Branch event status and control register */ 711#define SPRN_BESCR 806 /* Branch event status and control register */
712#define BESCR_GE 0x8000000000000000ULL /* Global Enable */
710#define SPRN_WORT 895 /* Workload optimization register - thread */ 713#define SPRN_WORT 895 /* Workload optimization register - thread */
711 714
712#define SPRN_PMC1 787 715#define SPRN_PMC1 787
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6c8dd5da4de5..c1faade6506d 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -510,7 +510,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
510 .pvr_mask = 0xffff0000, 510 .pvr_mask = 0xffff0000,
511 .pvr_value = 0x004b0000, 511 .pvr_value = 0x004b0000,
512 .cpu_name = "POWER8E (raw)", 512 .cpu_name = "POWER8E (raw)",
513 .cpu_features = CPU_FTRS_POWER8, 513 .cpu_features = CPU_FTRS_POWER8E,
514 .cpu_user_features = COMMON_USER_POWER8, 514 .cpu_user_features = COMMON_USER_POWER8,
515 .cpu_user_features2 = COMMON_USER2_POWER8, 515 .cpu_user_features2 = COMMON_USER2_POWER8,
516 .mmu_features = MMU_FTRS_POWER8, 516 .mmu_features = MMU_FTRS_POWER8,
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 38d507306a11..4c34c3c827ad 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -164,13 +164,18 @@ BEGIN_FTR_SECTION
164 */ 164 */
165 mfspr r13,SPRN_SRR1 165 mfspr r13,SPRN_SRR1
166 rlwinm. r13,r13,47-31,30,31 166 rlwinm. r13,r13,47-31,30,31
167 OPT_GET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
167 beq 9f 168 beq 9f
168 169
170 mfspr r13,SPRN_SRR1
171 rlwinm. r13,r13,47-31,30,31
169 /* waking up from powersave (nap) state */ 172 /* waking up from powersave (nap) state */
170 cmpwi cr1,r13,2 173 cmpwi cr1,r13,2
171 /* Total loss of HV state is fatal. let's just stay stuck here */ 174 /* Total loss of HV state is fatal. let's just stay stuck here */
175 OPT_GET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
172 bgt cr1,. 176 bgt cr1,.
1739: 1779:
178 OPT_SET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
174END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) 179END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
175#endif /* CONFIG_PPC_P7_NAP */ 180#endif /* CONFIG_PPC_P7_NAP */
176 EXCEPTION_PROLOG_0(PACA_EXMC) 181 EXCEPTION_PROLOG_0(PACA_EXMC)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 4cf674d7d5ae..f386296ff378 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -1013,12 +1013,13 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
1013 return NULL; 1013 return NULL;
1014} 1014}
1015 1015
1016/* We assume to be passed big endian arguments */
1016asmlinkage int ppc_rtas(struct rtas_args __user *uargs) 1017asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1017{ 1018{
1018 struct rtas_args args; 1019 struct rtas_args args;
1019 unsigned long flags; 1020 unsigned long flags;
1020 char *buff_copy, *errbuf = NULL; 1021 char *buff_copy, *errbuf = NULL;
1021 int nargs; 1022 int nargs, nret, token;
1022 int rc; 1023 int rc;
1023 1024
1024 if (!capable(CAP_SYS_ADMIN)) 1025 if (!capable(CAP_SYS_ADMIN))
@@ -1027,10 +1028,13 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1027 if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0) 1028 if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
1028 return -EFAULT; 1029 return -EFAULT;
1029 1030
1030 nargs = args.nargs; 1031 nargs = be32_to_cpu(args.nargs);
1032 nret = be32_to_cpu(args.nret);
1033 token = be32_to_cpu(args.token);
1034
1031 if (nargs > ARRAY_SIZE(args.args) 1035 if (nargs > ARRAY_SIZE(args.args)
1032 || args.nret > ARRAY_SIZE(args.args) 1036 || nret > ARRAY_SIZE(args.args)
1033 || nargs + args.nret > ARRAY_SIZE(args.args)) 1037 || nargs + nret > ARRAY_SIZE(args.args))
1034 return -EINVAL; 1038 return -EINVAL;
1035 1039
1036 /* Copy in args. */ 1040 /* Copy in args. */
@@ -1038,14 +1042,14 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1038 nargs * sizeof(rtas_arg_t)) != 0) 1042 nargs * sizeof(rtas_arg_t)) != 0)
1039 return -EFAULT; 1043 return -EFAULT;
1040 1044
1041 if (args.token == RTAS_UNKNOWN_SERVICE) 1045 if (token == RTAS_UNKNOWN_SERVICE)
1042 return -EINVAL; 1046 return -EINVAL;
1043 1047
1044 args.rets = &args.args[nargs]; 1048 args.rets = &args.args[nargs];
1045 memset(args.rets, 0, args.nret * sizeof(rtas_arg_t)); 1049 memset(args.rets, 0, nret * sizeof(rtas_arg_t));
1046 1050
1047 /* Need to handle ibm,suspend_me call specially */ 1051 /* Need to handle ibm,suspend_me call specially */
1048 if (args.token == ibm_suspend_me_token) { 1052 if (token == ibm_suspend_me_token) {
1049 rc = rtas_ibm_suspend_me(&args); 1053 rc = rtas_ibm_suspend_me(&args);
1050 if (rc) 1054 if (rc)
1051 return rc; 1055 return rc;
@@ -1062,7 +1066,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1062 1066
1063 /* A -1 return code indicates that the last command couldn't 1067 /* A -1 return code indicates that the last command couldn't
1064 be completed due to a hardware error. */ 1068 be completed due to a hardware error. */
1065 if (args.rets[0] == -1) 1069 if (be32_to_cpu(args.rets[0]) == -1)
1066 errbuf = __fetch_rtas_last_error(buff_copy); 1070 errbuf = __fetch_rtas_last_error(buff_copy);
1067 1071
1068 unlock_rtas(flags); 1072 unlock_rtas(flags);
@@ -1077,7 +1081,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1077 /* Copy out args. */ 1081 /* Copy out args. */
1078 if (copy_to_user(uargs->args + nargs, 1082 if (copy_to_user(uargs->args + nargs,
1079 args.args + nargs, 1083 args.args + nargs,
1080 args.nret * sizeof(rtas_arg_t)) != 0) 1084 nret * sizeof(rtas_arg_t)) != 0)
1081 return -EFAULT; 1085 return -EFAULT;
1082 1086
1083 return 0; 1087 return 0;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 33cd7a0b8e73..df86f0ce2d36 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1379,8 +1379,9 @@ void facility_unavailable_exception(struct pt_regs *regs)
1379 if (!arch_irq_disabled_regs(regs)) 1379 if (!arch_irq_disabled_regs(regs))
1380 local_irq_enable(); 1380 local_irq_enable();
1381 1381
1382 pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", 1382 pr_err_ratelimited(
1383 hv ? "Hypervisor " : "", facility, regs->nip, regs->msr); 1383 "%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n",
1384 hv ? "Hypervisor " : "", facility, regs->nip, regs->msr);
1384 1385
1385 if (user_mode(regs)) { 1386 if (user_mode(regs)) {
1386 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 1387 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 62bf5e8e78da..f6ce1f111f5b 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -647,6 +647,11 @@ void pmdp_splitting_flush(struct vm_area_struct *vma,
647 if (old & _PAGE_HASHPTE) 647 if (old & _PAGE_HASHPTE)
648 hpte_do_hugepage_flush(vma->vm_mm, address, pmdp); 648 hpte_do_hugepage_flush(vma->vm_mm, address, pmdp);
649 } 649 }
650 /*
651 * This ensures that generic code that rely on IRQ disabling
652 * to prevent a parallel THP split work as expected.
653 */
654 kick_all_cpus_sync();
650} 655}
651 656
652/* 657/*
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 60d71eea919c..f9c083a5652a 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -11,5 +11,7 @@ obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
11obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o 11obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
12obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o 12obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o
13 13
14obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o
15
14obj-$(CONFIG_PPC64) += $(obj64-y) 16obj-$(CONFIG_PPC64) += $(obj64-y)
15obj-$(CONFIG_PPC32) += $(obj32-y) 17obj-$(CONFIG_PPC32) += $(obj32-y)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 67cf22083f4c..4520c9356b54 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -78,6 +78,7 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;
78#define MMCR0_FC56 0 78#define MMCR0_FC56 0
79#define MMCR0_PMAO 0 79#define MMCR0_PMAO 0
80#define MMCR0_EBE 0 80#define MMCR0_EBE 0
81#define MMCR0_BHRBA 0
81#define MMCR0_PMCC 0 82#define MMCR0_PMCC 0
82#define MMCR0_PMCC_U6 0 83#define MMCR0_PMCC_U6 0
83 84
@@ -120,6 +121,7 @@ static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
120static inline void power_pmu_bhrb_disable(struct perf_event *event) {} 121static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
121void power_pmu_flush_branch_stack(void) {} 122void power_pmu_flush_branch_stack(void) {}
122static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} 123static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
124static void pmao_restore_workaround(bool ebb) { }
123#endif /* CONFIG_PPC32 */ 125#endif /* CONFIG_PPC32 */
124 126
125static bool regs_use_siar(struct pt_regs *regs) 127static bool regs_use_siar(struct pt_regs *regs)
@@ -502,8 +504,11 @@ static int ebb_event_check(struct perf_event *event)
502 if (!leader->attr.pinned || !leader->attr.exclusive) 504 if (!leader->attr.pinned || !leader->attr.exclusive)
503 return -EINVAL; 505 return -EINVAL;
504 506
505 if (event->attr.inherit || event->attr.sample_period || 507 if (event->attr.freq ||
506 event->attr.enable_on_exec || event->attr.freq) 508 event->attr.inherit ||
509 event->attr.sample_type ||
510 event->attr.sample_period ||
511 event->attr.enable_on_exec)
507 return -EINVAL; 512 return -EINVAL;
508 } 513 }
509 514
@@ -542,13 +547,21 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
542 if (!ebb) 547 if (!ebb)
543 goto out; 548 goto out;
544 549
545 /* Enable EBB and read/write to all 6 PMCs for userspace */ 550 /* Enable EBB and read/write to all 6 PMCs and BHRB for userspace */
546 mmcr0 |= MMCR0_EBE | MMCR0_PMCC_U6; 551 mmcr0 |= MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC_U6;
547 552
548 /* Add any bits from the user reg, FC or PMAO */ 553 /*
554 * Add any bits from the user MMCR0, FC or PMAO. This is compatible
555 * with pmao_restore_workaround() because we may add PMAO but we never
556 * clear it here.
557 */
549 mmcr0 |= current->thread.mmcr0; 558 mmcr0 |= current->thread.mmcr0;
550 559
551 /* Be careful not to set PMXE if userspace had it cleared */ 560 /*
561 * Be careful not to set PMXE if userspace had it cleared. This is also
562 * compatible with pmao_restore_workaround() because it has already
563 * cleared PMXE and we leave PMAO alone.
564 */
552 if (!(current->thread.mmcr0 & MMCR0_PMXE)) 565 if (!(current->thread.mmcr0 & MMCR0_PMXE))
553 mmcr0 &= ~MMCR0_PMXE; 566 mmcr0 &= ~MMCR0_PMXE;
554 567
@@ -559,13 +572,94 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
559out: 572out:
560 return mmcr0; 573 return mmcr0;
561} 574}
562#endif /* CONFIG_PPC64 */
563
564static void perf_event_interrupt(struct pt_regs *regs);
565 575
566void perf_event_print_debug(void) 576static void pmao_restore_workaround(bool ebb)
567{ 577{
578 unsigned pmcs[6];
579
580 if (!cpu_has_feature(CPU_FTR_PMAO_BUG))
581 return;
582
583 /*
584 * On POWER8E there is a hardware defect which affects the PMU context
585 * switch logic, ie. power_pmu_disable/enable().
586 *
587 * When a counter overflows PMXE is cleared and FC/PMAO is set in MMCR0
588 * by the hardware. Sometime later the actual PMU exception is
589 * delivered.
590 *
591 * If we context switch, or simply disable/enable, the PMU prior to the
592 * exception arriving, the exception will be lost when we clear PMAO.
593 *
594 * When we reenable the PMU, we will write the saved MMCR0 with PMAO
595 * set, and this _should_ generate an exception. However because of the
596 * defect no exception is generated when we write PMAO, and we get
597 * stuck with no counters counting but no exception delivered.
598 *
599 * The workaround is to detect this case and tweak the hardware to
600 * create another pending PMU exception.
601 *
602 * We do that by setting up PMC6 (cycles) for an imminent overflow and
603 * enabling the PMU. That causes a new exception to be generated in the
604 * chip, but we don't take it yet because we have interrupts hard
605 * disabled. We then write back the PMU state as we want it to be seen
606 * by the exception handler. When we reenable interrupts the exception
607 * handler will be called and see the correct state.
608 *
609 * The logic is the same for EBB, except that the exception is gated by
610 * us having interrupts hard disabled as well as the fact that we are
611 * not in userspace. The exception is finally delivered when we return
612 * to userspace.
613 */
614
615 /* Only if PMAO is set and PMAO_SYNC is clear */
616 if ((current->thread.mmcr0 & (MMCR0_PMAO | MMCR0_PMAO_SYNC)) != MMCR0_PMAO)
617 return;
618
619 /* If we're doing EBB, only if BESCR[GE] is set */
620 if (ebb && !(current->thread.bescr & BESCR_GE))
621 return;
622
623 /*
624 * We are already soft-disabled in power_pmu_enable(). We need to hard
625 * enable to actually prevent the PMU exception from firing.
626 */
627 hard_irq_disable();
628
629 /*
630 * This is a bit gross, but we know we're on POWER8E and have 6 PMCs.
631 * Using read/write_pmc() in a for loop adds 12 function calls and
632 * almost doubles our code size.
633 */
634 pmcs[0] = mfspr(SPRN_PMC1);
635 pmcs[1] = mfspr(SPRN_PMC2);
636 pmcs[2] = mfspr(SPRN_PMC3);
637 pmcs[3] = mfspr(SPRN_PMC4);
638 pmcs[4] = mfspr(SPRN_PMC5);
639 pmcs[5] = mfspr(SPRN_PMC6);
640
641 /* Ensure all freeze bits are unset */
642 mtspr(SPRN_MMCR2, 0);
643
644 /* Set up PMC6 to overflow in one cycle */
645 mtspr(SPRN_PMC6, 0x7FFFFFFE);
646
647 /* Enable exceptions and unfreeze PMC6 */
648 mtspr(SPRN_MMCR0, MMCR0_PMXE | MMCR0_PMCjCE | MMCR0_PMAO);
649
650 /* Now we need to refreeze and restore the PMCs */
651 mtspr(SPRN_MMCR0, MMCR0_FC | MMCR0_PMAO);
652
653 mtspr(SPRN_PMC1, pmcs[0]);
654 mtspr(SPRN_PMC2, pmcs[1]);
655 mtspr(SPRN_PMC3, pmcs[2]);
656 mtspr(SPRN_PMC4, pmcs[3]);
657 mtspr(SPRN_PMC5, pmcs[4]);
658 mtspr(SPRN_PMC6, pmcs[5]);
568} 659}
660#endif /* CONFIG_PPC64 */
661
662static void perf_event_interrupt(struct pt_regs *regs);
569 663
570/* 664/*
571 * Read one performance monitor counter (PMC). 665 * Read one performance monitor counter (PMC).
@@ -645,6 +739,57 @@ static void write_pmc(int idx, unsigned long val)
645 } 739 }
646} 740}
647 741
742/* Called from sysrq_handle_showregs() */
743void perf_event_print_debug(void)
744{
745 unsigned long sdar, sier, flags;
746 u32 pmcs[MAX_HWEVENTS];
747 int i;
748
749 if (!ppmu->n_counter)
750 return;
751
752 local_irq_save(flags);
753
754 pr_info("CPU: %d PMU registers, ppmu = %s n_counters = %d",
755 smp_processor_id(), ppmu->name, ppmu->n_counter);
756
757 for (i = 0; i < ppmu->n_counter; i++)
758 pmcs[i] = read_pmc(i + 1);
759
760 for (; i < MAX_HWEVENTS; i++)
761 pmcs[i] = 0xdeadbeef;
762
763 pr_info("PMC1: %08x PMC2: %08x PMC3: %08x PMC4: %08x\n",
764 pmcs[0], pmcs[1], pmcs[2], pmcs[3]);
765
766 if (ppmu->n_counter > 4)
767 pr_info("PMC5: %08x PMC6: %08x PMC7: %08x PMC8: %08x\n",
768 pmcs[4], pmcs[5], pmcs[6], pmcs[7]);
769
770 pr_info("MMCR0: %016lx MMCR1: %016lx MMCRA: %016lx\n",
771 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCRA));
772
773 sdar = sier = 0;
774#ifdef CONFIG_PPC64
775 sdar = mfspr(SPRN_SDAR);
776
777 if (ppmu->flags & PPMU_HAS_SIER)
778 sier = mfspr(SPRN_SIER);
779
780 if (ppmu->flags & PPMU_EBB) {
781 pr_info("MMCR2: %016lx EBBHR: %016lx\n",
782 mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
783 pr_info("EBBRR: %016lx BESCR: %016lx\n",
784 mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
785 }
786#endif
787 pr_info("SIAR: %016lx SDAR: %016lx SIER: %016lx\n",
788 mfspr(SPRN_SIAR), sdar, sier);
789
790 local_irq_restore(flags);
791}
792
648/* 793/*
649 * Check if a set of events can all go on the PMU at once. 794 * Check if a set of events can all go on the PMU at once.
650 * If they can't, this will look at alternative codes for the events 795 * If they can't, this will look at alternative codes for the events
@@ -973,11 +1118,12 @@ static void power_pmu_disable(struct pmu *pmu)
973 } 1118 }
974 1119
975 /* 1120 /*
976 * Set the 'freeze counters' bit, clear EBE/PMCC/PMAO/FC56. 1121 * Set the 'freeze counters' bit, clear EBE/BHRBA/PMCC/PMAO/FC56
977 */ 1122 */
978 val = mmcr0 = mfspr(SPRN_MMCR0); 1123 val = mmcr0 = mfspr(SPRN_MMCR0);
979 val |= MMCR0_FC; 1124 val |= MMCR0_FC;
980 val &= ~(MMCR0_EBE | MMCR0_PMCC | MMCR0_PMAO | MMCR0_FC56); 1125 val &= ~(MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC | MMCR0_PMAO |
1126 MMCR0_FC56);
981 1127
982 /* 1128 /*
983 * The barrier is to make sure the mtspr has been 1129 * The barrier is to make sure the mtspr has been
@@ -1144,6 +1290,8 @@ static void power_pmu_enable(struct pmu *pmu)
1144 cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; 1290 cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
1145 1291
1146 out_enable: 1292 out_enable:
1293 pmao_restore_workaround(ebb);
1294
1147 mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]); 1295 mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
1148 1296
1149 mb(); 1297 mb();
diff --git a/arch/powerpc/perf/hv-24x7-catalog.h b/arch/powerpc/perf/hv-24x7-catalog.h
new file mode 100644
index 000000000000..21b19dd86d9c
--- /dev/null
+++ b/arch/powerpc/perf/hv-24x7-catalog.h
@@ -0,0 +1,33 @@
1#ifndef LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_
2#define LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_
3
4#include <linux/types.h>
5
6/* From document "24x7 Event and Group Catalog Formats Proposal" v0.15 */
7
8struct hv_24x7_catalog_page_0 {
9#define HV_24X7_CATALOG_MAGIC 0x32347837 /* "24x7" in ASCII */
10 __be32 magic;
11 __be32 length; /* In 4096 byte pages */
12 __be64 version; /* XXX: arbitrary? what's the meaning/useage/purpose? */
13 __u8 build_time_stamp[16]; /* "YYYYMMDDHHMMSS\0\0" */
14 __u8 reserved2[32];
15 __be16 schema_data_offs; /* in 4096 byte pages */
16 __be16 schema_data_len; /* in 4096 byte pages */
17 __be16 schema_entry_count;
18 __u8 reserved3[2];
19 __be16 event_data_offs;
20 __be16 event_data_len;
21 __be16 event_entry_count;
22 __u8 reserved4[2];
23 __be16 group_data_offs; /* in 4096 byte pages */
24 __be16 group_data_len; /* in 4096 byte pages */
25 __be16 group_entry_count;
26 __u8 reserved5[2];
27 __be16 formula_data_offs; /* in 4096 byte pages */
28 __be16 formula_data_len; /* in 4096 byte pages */
29 __be16 formula_entry_count;
30 __u8 reserved6[2];
31} __packed;
32
33#endif
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
new file mode 100644
index 000000000000..297c91051413
--- /dev/null
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -0,0 +1,510 @@
1/*
2 * Hypervisor supplied "24x7" performance counter support
3 *
4 * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
5 * Copyright 2014 IBM Corporation.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#define pr_fmt(fmt) "hv-24x7: " fmt
14
15#include <linux/perf_event.h>
16#include <linux/module.h>
17#include <linux/slab.h>
18#include <asm/firmware.h>
19#include <asm/hvcall.h>
20#include <asm/io.h>
21
22#include "hv-24x7.h"
23#include "hv-24x7-catalog.h"
24#include "hv-common.h"
25
26/*
27 * TODO: Merging events:
28 * - Think of the hcall as an interface to a 4d array of counters:
29 * - x = domains
30 * - y = indexes in the domain (core, chip, vcpu, node, etc)
31 * - z = offset into the counter space
32 * - w = lpars (guest vms, "logical partitions")
33 * - A single request is: x,y,y_last,z,z_last,w,w_last
34 * - this means we can retrieve a rectangle of counters in y,z for a single x.
35 *
36 * - Things to consider (ignoring w):
37 * - input cost_per_request = 16
38 * - output cost_per_result(ys,zs) = 8 + 8 * ys + ys * zs
39 * - limited number of requests per hcall (must fit into 4K bytes)
40 * - 4k = 16 [buffer header] - 16 [request size] * request_count
41 * - 255 requests per hcall
42 * - sometimes it will be more efficient to read extra data and discard
43 */
44
45/*
46 * Example usage:
47 * perf stat -e 'hv_24x7/domain=2,offset=8,starting_index=0,lpar=0xffffffff/'
48 */
49
50/* u3 0-6, one of HV_24X7_PERF_DOMAIN */
51EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
52/* u16 */
53EVENT_DEFINE_RANGE_FORMAT(starting_index, config, 16, 31);
54/* u32, see "data_offset" */
55EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63);
56/* u16 */
57EVENT_DEFINE_RANGE_FORMAT(lpar, config1, 0, 15);
58
59EVENT_DEFINE_RANGE(reserved1, config, 4, 15);
60EVENT_DEFINE_RANGE(reserved2, config1, 16, 63);
61EVENT_DEFINE_RANGE(reserved3, config2, 0, 63);
62
63static struct attribute *format_attrs[] = {
64 &format_attr_domain.attr,
65 &format_attr_offset.attr,
66 &format_attr_starting_index.attr,
67 &format_attr_lpar.attr,
68 NULL,
69};
70
71static struct attribute_group format_group = {
72 .name = "format",
73 .attrs = format_attrs,
74};
75
76static struct kmem_cache *hv_page_cache;
77
78/*
79 * read_offset_data - copy data from one buffer to another while treating the
80 * source buffer as a small view on the total avaliable
81 * source data.
82 *
83 * @dest: buffer to copy into
84 * @dest_len: length of @dest in bytes
85 * @requested_offset: the offset within the source data we want. Must be > 0
86 * @src: buffer to copy data from
87 * @src_len: length of @src in bytes
88 * @source_offset: the offset in the sorce data that (src,src_len) refers to.
89 * Must be > 0
90 *
91 * returns the number of bytes copied.
92 *
93 * The following ascii art shows the various buffer possitioning we need to
94 * handle, assigns some arbitrary varibles to points on the buffer, and then
95 * shows how we fiddle with those values to get things we care about (copy
96 * start in src and copy len)
97 *
98 * s = @src buffer
99 * d = @dest buffer
100 * '.' areas in d are written to.
101 *
102 * u
103 * x w v z
104 * d |.........|
105 * s |----------------------|
106 *
107 * u
108 * x w z v
109 * d |........------|
110 * s |------------------|
111 *
112 * x w u,z,v
113 * d |........|
114 * s |------------------|
115 *
116 * x,w u,v,z
117 * d |..................|
118 * s |------------------|
119 *
120 * x u
121 * w v z
122 * d |........|
123 * s |------------------|
124 *
125 * x z w v
126 * d |------|
127 * s |------|
128 *
129 * x = source_offset
130 * w = requested_offset
131 * z = source_offset + src_len
132 * v = requested_offset + dest_len
133 *
134 * w_offset_in_s = w - x = requested_offset - source_offset
135 * z_offset_in_s = z - x = src_len
136 * v_offset_in_s = v - x = request_offset + dest_len - src_len
137 */
138static ssize_t read_offset_data(void *dest, size_t dest_len,
139 loff_t requested_offset, void *src,
140 size_t src_len, loff_t source_offset)
141{
142 size_t w_offset_in_s = requested_offset - source_offset;
143 size_t z_offset_in_s = src_len;
144 size_t v_offset_in_s = requested_offset + dest_len - src_len;
145 size_t u_offset_in_s = min(z_offset_in_s, v_offset_in_s);
146 size_t copy_len = u_offset_in_s - w_offset_in_s;
147
148 if (requested_offset < 0 || source_offset < 0)
149 return -EINVAL;
150
151 if (z_offset_in_s <= w_offset_in_s)
152 return 0;
153
154 memcpy(dest, src + w_offset_in_s, copy_len);
155 return copy_len;
156}
157
158static unsigned long h_get_24x7_catalog_page(char page[static 4096],
159 u32 version, u32 index)
160{
161 WARN_ON(!IS_ALIGNED((unsigned long)page, 4096));
162 return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE,
163 virt_to_phys(page),
164 version,
165 index);
166}
167
168static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
169 struct bin_attribute *bin_attr, char *buf,
170 loff_t offset, size_t count)
171{
172 unsigned long hret;
173 ssize_t ret = 0;
174 size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
175 loff_t page_offset = 0;
176 uint32_t catalog_version_num = 0;
177 void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
178 struct hv_24x7_catalog_page_0 *page_0 = page;
179 if (!page)
180 return -ENOMEM;
181
182 hret = h_get_24x7_catalog_page(page, 0, 0);
183 if (hret) {
184 ret = -EIO;
185 goto e_free;
186 }
187
188 catalog_version_num = be32_to_cpu(page_0->version);
189 catalog_page_len = be32_to_cpu(page_0->length);
190 catalog_len = catalog_page_len * 4096;
191
192 page_offset = offset / 4096;
193 page_count = count / 4096;
194
195 if (page_offset >= catalog_page_len)
196 goto e_free;
197
198 if (page_offset != 0) {
199 hret = h_get_24x7_catalog_page(page, catalog_version_num,
200 page_offset);
201 if (hret) {
202 ret = -EIO;
203 goto e_free;
204 }
205 }
206
207 ret = read_offset_data(buf, count, offset,
208 page, 4096, page_offset * 4096);
209e_free:
210 if (hret)
211 pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n",
212 catalog_version_num, page_offset, hret);
213 kfree(page);
214
215 pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n",
216 offset, page_offset, count, page_count, catalog_len,
217 catalog_page_len, ret);
218
219 return ret;
220}
221
222#define PAGE_0_ATTR(_name, _fmt, _expr) \
223static ssize_t _name##_show(struct device *dev, \
224 struct device_attribute *dev_attr, \
225 char *buf) \
226{ \
227 unsigned long hret; \
228 ssize_t ret = 0; \
229 void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); \
230 struct hv_24x7_catalog_page_0 *page_0 = page; \
231 if (!page) \
232 return -ENOMEM; \
233 hret = h_get_24x7_catalog_page(page, 0, 0); \
234 if (hret) { \
235 ret = -EIO; \
236 goto e_free; \
237 } \
238 ret = sprintf(buf, _fmt, _expr); \
239e_free: \
240 kfree(page); \
241 return ret; \
242} \
243static DEVICE_ATTR_RO(_name)
244
245PAGE_0_ATTR(catalog_version, "%lld\n",
246 (unsigned long long)be32_to_cpu(page_0->version));
247PAGE_0_ATTR(catalog_len, "%lld\n",
248 (unsigned long long)be32_to_cpu(page_0->length) * 4096);
249static BIN_ATTR_RO(catalog, 0/* real length varies */);
250
251static struct bin_attribute *if_bin_attrs[] = {
252 &bin_attr_catalog,
253 NULL,
254};
255
256static struct attribute *if_attrs[] = {
257 &dev_attr_catalog_len.attr,
258 &dev_attr_catalog_version.attr,
259 NULL,
260};
261
262static struct attribute_group if_group = {
263 .name = "interface",
264 .bin_attrs = if_bin_attrs,
265 .attrs = if_attrs,
266};
267
268static const struct attribute_group *attr_groups[] = {
269 &format_group,
270 &if_group,
271 NULL,
272};
273
274static bool is_physical_domain(int domain)
275{
276 return domain == HV_24X7_PERF_DOMAIN_PHYSICAL_CHIP ||
277 domain == HV_24X7_PERF_DOMAIN_PHYSICAL_CORE;
278}
279
280static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
281 u16 lpar, u64 *res,
282 bool success_expected)
283{
284 unsigned long ret;
285
286 /*
287 * request_buffer and result_buffer are not required to be 4k aligned,
288 * but are not allowed to cross any 4k boundary. Aligning them to 4k is
289 * the simplest way to ensure that.
290 */
291 struct reqb {
292 struct hv_24x7_request_buffer buf;
293 struct hv_24x7_request req;
294 } __packed __aligned(4096) request_buffer = {
295 .buf = {
296 .interface_version = HV_24X7_IF_VERSION_CURRENT,
297 .num_requests = 1,
298 },
299 .req = {
300 .performance_domain = domain,
301 .data_size = cpu_to_be16(8),
302 .data_offset = cpu_to_be32(offset),
303 .starting_lpar_ix = cpu_to_be16(lpar),
304 .max_num_lpars = cpu_to_be16(1),
305 .starting_ix = cpu_to_be16(ix),
306 .max_ix = cpu_to_be16(1),
307 }
308 };
309
310 struct resb {
311 struct hv_24x7_data_result_buffer buf;
312 struct hv_24x7_result res;
313 struct hv_24x7_result_element elem;
314 __be64 result;
315 } __packed __aligned(4096) result_buffer = {};
316
317 ret = plpar_hcall_norets(H_GET_24X7_DATA,
318 virt_to_phys(&request_buffer), sizeof(request_buffer),
319 virt_to_phys(&result_buffer), sizeof(result_buffer));
320
321 if (ret) {
322 if (success_expected)
323 pr_err_ratelimited("hcall failed: %d %#x %#x %d => 0x%lx (%ld) detail=0x%x failing ix=%x\n",
324 domain, offset, ix, lpar,
325 ret, ret,
326 result_buffer.buf.detailed_rc,
327 result_buffer.buf.failing_request_ix);
328 return ret;
329 }
330
331 *res = be64_to_cpu(result_buffer.result);
332 return ret;
333}
334
335static unsigned long event_24x7_request(struct perf_event *event, u64 *res,
336 bool success_expected)
337{
338 return single_24x7_request(event_get_domain(event),
339 event_get_offset(event),
340 event_get_starting_index(event),
341 event_get_lpar(event),
342 res,
343 success_expected);
344}
345
346static int h_24x7_event_init(struct perf_event *event)
347{
348 struct hv_perf_caps caps;
349 unsigned domain;
350 unsigned long hret;
351 u64 ct;
352
353 /* Not our event */
354 if (event->attr.type != event->pmu->type)
355 return -ENOENT;
356
357 /* Unused areas must be 0 */
358 if (event_get_reserved1(event) ||
359 event_get_reserved2(event) ||
360 event_get_reserved3(event)) {
361 pr_devel("reserved set when forbidden 0x%llx(0x%llx) 0x%llx(0x%llx) 0x%llx(0x%llx)\n",
362 event->attr.config,
363 event_get_reserved1(event),
364 event->attr.config1,
365 event_get_reserved2(event),
366 event->attr.config2,
367 event_get_reserved3(event));
368 return -EINVAL;
369 }
370
371 /* unsupported modes and filters */
372 if (event->attr.exclude_user ||
373 event->attr.exclude_kernel ||
374 event->attr.exclude_hv ||
375 event->attr.exclude_idle ||
376 event->attr.exclude_host ||
377 event->attr.exclude_guest ||
378 is_sampling_event(event)) /* no sampling */
379 return -EINVAL;
380
381 /* no branch sampling */
382 if (has_branch_stack(event))
383 return -EOPNOTSUPP;
384
385 /* offset must be 8 byte aligned */
386 if (event_get_offset(event) % 8) {
387 pr_devel("bad alignment\n");
388 return -EINVAL;
389 }
390
391 /* Domains above 6 are invalid */
392 domain = event_get_domain(event);
393 if (domain > 6) {
394 pr_devel("invalid domain %d\n", domain);
395 return -EINVAL;
396 }
397
398 hret = hv_perf_caps_get(&caps);
399 if (hret) {
400 pr_devel("could not get capabilities: rc=%ld\n", hret);
401 return -EIO;
402 }
403
404 /* PHYSICAL domains & other lpars require extra capabilities */
405 if (!caps.collect_privileged && (is_physical_domain(domain) ||
406 (event_get_lpar(event) != event_get_lpar_max()))) {
407 pr_devel("hv permisions disallow: is_physical_domain:%d, lpar=0x%llx\n",
408 is_physical_domain(domain),
409 event_get_lpar(event));
410 return -EACCES;
411 }
412
413 /* see if the event complains */
414 if (event_24x7_request(event, &ct, false)) {
415 pr_devel("test hcall failed\n");
416 return -EIO;
417 }
418
419 return 0;
420}
421
422static u64 h_24x7_get_value(struct perf_event *event)
423{
424 unsigned long ret;
425 u64 ct;
426 ret = event_24x7_request(event, &ct, true);
427 if (ret)
428 /* We checked this in event init, shouldn't fail here... */
429 return 0;
430
431 return ct;
432}
433
434static void h_24x7_event_update(struct perf_event *event)
435{
436 s64 prev;
437 u64 now;
438 now = h_24x7_get_value(event);
439 prev = local64_xchg(&event->hw.prev_count, now);
440 local64_add(now - prev, &event->count);
441}
442
443static void h_24x7_event_start(struct perf_event *event, int flags)
444{
445 if (flags & PERF_EF_RELOAD)
446 local64_set(&event->hw.prev_count, h_24x7_get_value(event));
447}
448
449static void h_24x7_event_stop(struct perf_event *event, int flags)
450{
451 h_24x7_event_update(event);
452}
453
454static int h_24x7_event_add(struct perf_event *event, int flags)
455{
456 if (flags & PERF_EF_START)
457 h_24x7_event_start(event, flags);
458
459 return 0;
460}
461
462static int h_24x7_event_idx(struct perf_event *event)
463{
464 return 0;
465}
466
467static struct pmu h_24x7_pmu = {
468 .task_ctx_nr = perf_invalid_context,
469
470 .name = "hv_24x7",
471 .attr_groups = attr_groups,
472 .event_init = h_24x7_event_init,
473 .add = h_24x7_event_add,
474 .del = h_24x7_event_stop,
475 .start = h_24x7_event_start,
476 .stop = h_24x7_event_stop,
477 .read = h_24x7_event_update,
478 .event_idx = h_24x7_event_idx,
479};
480
481static int hv_24x7_init(void)
482{
483 int r;
484 unsigned long hret;
485 struct hv_perf_caps caps;
486
487 if (!firmware_has_feature(FW_FEATURE_LPAR)) {
488 pr_info("not a virtualized system, not enabling\n");
489 return -ENODEV;
490 }
491
492 hret = hv_perf_caps_get(&caps);
493 if (hret) {
494 pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
495 hret);
496 return -ENODEV;
497 }
498
499 hv_page_cache = kmem_cache_create("hv-page-4096", 4096, 4096, 0, NULL);
500 if (!hv_page_cache)
501 return -ENOMEM;
502
503 r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1);
504 if (r)
505 return r;
506
507 return 0;
508}
509
510device_initcall(hv_24x7_init);
diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h
new file mode 100644
index 000000000000..720ebce4b435
--- /dev/null
+++ b/arch/powerpc/perf/hv-24x7.h
@@ -0,0 +1,109 @@
1#ifndef LINUX_POWERPC_PERF_HV_24X7_H_
2#define LINUX_POWERPC_PERF_HV_24X7_H_
3
4#include <linux/types.h>
5
6struct hv_24x7_request {
7 /* PHYSICAL domains require enabling via phyp/hmc. */
8#define HV_24X7_PERF_DOMAIN_PHYSICAL_CHIP 0x01
9#define HV_24X7_PERF_DOMAIN_PHYSICAL_CORE 0x02
10#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_CORE 0x03
11#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_CHIP 0x04
12#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_NODE 0x05
13#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_REMOTE_NODE 0x06
14 __u8 performance_domain;
15 __u8 reserved[0x1];
16
17 /* bytes to read starting at @data_offset. must be a multiple of 8 */
18 __be16 data_size;
19
20 /*
21 * byte offset within the perf domain to read from. must be 8 byte
22 * aligned
23 */
24 __be32 data_offset;
25
26 /*
27 * only valid for VIRTUAL_PROCESSOR domains, ignored for others.
28 * -1 means "current partition only"
29 * Enabling via phyp/hmc required for non-"-1" values. 0 forbidden
30 * unless requestor is 0.
31 */
32 __be16 starting_lpar_ix;
33
34 /*
35 * Ignored when @starting_lpar_ix == -1
36 * Ignored when @performance_domain is not VIRTUAL_PROCESSOR_*
37 * -1 means "infinite" or all
38 */
39 __be16 max_num_lpars;
40
41 /* chip, core, or virtual processor based on @performance_domain */
42 __be16 starting_ix;
43 __be16 max_ix;
44} __packed;
45
46struct hv_24x7_request_buffer {
47 /* 0 - ? */
48 /* 1 - ? */
49#define HV_24X7_IF_VERSION_CURRENT 0x01
50 __u8 interface_version;
51 __u8 num_requests;
52 __u8 reserved[0xE];
53 struct hv_24x7_request requests[];
54} __packed;
55
56struct hv_24x7_result_element {
57 __be16 lpar_ix;
58
59 /*
60 * represents the core, chip, or virtual processor based on the
61 * request's @performance_domain
62 */
63 __be16 domain_ix;
64
65 /* -1 if @performance_domain does not refer to a virtual processor */
66 __be32 lpar_cfg_instance_id;
67
68 /* size = @result_element_data_size of cointaining result. */
69 __u8 element_data[];
70} __packed;
71
72struct hv_24x7_result {
73 __u8 result_ix;
74
75 /*
76 * 0 = not all result elements fit into the buffer, additional requests
77 * required
78 * 1 = all result elements were returned
79 */
80 __u8 results_complete;
81 __be16 num_elements_returned;
82
83 /* This is a copy of @data_size from the coresponding hv_24x7_request */
84 __be16 result_element_data_size;
85 __u8 reserved[0x2];
86
87 /* WARNING: only valid for first result element due to variable sizes
88 * of result elements */
89 /* struct hv_24x7_result_element[@num_elements_returned] */
90 struct hv_24x7_result_element elements[];
91} __packed;
92
93struct hv_24x7_data_result_buffer {
94 /* See versioning for request buffer */
95 __u8 interface_version;
96
97 __u8 num_results;
98 __u8 reserved[0x1];
99 __u8 failing_request_ix;
100 __be32 detailed_rc;
101 __be64 cec_cfg_instance_id;
102 __be64 catalog_version_num;
103 __u8 reserved2[0x8];
104 /* WARNING: only valid for the first result due to variable sizes of
105 * results */
106 struct hv_24x7_result results[]; /* [@num_results] */
107} __packed;
108
109#endif
diff --git a/arch/powerpc/perf/hv-common.c b/arch/powerpc/perf/hv-common.c
new file mode 100644
index 000000000000..47e02b366f58
--- /dev/null
+++ b/arch/powerpc/perf/hv-common.c
@@ -0,0 +1,39 @@
1#include <asm/io.h>
2#include <asm/hvcall.h>
3
4#include "hv-gpci.h"
5#include "hv-common.h"
6
7unsigned long hv_perf_caps_get(struct hv_perf_caps *caps)
8{
9 unsigned long r;
10 struct p {
11 struct hv_get_perf_counter_info_params params;
12 struct cv_system_performance_capabilities caps;
13 } __packed __aligned(sizeof(uint64_t));
14
15 struct p arg = {
16 .params = {
17 .counter_request = cpu_to_be32(
18 CIR_SYSTEM_PERFORMANCE_CAPABILITIES),
19 .starting_index = cpu_to_be32(-1),
20 .counter_info_version_in = 0,
21 }
22 };
23
24 r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
25 virt_to_phys(&arg), sizeof(arg));
26
27 if (r)
28 return r;
29
30 pr_devel("capability_mask: 0x%x\n", arg.caps.capability_mask);
31
32 caps->version = arg.params.counter_info_version_out;
33 caps->collect_privileged = !!arg.caps.perf_collect_privileged;
34 caps->ga = !!(arg.caps.capability_mask & CV_CM_GA);
35 caps->expanded = !!(arg.caps.capability_mask & CV_CM_EXPANDED);
36 caps->lab = !!(arg.caps.capability_mask & CV_CM_LAB);
37
38 return r;
39}
diff --git a/arch/powerpc/perf/hv-common.h b/arch/powerpc/perf/hv-common.h
new file mode 100644
index 000000000000..5d79cecbd73d
--- /dev/null
+++ b/arch/powerpc/perf/hv-common.h
@@ -0,0 +1,36 @@
1#ifndef LINUX_POWERPC_PERF_HV_COMMON_H_
2#define LINUX_POWERPC_PERF_HV_COMMON_H_
3
4#include <linux/perf_event.h>
5#include <linux/types.h>
6
7struct hv_perf_caps {
8 u16 version;
9 u16 collect_privileged:1,
10 ga:1,
11 expanded:1,
12 lab:1,
13 unused:12;
14};
15
16unsigned long hv_perf_caps_get(struct hv_perf_caps *caps);
17
18
19#define EVENT_DEFINE_RANGE_FORMAT(name, attr_var, bit_start, bit_end) \
20PMU_FORMAT_ATTR(name, #attr_var ":" #bit_start "-" #bit_end); \
21EVENT_DEFINE_RANGE(name, attr_var, bit_start, bit_end)
22
23#define EVENT_DEFINE_RANGE(name, attr_var, bit_start, bit_end) \
24static u64 event_get_##name##_max(void) \
25{ \
26 BUILD_BUG_ON((bit_start > bit_end) \
27 || (bit_end >= (sizeof(1ull) * 8))); \
28 return (((1ull << (bit_end - bit_start)) - 1) << 1) + 1; \
29} \
30static u64 event_get_##name(struct perf_event *event) \
31{ \
32 return (event->attr.attr_var >> (bit_start)) & \
33 event_get_##name##_max(); \
34}
35
36#endif
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
new file mode 100644
index 000000000000..278ba7b9c2b5
--- /dev/null
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -0,0 +1,294 @@
1/*
2 * Hypervisor supplied "gpci" ("get performance counter info") performance
3 * counter support
4 *
5 * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
6 * Copyright 2014 IBM Corporation.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#define pr_fmt(fmt) "hv-gpci: " fmt
15
16#include <linux/init.h>
17#include <linux/perf_event.h>
18#include <asm/firmware.h>
19#include <asm/hvcall.h>
20#include <asm/io.h>
21
22#include "hv-gpci.h"
23#include "hv-common.h"
24
25/*
26 * Example usage:
27 * perf stat -e 'hv_gpci/counter_info_version=3,offset=0,length=8,
28 * secondary_index=0,starting_index=0xffffffff,request=0x10/' ...
29 */
30
31/* u32 */
32EVENT_DEFINE_RANGE_FORMAT(request, config, 0, 31);
33/* u32 */
34EVENT_DEFINE_RANGE_FORMAT(starting_index, config, 32, 63);
35/* u16 */
36EVENT_DEFINE_RANGE_FORMAT(secondary_index, config1, 0, 15);
37/* u8 */
38EVENT_DEFINE_RANGE_FORMAT(counter_info_version, config1, 16, 23);
39/* u8, bytes of data (1-8) */
40EVENT_DEFINE_RANGE_FORMAT(length, config1, 24, 31);
41/* u32, byte offset */
42EVENT_DEFINE_RANGE_FORMAT(offset, config1, 32, 63);
43
44static struct attribute *format_attrs[] = {
45 &format_attr_request.attr,
46 &format_attr_starting_index.attr,
47 &format_attr_secondary_index.attr,
48 &format_attr_counter_info_version.attr,
49
50 &format_attr_offset.attr,
51 &format_attr_length.attr,
52 NULL,
53};
54
55static struct attribute_group format_group = {
56 .name = "format",
57 .attrs = format_attrs,
58};
59
60#define HV_CAPS_ATTR(_name, _format) \
61static ssize_t _name##_show(struct device *dev, \
62 struct device_attribute *attr, \
63 char *page) \
64{ \
65 struct hv_perf_caps caps; \
66 unsigned long hret = hv_perf_caps_get(&caps); \
67 if (hret) \
68 return -EIO; \
69 \
70 return sprintf(page, _format, caps._name); \
71} \
72static struct device_attribute hv_caps_attr_##_name = __ATTR_RO(_name)
73
74static ssize_t kernel_version_show(struct device *dev,
75 struct device_attribute *attr,
76 char *page)
77{
78 return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT);
79}
80
81DEVICE_ATTR_RO(kernel_version);
82HV_CAPS_ATTR(version, "0x%x\n");
83HV_CAPS_ATTR(ga, "%d\n");
84HV_CAPS_ATTR(expanded, "%d\n");
85HV_CAPS_ATTR(lab, "%d\n");
86HV_CAPS_ATTR(collect_privileged, "%d\n");
87
88static struct attribute *interface_attrs[] = {
89 &dev_attr_kernel_version.attr,
90 &hv_caps_attr_version.attr,
91 &hv_caps_attr_ga.attr,
92 &hv_caps_attr_expanded.attr,
93 &hv_caps_attr_lab.attr,
94 &hv_caps_attr_collect_privileged.attr,
95 NULL,
96};
97
98static struct attribute_group interface_group = {
99 .name = "interface",
100 .attrs = interface_attrs,
101};
102
103static const struct attribute_group *attr_groups[] = {
104 &format_group,
105 &interface_group,
106 NULL,
107};
108
109#define GPCI_MAX_DATA_BYTES \
110 (1024 - sizeof(struct hv_get_perf_counter_info_params))
111
112static unsigned long single_gpci_request(u32 req, u32 starting_index,
113 u16 secondary_index, u8 version_in, u32 offset, u8 length,
114 u64 *value)
115{
116 unsigned long ret;
117 size_t i;
118 u64 count;
119
120 struct {
121 struct hv_get_perf_counter_info_params params;
122 uint8_t bytes[GPCI_MAX_DATA_BYTES];
123 } __packed __aligned(sizeof(uint64_t)) arg = {
124 .params = {
125 .counter_request = cpu_to_be32(req),
126 .starting_index = cpu_to_be32(starting_index),
127 .secondary_index = cpu_to_be16(secondary_index),
128 .counter_info_version_in = version_in,
129 }
130 };
131
132 ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
133 virt_to_phys(&arg), sizeof(arg));
134 if (ret) {
135 pr_devel("hcall failed: 0x%lx\n", ret);
136 return ret;
137 }
138
139 /*
140 * we verify offset and length are within the zeroed buffer at event
141 * init.
142 */
143 count = 0;
144 for (i = offset; i < offset + length; i++)
145 count |= arg.bytes[i] << (i - offset);
146
147 *value = count;
148 return ret;
149}
150
151static u64 h_gpci_get_value(struct perf_event *event)
152{
153 u64 count;
154 unsigned long ret = single_gpci_request(event_get_request(event),
155 event_get_starting_index(event),
156 event_get_secondary_index(event),
157 event_get_counter_info_version(event),
158 event_get_offset(event),
159 event_get_length(event),
160 &count);
161 if (ret)
162 return 0;
163 return count;
164}
165
166static void h_gpci_event_update(struct perf_event *event)
167{
168 s64 prev;
169 u64 now = h_gpci_get_value(event);
170 prev = local64_xchg(&event->hw.prev_count, now);
171 local64_add(now - prev, &event->count);
172}
173
174static void h_gpci_event_start(struct perf_event *event, int flags)
175{
176 local64_set(&event->hw.prev_count, h_gpci_get_value(event));
177}
178
179static void h_gpci_event_stop(struct perf_event *event, int flags)
180{
181 h_gpci_event_update(event);
182}
183
184static int h_gpci_event_add(struct perf_event *event, int flags)
185{
186 if (flags & PERF_EF_START)
187 h_gpci_event_start(event, flags);
188
189 return 0;
190}
191
192static int h_gpci_event_init(struct perf_event *event)
193{
194 u64 count;
195 u8 length;
196
197 /* Not our event */
198 if (event->attr.type != event->pmu->type)
199 return -ENOENT;
200
201 /* config2 is unused */
202 if (event->attr.config2) {
203 pr_devel("config2 set when reserved\n");
204 return -EINVAL;
205 }
206
207 /* unsupported modes and filters */
208 if (event->attr.exclude_user ||
209 event->attr.exclude_kernel ||
210 event->attr.exclude_hv ||
211 event->attr.exclude_idle ||
212 event->attr.exclude_host ||
213 event->attr.exclude_guest ||
214 is_sampling_event(event)) /* no sampling */
215 return -EINVAL;
216
217 /* no branch sampling */
218 if (has_branch_stack(event))
219 return -EOPNOTSUPP;
220
221 length = event_get_length(event);
222 if (length < 1 || length > 8) {
223 pr_devel("length invalid\n");
224 return -EINVAL;
225 }
226
227 /* last byte within the buffer? */
228 if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) {
229 pr_devel("request outside of buffer: %zu > %zu\n",
230 (size_t)event_get_offset(event) + length,
231 GPCI_MAX_DATA_BYTES);
232 return -EINVAL;
233 }
234
235 /* check if the request works... */
236 if (single_gpci_request(event_get_request(event),
237 event_get_starting_index(event),
238 event_get_secondary_index(event),
239 event_get_counter_info_version(event),
240 event_get_offset(event),
241 length,
242 &count)) {
243 pr_devel("gpci hcall failed\n");
244 return -EINVAL;
245 }
246
247 return 0;
248}
249
250static int h_gpci_event_idx(struct perf_event *event)
251{
252 return 0;
253}
254
255static struct pmu h_gpci_pmu = {
256 .task_ctx_nr = perf_invalid_context,
257
258 .name = "hv_gpci",
259 .attr_groups = attr_groups,
260 .event_init = h_gpci_event_init,
261 .add = h_gpci_event_add,
262 .del = h_gpci_event_stop,
263 .start = h_gpci_event_start,
264 .stop = h_gpci_event_stop,
265 .read = h_gpci_event_update,
266 .event_idx = h_gpci_event_idx,
267};
268
269static int hv_gpci_init(void)
270{
271 int r;
272 unsigned long hret;
273 struct hv_perf_caps caps;
274
275 if (!firmware_has_feature(FW_FEATURE_LPAR)) {
276 pr_info("not a virtualized system, not enabling\n");
277 return -ENODEV;
278 }
279
280 hret = hv_perf_caps_get(&caps);
281 if (hret) {
282 pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
283 hret);
284 return -ENODEV;
285 }
286
287 r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
288 if (r)
289 return r;
290
291 return 0;
292}
293
294device_initcall(hv_gpci_init);
diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h
new file mode 100644
index 000000000000..b25f460c9cce
--- /dev/null
+++ b/arch/powerpc/perf/hv-gpci.h
@@ -0,0 +1,73 @@
1#ifndef LINUX_POWERPC_PERF_HV_GPCI_H_
2#define LINUX_POWERPC_PERF_HV_GPCI_H_
3
4#include <linux/types.h>
5
6/* From the document "H_GetPerformanceCounterInfo Interface" v1.07 */
7
8/* H_GET_PERF_COUNTER_INFO argument */
9struct hv_get_perf_counter_info_params {
10 __be32 counter_request; /* I */
11 __be32 starting_index; /* IO */
12 __be16 secondary_index; /* IO */
13 __be16 returned_values; /* O */
14 __be32 detail_rc; /* O, only needed when called via *_norets() */
15
16 /*
17 * O, size each of counter_value element in bytes, only set for version
18 * >= 0x3
19 */
20 __be16 cv_element_size;
21
22 /* I, 0 (zero) for versions < 0x3 */
23 __u8 counter_info_version_in;
24
25 /* O, 0 (zero) if version < 0x3. Must be set to 0 when making hcall */
26 __u8 counter_info_version_out;
27 __u8 reserved[0xC];
28 __u8 counter_value[];
29} __packed;
30
31/*
32 * counter info version => fw version/reference (spec version)
33 *
34 * 8 => power8 (1.07)
35 * [7 is skipped by spec 1.07]
36 * 6 => TLBIE (1.07)
37 * 5 => v7r7m0.phyp (1.05)
38 * [4 skipped]
39 * 3 => v7r6m0.phyp (?)
40 * [1,2 skipped]
41 * 0 => v7r{2,3,4}m0.phyp (?)
42 */
43#define COUNTER_INFO_VERSION_CURRENT 0x8
44
45/*
46 * These determine the counter_value[] layout and the meaning of starting_index
47 * and secondary_index.
48 *
49 * Unless otherwise noted, @secondary_index is unused and ignored.
50 */
51enum counter_info_requests {
52
53 /* GENERAL */
54
55 /* @starting_index: must be -1 (to refer to the current partition)
56 */
57 CIR_SYSTEM_PERFORMANCE_CAPABILITIES = 0X40,
58};
59
60struct cv_system_performance_capabilities {
61 /* If != 0, allowed to collect data from other partitions */
62 __u8 perf_collect_privileged;
63
64 /* These following are only valid if counter_info_version >= 0x3 */
65#define CV_CM_GA (1 << 7)
66#define CV_CM_EXPANDED (1 << 6)
67#define CV_CM_LAB (1 << 5)
68 /* remaining bits are reserved */
69 __u8 capability_mask;
70 __u8 reserved[0xE];
71} __packed;
72
73#endif
diff --git a/arch/powerpc/perf/power7-events-list.h b/arch/powerpc/perf/power7-events-list.h
index 687790a2c0b8..64f13d9260a6 100644
--- a/arch/powerpc/perf/power7-events-list.h
+++ b/arch/powerpc/perf/power7-events-list.h
@@ -546,3 +546,13 @@ EVENT(PM_MRK_DATA_FROM_RL2L3_SHR, 0x1d04c)
546EVENT(PM_DTLB_MISS_16M, 0x4c05e) 546EVENT(PM_DTLB_MISS_16M, 0x4c05e)
547EVENT(PM_LSU1_LMQ_LHR_MERGE, 0x0d09a) 547EVENT(PM_LSU1_LMQ_LHR_MERGE, 0x0d09a)
548EVENT(PM_IFU_FIN, 0x40066) 548EVENT(PM_IFU_FIN, 0x40066)
549EVENT(PM_1THRD_CON_RUN_INSTR, 0x30062)
550EVENT(PM_CMPLU_STALL_COUNT, 0x4000B)
551EVENT(PM_MEM0_PB_RD_CL, 0x30083)
552EVENT(PM_THRD_1_RUN_CYC, 0x10060)
553EVENT(PM_THRD_2_CONC_RUN_INSTR, 0x40062)
554EVENT(PM_THRD_2_RUN_CYC, 0x20060)
555EVENT(PM_THRD_3_CONC_RUN_INST, 0x10062)
556EVENT(PM_THRD_3_RUN_CYC, 0x30060)
557EVENT(PM_THRD_4_CONC_RUN_INST, 0x20062)
558EVENT(PM_THRD_4_RUN_CYC, 0x40060)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 96cee20dcd34..fe2763b6e039 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -10,6 +10,8 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13#define pr_fmt(fmt) "power8-pmu: " fmt
14
13#include <linux/kernel.h> 15#include <linux/kernel.h>
14#include <linux/perf_event.h> 16#include <linux/perf_event.h>
15#include <asm/firmware.h> 17#include <asm/firmware.h>
@@ -62,9 +64,11 @@
62 * 64 *
63 * 60 56 52 48 44 40 36 32 65 * 60 56 52 48 44 40 36 32
64 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | 66 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
65 * | [ thresh_cmp ] [ thresh_ctl ] 67 * | | [ ] [ thresh_cmp ] [ thresh_ctl ]
66 * | | 68 * | | | |
67 * *- EBB (Linux) thresh start/stop OR FAB match -* 69 * | | *- IFM (Linux) thresh start/stop OR FAB match -*
70 * | *- BHRB (Linux)
71 * *- EBB (Linux)
68 * 72 *
69 * 28 24 20 16 12 8 4 0 73 * 28 24 20 16 12 8 4 0
70 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | 74 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
@@ -114,9 +118,18 @@
114 * MMCRA[57:59] = sample[0:2] (RAND_SAMP_ELIG) 118 * MMCRA[57:59] = sample[0:2] (RAND_SAMP_ELIG)
115 * MMCRA[61:62] = sample[3:4] (RAND_SAMP_MODE) 119 * MMCRA[61:62] = sample[3:4] (RAND_SAMP_MODE)
116 * 120 *
121 * if EBB and BHRB:
122 * MMCRA[32:33] = IFM
123 *
117 */ 124 */
118 125
119#define EVENT_EBB_MASK 1ull 126#define EVENT_EBB_MASK 1ull
127#define EVENT_EBB_SHIFT PERF_EVENT_CONFIG_EBB_SHIFT
128#define EVENT_BHRB_MASK 1ull
129#define EVENT_BHRB_SHIFT 62
130#define EVENT_WANTS_BHRB (EVENT_BHRB_MASK << EVENT_BHRB_SHIFT)
131#define EVENT_IFM_MASK 3ull
132#define EVENT_IFM_SHIFT 60
120#define EVENT_THR_CMP_SHIFT 40 /* Threshold CMP value */ 133#define EVENT_THR_CMP_SHIFT 40 /* Threshold CMP value */
121#define EVENT_THR_CMP_MASK 0x3ff 134#define EVENT_THR_CMP_MASK 0x3ff
122#define EVENT_THR_CTL_SHIFT 32 /* Threshold control value (start/stop) */ 135#define EVENT_THR_CTL_SHIFT 32 /* Threshold control value (start/stop) */
@@ -141,6 +154,12 @@
141#define EVENT_IS_MARKED (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) 154#define EVENT_IS_MARKED (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT)
142#define EVENT_PSEL_MASK 0xff /* PMCxSEL value */ 155#define EVENT_PSEL_MASK 0xff /* PMCxSEL value */
143 156
157/* Bits defined by Linux */
158#define EVENT_LINUX_MASK \
159 ((EVENT_EBB_MASK << EVENT_EBB_SHIFT) | \
160 (EVENT_BHRB_MASK << EVENT_BHRB_SHIFT) | \
161 (EVENT_IFM_MASK << EVENT_IFM_SHIFT))
162
144#define EVENT_VALID_MASK \ 163#define EVENT_VALID_MASK \
145 ((EVENT_THRESH_MASK << EVENT_THRESH_SHIFT) | \ 164 ((EVENT_THRESH_MASK << EVENT_THRESH_SHIFT) | \
146 (EVENT_SAMPLE_MASK << EVENT_SAMPLE_SHIFT) | \ 165 (EVENT_SAMPLE_MASK << EVENT_SAMPLE_SHIFT) | \
@@ -149,7 +168,7 @@
149 (EVENT_UNIT_MASK << EVENT_UNIT_SHIFT) | \ 168 (EVENT_UNIT_MASK << EVENT_UNIT_SHIFT) | \
150 (EVENT_COMBINE_MASK << EVENT_COMBINE_SHIFT) | \ 169 (EVENT_COMBINE_MASK << EVENT_COMBINE_SHIFT) | \
151 (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \ 170 (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \
152 (EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT) | \ 171 EVENT_LINUX_MASK | \
153 EVENT_PSEL_MASK) 172 EVENT_PSEL_MASK)
154 173
155/* MMCRA IFM bits - POWER8 */ 174/* MMCRA IFM bits - POWER8 */
@@ -173,10 +192,11 @@
173 * 192 *
174 * 28 24 20 16 12 8 4 0 193 * 28 24 20 16 12 8 4 0
175 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | 194 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
176 * | [ ] [ sample ] [ ] [6] [5] [4] [3] [2] [1] 195 * [ ] | [ ] [ sample ] [ ] [6] [5] [4] [3] [2] [1]
177 * EBB -* | | 196 * | | | |
178 * | | Count of events for each PMC. 197 * BHRB IFM -* | | | Count of events for each PMC.
179 * L1 I/D qualifier -* | p1, p2, p3, p4, p5, p6. 198 * EBB -* | | p1, p2, p3, p4, p5, p6.
199 * L1 I/D qualifier -* |
180 * nc - number of counters -* 200 * nc - number of counters -*
181 * 201 *
182 * The PMC fields P1..P6, and NC, are adder fields. As we accumulate constraints 202 * The PMC fields P1..P6, and NC, are adder fields. As we accumulate constraints
@@ -195,6 +215,9 @@
195#define CNST_EBB_VAL(v) (((v) & EVENT_EBB_MASK) << 24) 215#define CNST_EBB_VAL(v) (((v) & EVENT_EBB_MASK) << 24)
196#define CNST_EBB_MASK CNST_EBB_VAL(EVENT_EBB_MASK) 216#define CNST_EBB_MASK CNST_EBB_VAL(EVENT_EBB_MASK)
197 217
218#define CNST_IFM_VAL(v) (((v) & EVENT_IFM_MASK) << 25)
219#define CNST_IFM_MASK CNST_IFM_VAL(EVENT_IFM_MASK)
220
198#define CNST_L1_QUAL_VAL(v) (((v) & 3) << 22) 221#define CNST_L1_QUAL_VAL(v) (((v) & 3) << 22)
199#define CNST_L1_QUAL_MASK CNST_L1_QUAL_VAL(3) 222#define CNST_L1_QUAL_MASK CNST_L1_QUAL_VAL(3)
200 223
@@ -241,6 +264,7 @@
241#define MMCRA_THR_SEL_SHIFT 16 264#define MMCRA_THR_SEL_SHIFT 16
242#define MMCRA_THR_CMP_SHIFT 32 265#define MMCRA_THR_CMP_SHIFT 32
243#define MMCRA_SDAR_MODE_TLB (1ull << 42) 266#define MMCRA_SDAR_MODE_TLB (1ull << 42)
267#define MMCRA_IFM_SHIFT 30
244 268
245 269
246static inline bool event_is_fab_match(u64 event) 270static inline bool event_is_fab_match(u64 event)
@@ -265,20 +289,22 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
265 pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 289 pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
266 unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; 290 unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
267 cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK; 291 cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK;
268 ebb = (event >> PERF_EVENT_CONFIG_EBB_SHIFT) & EVENT_EBB_MASK; 292 ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK;
269
270 /* Clear the EBB bit in the event, so event checks work below */
271 event &= ~(EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT);
272 293
273 if (pmc) { 294 if (pmc) {
295 u64 base_event;
296
274 if (pmc > 6) 297 if (pmc > 6)
275 return -1; 298 return -1;
276 299
277 mask |= CNST_PMC_MASK(pmc); 300 /* Ignore Linux defined bits when checking event below */
278 value |= CNST_PMC_VAL(pmc); 301 base_event = event & ~EVENT_LINUX_MASK;
279 302
280 if (pmc >= 5 && event != 0x500fa && event != 0x600f4) 303 if (pmc >= 5 && base_event != 0x500fa && base_event != 0x600f4)
281 return -1; 304 return -1;
305
306 mask |= CNST_PMC_MASK(pmc);
307 value |= CNST_PMC_VAL(pmc);
282 } 308 }
283 309
284 if (pmc <= 4) { 310 if (pmc <= 4) {
@@ -299,9 +325,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
299 * HV writable, and there is no API for guest kernels to modify 325 * HV writable, and there is no API for guest kernels to modify
300 * it. The solution is for the hypervisor to initialise the 326 * it. The solution is for the hypervisor to initialise the
301 * field to zeroes, and for us to only ever allow events that 327 * field to zeroes, and for us to only ever allow events that
302 * have a cache selector of zero. 328 * have a cache selector of zero. The bank selector (bit 3) is
329 * irrelevant, as long as the rest of the value is 0.
303 */ 330 */
304 if (cache) 331 if (cache & 0x7)
305 return -1; 332 return -1;
306 333
307 } else if (event & EVENT_IS_L1) { 334 } else if (event & EVENT_IS_L1) {
@@ -342,6 +369,15 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
342 /* EBB events must specify the PMC */ 369 /* EBB events must specify the PMC */
343 return -1; 370 return -1;
344 371
372 if (event & EVENT_WANTS_BHRB) {
373 if (!ebb)
374 /* Only EBB events can request BHRB */
375 return -1;
376
377 mask |= CNST_IFM_MASK;
378 value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT);
379 }
380
345 /* 381 /*
346 * All events must agree on EBB, either all request it or none. 382 * All events must agree on EBB, either all request it or none.
347 * EBB events are pinned & exclusive, so this should never actually 383 * EBB events are pinned & exclusive, so this should never actually
@@ -431,6 +467,11 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
431 mmcra |= val << MMCRA_THR_CMP_SHIFT; 467 mmcra |= val << MMCRA_THR_CMP_SHIFT;
432 } 468 }
433 469
470 if (event[i] & EVENT_WANTS_BHRB) {
471 val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK;
472 mmcra |= val << MMCRA_IFM_SHIFT;
473 }
474
434 hwc[i] = pmc - 1; 475 hwc[i] = pmc - 1;
435 } 476 }
436 477
@@ -774,6 +815,9 @@ static int __init init_power8_pmu(void)
774 /* Tell userspace that EBB is supported */ 815 /* Tell userspace that EBB is supported */
775 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB; 816 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
776 817
818 if (cpu_has_feature(CPU_FTR_PMAO_BUG))
819 pr_info("PMAO restore workaround active.\n");
820
777 return 0; 821 return 0;
778} 822}
779early_initcall(init_power8_pmu); 823early_initcall(init_power8_pmu);
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index 5125caeb40f4..f324ea099503 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,6 +1,6 @@
1obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o 1obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
2obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o 2obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
3obj-y += rng.o opal-elog.o opal-dump.o 3obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
4 4
5obj-$(CONFIG_SMP) += smp.o 5obj-$(CONFIG_SMP) += smp.o
6obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o 6obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c
new file mode 100644
index 000000000000..cd0c1354d404
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-async.c
@@ -0,0 +1,203 @@
1/*
2 * PowerNV OPAL asynchronous completion interfaces
3 *
4 * Copyright 2013 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#undef DEBUG
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/sched.h>
18#include <linux/semaphore.h>
19#include <linux/spinlock.h>
20#include <linux/wait.h>
21#include <linux/gfp.h>
22#include <linux/of.h>
23#include <asm/opal.h>
24
25#define N_ASYNC_COMPLETIONS 64
26
27static DECLARE_BITMAP(opal_async_complete_map, N_ASYNC_COMPLETIONS) = {~0UL};
28static DECLARE_BITMAP(opal_async_token_map, N_ASYNC_COMPLETIONS);
29static DECLARE_WAIT_QUEUE_HEAD(opal_async_wait);
30static DEFINE_SPINLOCK(opal_async_comp_lock);
31static struct semaphore opal_async_sem;
32static struct opal_msg *opal_async_responses;
33static unsigned int opal_max_async_tokens;
34
35int __opal_async_get_token(void)
36{
37 unsigned long flags;
38 int token;
39
40 spin_lock_irqsave(&opal_async_comp_lock, flags);
41 token = find_first_bit(opal_async_complete_map, opal_max_async_tokens);
42 if (token >= opal_max_async_tokens) {
43 token = -EBUSY;
44 goto out;
45 }
46
47 if (__test_and_set_bit(token, opal_async_token_map)) {
48 token = -EBUSY;
49 goto out;
50 }
51
52 __clear_bit(token, opal_async_complete_map);
53
54out:
55 spin_unlock_irqrestore(&opal_async_comp_lock, flags);
56 return token;
57}
58
59int opal_async_get_token_interruptible(void)
60{
61 int token;
62
63 /* Wait until a token is available */
64 if (down_interruptible(&opal_async_sem))
65 return -ERESTARTSYS;
66
67 token = __opal_async_get_token();
68 if (token < 0)
69 up(&opal_async_sem);
70
71 return token;
72}
73
74int __opal_async_release_token(int token)
75{
76 unsigned long flags;
77
78 if (token < 0 || token >= opal_max_async_tokens) {
79 pr_err("%s: Passed token is out of range, token %d\n",
80 __func__, token);
81 return -EINVAL;
82 }
83
84 spin_lock_irqsave(&opal_async_comp_lock, flags);
85 __set_bit(token, opal_async_complete_map);
86 __clear_bit(token, opal_async_token_map);
87 spin_unlock_irqrestore(&opal_async_comp_lock, flags);
88
89 return 0;
90}
91
92int opal_async_release_token(int token)
93{
94 int ret;
95
96 ret = __opal_async_release_token(token);
97 if (ret)
98 return ret;
99
100 up(&opal_async_sem);
101
102 return 0;
103}
104
105int opal_async_wait_response(uint64_t token, struct opal_msg *msg)
106{
107 if (token >= opal_max_async_tokens) {
108 pr_err("%s: Invalid token passed\n", __func__);
109 return -EINVAL;
110 }
111
112 if (!msg) {
113 pr_err("%s: Invalid message pointer passed\n", __func__);
114 return -EINVAL;
115 }
116
117 wait_event(opal_async_wait, test_bit(token, opal_async_complete_map));
118 memcpy(msg, &opal_async_responses[token], sizeof(*msg));
119
120 return 0;
121}
122
123static int opal_async_comp_event(struct notifier_block *nb,
124 unsigned long msg_type, void *msg)
125{
126 struct opal_msg *comp_msg = msg;
127 unsigned long flags;
128
129 if (msg_type != OPAL_MSG_ASYNC_COMP)
130 return 0;
131
132 memcpy(&opal_async_responses[comp_msg->params[0]], comp_msg,
133 sizeof(*comp_msg));
134 spin_lock_irqsave(&opal_async_comp_lock, flags);
135 __set_bit(comp_msg->params[0], opal_async_complete_map);
136 spin_unlock_irqrestore(&opal_async_comp_lock, flags);
137
138 wake_up(&opal_async_wait);
139
140 return 0;
141}
142
143static struct notifier_block opal_async_comp_nb = {
144 .notifier_call = opal_async_comp_event,
145 .next = NULL,
146 .priority = 0,
147};
148
149static int __init opal_async_comp_init(void)
150{
151 struct device_node *opal_node;
152 const __be32 *async;
153 int err;
154
155 opal_node = of_find_node_by_path("/ibm,opal");
156 if (!opal_node) {
157 pr_err("%s: Opal node not found\n", __func__);
158 err = -ENOENT;
159 goto out;
160 }
161
162 async = of_get_property(opal_node, "opal-msg-async-num", NULL);
163 if (!async) {
164 pr_err("%s: %s has no opal-msg-async-num\n",
165 __func__, opal_node->full_name);
166 err = -ENOENT;
167 goto out_opal_node;
168 }
169
170 opal_max_async_tokens = be32_to_cpup(async);
171 if (opal_max_async_tokens > N_ASYNC_COMPLETIONS)
172 opal_max_async_tokens = N_ASYNC_COMPLETIONS;
173
174 err = opal_message_notifier_register(OPAL_MSG_ASYNC_COMP,
175 &opal_async_comp_nb);
176 if (err) {
177 pr_err("%s: Can't register OPAL event notifier (%d)\n",
178 __func__, err);
179 goto out_opal_node;
180 }
181
182 opal_async_responses = kzalloc(
183 sizeof(*opal_async_responses) * opal_max_async_tokens,
184 GFP_KERNEL);
185 if (!opal_async_responses) {
186 pr_err("%s: Out of memory, failed to do asynchronous "
187 "completion init\n", __func__);
188 err = -ENOMEM;
189 goto out_opal_node;
190 }
191
192 /* Initialize to 1 less than the maximum tokens available, as we may
193 * require to pop one during emergency through synchronous call to
194 * __opal_async_get_token()
195 */
196 sema_init(&opal_async_sem, opal_max_async_tokens - 1);
197
198out_opal_node:
199 of_node_put(opal_node);
200out:
201 return err;
202}
203subsys_initcall(opal_async_comp_init);
diff --git a/arch/powerpc/platforms/powernv/opal-sensor.c b/arch/powerpc/platforms/powernv/opal-sensor.c
new file mode 100644
index 000000000000..663cc9c65613
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-sensor.c
@@ -0,0 +1,64 @@
1/*
2 * PowerNV sensor code
3 *
4 * Copyright (C) 2013 IBM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/delay.h>
22#include <linux/mutex.h>
23#include <asm/opal.h>
24
25static DEFINE_MUTEX(opal_sensor_mutex);
26
27/*
28 * This will return sensor information to driver based on the requested sensor
29 * handle. A handle is an opaque id for the powernv, read by the driver from the
30 * device tree..
31 */
32int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data)
33{
34 int ret, token;
35 struct opal_msg msg;
36
37 token = opal_async_get_token_interruptible();
38 if (token < 0) {
39 pr_err("%s: Couldn't get the token, returning\n", __func__);
40 ret = token;
41 goto out;
42 }
43
44 mutex_lock(&opal_sensor_mutex);
45 ret = opal_sensor_read(sensor_hndl, token, sensor_data);
46 if (ret != OPAL_ASYNC_COMPLETION)
47 goto out_token;
48
49 ret = opal_async_wait_response(token, &msg);
50 if (ret) {
51 pr_err("%s: Failed to wait for the async response, %d\n",
52 __func__, ret);
53 goto out_token;
54 }
55
56 ret = msg.params[1];
57
58out_token:
59 mutex_unlock(&opal_sensor_mutex);
60 opal_async_release_token(token);
61out:
62 return ret;
63}
64EXPORT_SYMBOL_GPL(opal_get_sensor_data);
diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c
new file mode 100644
index 000000000000..0bd249a26f30
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-sysparam.c
@@ -0,0 +1,290 @@
1/*
2 * PowerNV system parameter code
3 *
4 * Copyright (C) 2013 IBM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kobject.h>
22#include <linux/mutex.h>
23#include <linux/slab.h>
24#include <linux/of.h>
25#include <linux/gfp.h>
26#include <linux/stat.h>
27#include <asm/opal.h>
28
29#define MAX_PARAM_DATA_LEN 64
30
31static DEFINE_MUTEX(opal_sysparam_mutex);
32static struct kobject *sysparam_kobj;
33static void *param_data_buf;
34
35struct param_attr {
36 struct list_head list;
37 u32 param_id;
38 u32 param_size;
39 struct kobj_attribute kobj_attr;
40};
41
42static int opal_get_sys_param(u32 param_id, u32 length, void *buffer)
43{
44 struct opal_msg msg;
45 int ret, token;
46
47 token = opal_async_get_token_interruptible();
48 if (token < 0) {
49 if (token != -ERESTARTSYS)
50 pr_err("%s: Couldn't get the token, returning\n",
51 __func__);
52 ret = token;
53 goto out;
54 }
55
56 ret = opal_get_param(token, param_id, (u64)buffer, length);
57 if (ret != OPAL_ASYNC_COMPLETION)
58 goto out_token;
59
60 ret = opal_async_wait_response(token, &msg);
61 if (ret) {
62 pr_err("%s: Failed to wait for the async response, %d\n",
63 __func__, ret);
64 goto out_token;
65 }
66
67 ret = msg.params[1];
68
69out_token:
70 opal_async_release_token(token);
71out:
72 return ret;
73}
74
75static int opal_set_sys_param(u32 param_id, u32 length, void *buffer)
76{
77 struct opal_msg msg;
78 int ret, token;
79
80 token = opal_async_get_token_interruptible();
81 if (token < 0) {
82 if (token != -ERESTARTSYS)
83 pr_err("%s: Couldn't get the token, returning\n",
84 __func__);
85 ret = token;
86 goto out;
87 }
88
89 ret = opal_set_param(token, param_id, (u64)buffer, length);
90
91 if (ret != OPAL_ASYNC_COMPLETION)
92 goto out_token;
93
94 ret = opal_async_wait_response(token, &msg);
95 if (ret) {
96 pr_err("%s: Failed to wait for the async response, %d\n",
97 __func__, ret);
98 goto out_token;
99 }
100
101 ret = msg.params[1];
102
103out_token:
104 opal_async_release_token(token);
105out:
106 return ret;
107}
108
109static ssize_t sys_param_show(struct kobject *kobj,
110 struct kobj_attribute *kobj_attr, char *buf)
111{
112 struct param_attr *attr = container_of(kobj_attr, struct param_attr,
113 kobj_attr);
114 int ret;
115
116 mutex_lock(&opal_sysparam_mutex);
117 ret = opal_get_sys_param(attr->param_id, attr->param_size,
118 param_data_buf);
119 if (ret)
120 goto out;
121
122 memcpy(buf, param_data_buf, attr->param_size);
123
124out:
125 mutex_unlock(&opal_sysparam_mutex);
126 return ret ? ret : attr->param_size;
127}
128
129static ssize_t sys_param_store(struct kobject *kobj,
130 struct kobj_attribute *kobj_attr, const char *buf, size_t count)
131{
132 struct param_attr *attr = container_of(kobj_attr, struct param_attr,
133 kobj_attr);
134 int ret;
135
136 mutex_lock(&opal_sysparam_mutex);
137 memcpy(param_data_buf, buf, count);
138 ret = opal_set_sys_param(attr->param_id, attr->param_size,
139 param_data_buf);
140 mutex_unlock(&opal_sysparam_mutex);
141 return ret ? ret : count;
142}
143
144void __init opal_sys_param_init(void)
145{
146 struct device_node *sysparam;
147 struct param_attr *attr;
148 u32 *id, *size;
149 int count, i;
150 u8 *perm;
151
152 if (!opal_kobj) {
153 pr_warn("SYSPARAM: opal kobject is not available\n");
154 goto out;
155 }
156
157 sysparam_kobj = kobject_create_and_add("sysparams", opal_kobj);
158 if (!sysparam_kobj) {
159 pr_err("SYSPARAM: Failed to create sysparam kobject\n");
160 goto out;
161 }
162
163 /* Allocate big enough buffer for any get/set transactions */
164 param_data_buf = kzalloc(MAX_PARAM_DATA_LEN, GFP_KERNEL);
165 if (!param_data_buf) {
166 pr_err("SYSPARAM: Failed to allocate memory for param data "
167 "buf\n");
168 goto out_kobj_put;
169 }
170
171 sysparam = of_find_node_by_path("/ibm,opal/sysparams");
172 if (!sysparam) {
173 pr_err("SYSPARAM: Opal sysparam node not found\n");
174 goto out_param_buf;
175 }
176
177 if (!of_device_is_compatible(sysparam, "ibm,opal-sysparams")) {
178 pr_err("SYSPARAM: Opal sysparam node not compatible\n");
179 goto out_node_put;
180 }
181
182 /* Number of parameters exposed through DT */
183 count = of_property_count_strings(sysparam, "param-name");
184 if (count < 0) {
185 pr_err("SYSPARAM: No string found of property param-name in "
186 "the node %s\n", sysparam->name);
187 goto out_node_put;
188 }
189
190 id = kzalloc(sizeof(*id) * count, GFP_KERNEL);
191 if (!id) {
192 pr_err("SYSPARAM: Failed to allocate memory to read parameter "
193 "id\n");
194 goto out_node_put;
195 }
196
197 size = kzalloc(sizeof(*size) * count, GFP_KERNEL);
198 if (!size) {
199 pr_err("SYSPARAM: Failed to allocate memory to read parameter "
200 "size\n");
201 goto out_free_id;
202 }
203
204 perm = kzalloc(sizeof(*perm) * count, GFP_KERNEL);
205 if (!perm) {
206 pr_err("SYSPARAM: Failed to allocate memory to read supported "
207 "action on the parameter");
208 goto out_free_size;
209 }
210
211 if (of_property_read_u32_array(sysparam, "param-id", id, count)) {
212 pr_err("SYSPARAM: Missing property param-id in the DT\n");
213 goto out_free_perm;
214 }
215
216 if (of_property_read_u32_array(sysparam, "param-len", size, count)) {
217 pr_err("SYSPARAM: Missing propery param-len in the DT\n");
218 goto out_free_perm;
219 }
220
221
222 if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) {
223 pr_err("SYSPARAM: Missing propery param-perm in the DT\n");
224 goto out_free_perm;
225 }
226
227 attr = kzalloc(sizeof(*attr) * count, GFP_KERNEL);
228 if (!attr) {
229 pr_err("SYSPARAM: Failed to allocate memory for parameter "
230 "attributes\n");
231 goto out_free_perm;
232 }
233
234 /* For each of the parameters, populate the parameter attributes */
235 for (i = 0; i < count; i++) {
236 sysfs_attr_init(&attr[i].kobj_attr.attr);
237 attr[i].param_id = id[i];
238 attr[i].param_size = size[i];
239 if (of_property_read_string_index(sysparam, "param-name", i,
240 &attr[i].kobj_attr.attr.name))
241 continue;
242
243 /* If the parameter is read-only or read-write */
244 switch (perm[i] & 3) {
245 case OPAL_SYSPARAM_READ:
246 attr[i].kobj_attr.attr.mode = S_IRUGO;
247 break;
248 case OPAL_SYSPARAM_WRITE:
249 attr[i].kobj_attr.attr.mode = S_IWUGO;
250 break;
251 case OPAL_SYSPARAM_RW:
252 attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUGO;
253 break;
254 default:
255 break;
256 }
257
258 attr[i].kobj_attr.show = sys_param_show;
259 attr[i].kobj_attr.store = sys_param_store;
260
261 if (sysfs_create_file(sysparam_kobj, &attr[i].kobj_attr.attr)) {
262 pr_err("SYSPARAM: Failed to create sysfs file %s\n",
263 attr[i].kobj_attr.attr.name);
264 goto out_free_attr;
265 }
266 }
267
268 kfree(perm);
269 kfree(size);
270 kfree(id);
271 of_node_put(sysparam);
272 return;
273
274out_free_attr:
275 kfree(attr);
276out_free_perm:
277 kfree(perm);
278out_free_size:
279 kfree(size);
280out_free_id:
281 kfree(id);
282out_node_put:
283 of_node_put(sysparam);
284out_param_buf:
285 kfree(param_data_buf);
286out_kobj_put:
287 kobject_put(sysparam_kobj);
288out:
289 return;
290}
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 47ec3f738062..75c89df8d71e 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -140,3 +140,6 @@ OPAL_CALL(opal_get_msg, OPAL_GET_MSG);
140OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); 140OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION);
141OPAL_CALL(opal_dump_resend_notification, OPAL_DUMP_RESEND); 141OPAL_CALL(opal_dump_resend_notification, OPAL_DUMP_RESEND);
142OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT); 142OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT);
143OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ);
144OPAL_CALL(opal_get_param, OPAL_GET_PARAM);
145OPAL_CALL(opal_set_param, OPAL_SET_PARAM);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 2e269c27dd23..e92f2f67640f 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -572,6 +572,8 @@ static int __init opal_init(void)
572 opal_flash_init(); 572 opal_flash_init();
573 /* Setup platform dump extract interface */ 573 /* Setup platform dump extract interface */
574 opal_platform_dump_init(); 574 opal_platform_dump_init();
575 /* Setup system parameters interface */
576 opal_sys_param_init();
575 } 577 }
576 578
577 return 0; 579 return 0;
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 80b1d57c306a..2cb8b776c84a 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -111,6 +111,18 @@ config CMM
111 will be reused for other LPARs. The interface allows firmware to 111 will be reused for other LPARs. The interface allows firmware to
112 balance memory across many LPARs. 112 balance memory across many LPARs.
113 113
114config HV_PERF_CTRS
115 bool "Hypervisor supplied PMU events (24x7 & GPCI)"
116 default y
117 depends on PERF_EVENTS && PPC_PSERIES
118 help
119 Enable access to hypervisor supplied counters in perf. Currently,
120 this enables code that uses the hcall GetPerfCounterInfo and 24x7
121 interfaces to retrieve counters. GPCI exists on Power 6 and later
122 systems. 24x7 is available on Power 8 systems.
123
124 If unsure, select Y.
125
114config DTL 126config DTL
115 bool "Dispatch Trace Log" 127 bool "Dispatch Trace Log"
116 depends on PPC_SPLPAR && DEBUG_FS 128 depends on PPC_SPLPAR && DEBUG_FS
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 5ce43d8dfa98..ad4cdcbc618b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -557,6 +557,14 @@ config SENSORS_IBMPEX
557 This driver can also be built as a module. If so, the module 557 This driver can also be built as a module. If so, the module
558 will be called ibmpex. 558 will be called ibmpex.
559 559
560config SENSORS_IBMPOWERNV
561 tristate "IBM PowerNv Platform temperature/power/fan sensor"
562 depends on PPC_POWERNV
563 default y
564 help
565 If you say yes here you get support for the temperature/fan/power
566 sensors on your platform.
567
560config SENSORS_IIO_HWMON 568config SENSORS_IIO_HWMON
561 tristate "Hwmon driver that uses channels specified via iio maps" 569 tristate "Hwmon driver that uses channels specified via iio maps"
562 depends on IIO 570 depends on IIO
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index ec7cde06eb52..807e1721ed79 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
70obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o 70obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
71obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o 71obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
72obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o 72obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
73obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
73obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o 74obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
74obj-$(CONFIG_SENSORS_INA209) += ina209.o 75obj-$(CONFIG_SENSORS_INA209) += ina209.o
75obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o 76obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
new file mode 100644
index 000000000000..b7b1297a9b02
--- /dev/null
+++ b/drivers/hwmon/ibmpowernv.c
@@ -0,0 +1,529 @@
1/*
2 * hwmon driver for temperature/power/fan on IBM PowerNV platform
3 * Copyright (C) 2013 IBM
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/hwmon.h>
24#include <linux/hwmon-sysfs.h>
25#include <linux/of.h>
26#include <linux/slab.h>
27
28#include <linux/jiffies.h>
29#include <linux/platform_device.h>
30#include <asm/opal.h>
31#include <linux/err.h>
32
33MODULE_DESCRIPTION("IBM PowerNV Platform power/temp/fan sensor hwmon module");
34MODULE_LICENSE("GPL");
35
36#define MAX_ATTR_LENGTH 32
37
38/* Device tree sensor name prefixes. The device tree has the names in the
39 * format "cooling-fan#2-faulted" where the "cooling-fan" is the sensor type,
40 * 2 is the sensor count, and "faulted" is the sensor data attribute type.
41 */
42#define DT_FAULT_ATTR_SUFFIX "faulted"
43#define DT_DATA_ATTR_SUFFIX "data"
44#define DT_THRESHOLD_ATTR_SUFFIX "thrs"
45
46enum sensors {
47 FAN,
48 TEMPERATURE,
49 POWERSUPPLY,
50 POWER,
51 MAX_SENSOR_TYPE,
52};
53
54enum attributes {
55 INPUT,
56 MINIMUM,
57 MAXIMUM,
58 FAULT,
59 MAX_ATTR_TYPES
60};
61
62static struct sensor_name {
63 char *name;
64 char *compaible;
65} sensor_names[] = {
66 {"fan-sensor", "ibm,opal-sensor-cooling-fan"},
67 {"amb-temp-sensor", "ibm,opal-sensor-amb-temp"},
68 {"power-sensor", "ibm,opal-sensor-power-supply"},
69 {"power", "ibm,opal-sensor-power"}
70};
71
72static const char * const attribute_type_table[] = {
73 "input",
74 "min",
75 "max",
76 "fault",
77 NULL
78};
79
80struct pdev_entry {
81 struct list_head list;
82 struct platform_device *pdev;
83 enum sensors type;
84};
85
86static LIST_HEAD(pdev_list);
87
88/* The sensors are categorised on type.
89 *
90 * The sensors of same type are categorised under a common platform device.
91 * So, The pdev is shared by all sensors of same type.
92 * Ex : temp1_input, temp1_max, temp2_input,temp2_max all share same platform
93 * device.
94 *
95 * "sensor_data" is the Platform device specific data.
96 * There is one hwmon_device instance for all the sensors of same type.
97 * This also holds the list of all sensors with same type but different
98 * attribute and index.
99 */
100struct sensor_specific_data {
101 u32 sensor_id; /* The hex value as in the device tree */
102 u32 sensor_index; /* The sensor instance index */
103 struct sensor_device_attribute sd_attr;
104 enum attributes attr_type;
105 char attr_name[64];
106};
107
108struct sensor_data {
109 struct device *hwmon_dev;
110 struct list_head sensor_list;
111 struct device_attribute name_attr;
112};
113
114struct sensor_entry {
115 struct list_head list;
116 struct sensor_specific_data *sensor_data;
117};
118
119static struct platform_device *powernv_sensor_get_pdev(enum sensors type)
120{
121 struct pdev_entry *p;
122 list_for_each_entry(p, &pdev_list, list)
123 if (p->type == type)
124 return p->pdev;
125
126 return NULL;
127}
128
129static struct sensor_specific_data *powernv_sensor_get_sensor_data(
130 struct sensor_data *pdata,
131 int index, enum attributes attr_type)
132{
133 struct sensor_entry *p;
134 list_for_each_entry(p, &pdata->sensor_list, list)
135 if ((p->sensor_data->sensor_index == index) &&
136 (attr_type == p->sensor_data->attr_type))
137 return p->sensor_data;
138
139 return NULL;
140}
141
142static ssize_t show_name(struct device *dev,
143 struct device_attribute *devattr, char *buf)
144{
145 struct platform_device *pdev = to_platform_device(dev);
146
147 return sprintf(buf, "%s\n", pdev->name);
148}
149
150/* Note: Data from the sensors for each sensor type needs to be converted to
151 * the dimension appropriate.
152 */
153static ssize_t show_sensor(struct device *dev,
154 struct device_attribute *devattr, char *buf)
155{
156 struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(devattr);
157 struct platform_device *pdev = to_platform_device(dev);
158 struct sensor_data *pdata = platform_get_drvdata(pdev);
159 struct sensor_specific_data *tdata = NULL;
160 enum sensors sensor_type = pdev->id;
161 u32 x = -1;
162 int ret;
163
164 if (sd_attr && sd_attr->dev_attr.attr.name) {
165 char *pos = strchr(sd_attr->dev_attr.attr.name, '_');
166 int i;
167
168 for (i = 0; i < MAX_ATTR_TYPES; i++) {
169 if (strcmp(pos+1, attribute_type_table[i]) == 0) {
170 tdata = powernv_sensor_get_sensor_data(pdata,
171 sd_attr->index, i);
172 break;
173 }
174 }
175 }
176
177 if (tdata) {
178 ret = opal_get_sensor_data(tdata->sensor_id, &x);
179 if (ret)
180 x = -1;
181 }
182
183 if (sensor_type == TEMPERATURE && x > 0) {
184 /* Temperature comes in Degrees and convert it to
185 * milli-degrees.
186 */
187 x = x*1000;
188 } else if (sensor_type == POWER && x > 0) {
189 /* Power value comes in watts, convert to micro-watts */
190 x = x * 1000000;
191 }
192
193 return sprintf(buf, "%d\n", x);
194}
195
196static u32 get_sensor_index_from_name(const char *name)
197{
198 char *hash_position = strchr(name, '#');
199 u32 index = 0, copy_length;
200 char newbuf[8];
201
202 if (hash_position) {
203 copy_length = strchr(hash_position, '-') - hash_position - 1;
204 if (copy_length < sizeof(newbuf)) {
205 strncpy(newbuf, hash_position + 1, copy_length);
206 sscanf(newbuf, "%d", &index);
207 }
208 }
209
210 return index;
211}
212
213static inline void get_sensor_suffix_from_name(const char *name, char *suffix)
214{
215 char *dash_position = strrchr(name, '-');
216 if (dash_position)
217 strncpy(suffix, dash_position+1, MAX_ATTR_LENGTH);
218 else
219 strcpy(suffix,"");
220}
221
222static int get_sensor_attr_properties(const char *sensor_name,
223 enum sensors sensor_type, enum attributes *attr_type,
224 u32 *sensor_index)
225{
226 char suffix[MAX_ATTR_LENGTH];
227
228 *attr_type = MAX_ATTR_TYPES;
229 *sensor_index = get_sensor_index_from_name(sensor_name);
230 if (*sensor_index == 0)
231 return -EINVAL;
232
233 get_sensor_suffix_from_name(sensor_name, suffix);
234 if (strcmp(suffix, "") == 0)
235 return -EINVAL;
236
237 if (strcmp(suffix, DT_FAULT_ATTR_SUFFIX) == 0)
238 *attr_type = FAULT;
239 else if (strcmp(suffix, DT_DATA_ATTR_SUFFIX) == 0)
240 *attr_type = INPUT;
241 else if ((sensor_type == TEMPERATURE) &&
242 (strcmp(suffix, DT_THRESHOLD_ATTR_SUFFIX) == 0))
243 *attr_type = MAXIMUM;
244 else if ((sensor_type == FAN) &&
245 (strcmp(suffix, DT_THRESHOLD_ATTR_SUFFIX) == 0))
246 *attr_type = MINIMUM;
247 else
248 return -ENOENT;
249
250 if (((sensor_type == FAN) && ((*attr_type == INPUT) ||
251 (*attr_type == MINIMUM)))
252 || ((sensor_type == TEMPERATURE) && ((*attr_type == INPUT) ||
253 (*attr_type == MAXIMUM)))
254 || ((sensor_type == POWER) && ((*attr_type == INPUT))))
255 return 0;
256
257 return -ENOENT;
258}
259
260static int create_sensor_attr(struct sensor_specific_data *tdata,
261 struct device *dev, enum sensors sensor_type,
262 enum attributes attr_type)
263{
264 int err = 0;
265 char temp_file_prefix[50];
266 static const char *const file_name_format = "%s%d_%s";
267
268 tdata->attr_type = attr_type;
269
270 if (sensor_type == FAN)
271 strcpy(temp_file_prefix, "fan");
272 else if (sensor_type == TEMPERATURE)
273 strcpy(temp_file_prefix, "temp");
274 else if (sensor_type == POWERSUPPLY)
275 strcpy(temp_file_prefix, "powersupply");
276 else if (sensor_type == POWER)
277 strcpy(temp_file_prefix, "power");
278
279 snprintf(tdata->attr_name, sizeof(tdata->attr_name), file_name_format,
280 temp_file_prefix, tdata->sensor_index,
281 attribute_type_table[tdata->attr_type]);
282
283 sysfs_attr_init(&tdata->sd_attr.dev_attr.attr);
284 tdata->sd_attr.dev_attr.attr.name = tdata->attr_name;
285 tdata->sd_attr.dev_attr.attr.mode = S_IRUGO;
286 tdata->sd_attr.dev_attr.show = show_sensor;
287
288 tdata->sd_attr.index = tdata->sensor_index;
289 err = device_create_file(dev, &tdata->sd_attr.dev_attr);
290
291 return err;
292}
293
294static int create_name_attr(struct sensor_data *pdata,
295 struct device *dev)
296{
297 sysfs_attr_init(&pdata->name_attr.attr);
298 pdata->name_attr.attr.name = "name";
299 pdata->name_attr.attr.mode = S_IRUGO;
300 pdata->name_attr.show = show_name;
301 return device_create_file(dev, &pdata->name_attr);
302}
303
304static int create_platform_device(enum sensors sensor_type,
305 struct platform_device **pdev)
306{
307 struct pdev_entry *pdev_entry = NULL;
308 int err;
309
310 *pdev = platform_device_alloc(sensor_names[sensor_type].name,
311 sensor_type);
312 if (!*pdev) {
313 pr_err("Device allocation failed\n");
314 err = -ENOMEM;
315 goto exit;
316 }
317
318 pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
319 if (!pdev_entry) {
320 pr_err("Device allocation failed\n");
321 err = -ENOMEM;
322 goto exit_device_put;
323 }
324
325 err = platform_device_add(*pdev);
326 if (err) {
327 pr_err("Device addition failed (%d)\n", err);
328 goto exit_device_free;
329 }
330
331 pdev_entry->pdev = *pdev;
332 pdev_entry->type = (*pdev)->id;
333
334 list_add_tail(&pdev_entry->list, &pdev_list);
335
336 return 0;
337exit_device_free:
338 kfree(pdev_entry);
339exit_device_put:
340 platform_device_put(*pdev);
341exit:
342 return err;
343}
344
345static int create_sensor_data(struct platform_device *pdev)
346{
347 struct sensor_data *pdata = NULL;
348 int err = 0;
349
350 pdata = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
351 if (!pdata) {
352 err = -ENOMEM;
353 goto exit;
354 }
355
356 err = create_name_attr(pdata, &pdev->dev);
357 if (err)
358 goto exit_free;
359
360 pdata->hwmon_dev = hwmon_device_register(&pdev->dev);
361 if (IS_ERR(pdata->hwmon_dev)) {
362 err = PTR_ERR(pdata->hwmon_dev);
363 dev_err(&pdev->dev, "Class registration failed (%d)\n",
364 err);
365 goto exit_name;
366 }
367
368 INIT_LIST_HEAD(&pdata->sensor_list);
369 platform_set_drvdata(pdev, pdata);
370
371 return 0;
372
373exit_name:
374 device_remove_file(&pdev->dev, &pdata->name_attr);
375exit_free:
376 kfree(pdata);
377exit:
378 return err;
379}
380
381static void delete_sensor_attr(struct sensor_data *pdata)
382{
383 struct sensor_entry *s, *l;
384
385 list_for_each_entry_safe(s, l, &pdata->sensor_list, list) {
386 struct sensor_specific_data *tdata = s->sensor_data;
387 kfree(tdata);
388 list_del(&s->list);
389 kfree(s);
390 }
391}
392
393static int powernv_sensor_init(u32 sensor_id, const struct device_node *np,
394 enum sensors sensor_type, enum attributes attr_type,
395 u32 sensor_index)
396{
397 struct platform_device *pdev = powernv_sensor_get_pdev(sensor_type);
398 struct sensor_specific_data *tdata;
399 struct sensor_entry *sensor_entry;
400 struct sensor_data *pdata;
401 int err = 0;
402
403 if (!pdev) {
404 err = create_platform_device(sensor_type, &pdev);
405 if (err)
406 goto exit;
407
408 err = create_sensor_data(pdev);
409 if (err)
410 goto exit;
411 }
412
413 pdata = platform_get_drvdata(pdev);
414 if (!pdata) {
415 err = -ENOMEM;
416 goto exit;
417 }
418
419 tdata = kzalloc(sizeof(struct sensor_specific_data), GFP_KERNEL);
420 if (!tdata) {
421 err = -ENOMEM;
422 goto exit;
423 }
424
425 tdata->sensor_id = sensor_id;
426 tdata->sensor_index = sensor_index;
427
428 err = create_sensor_attr(tdata, &pdev->dev, sensor_type, attr_type);
429 if (err)
430 goto exit_free;
431
432 sensor_entry = kzalloc(sizeof(struct sensor_entry), GFP_KERNEL);
433 if (!sensor_entry) {
434 err = -ENOMEM;
435 goto exit_attr;
436 }
437
438 sensor_entry->sensor_data = tdata;
439
440 list_add_tail(&sensor_entry->list, &pdata->sensor_list);
441
442 return 0;
443exit_attr:
444 device_remove_file(&pdev->dev, &tdata->sd_attr.dev_attr);
445exit_free:
446 kfree(tdata);
447exit:
448 return err;
449}
450
451static void delete_unregister_sensors(void)
452{
453 struct pdev_entry *p, *n;
454
455 list_for_each_entry_safe(p, n, &pdev_list, list) {
456 struct sensor_data *pdata = platform_get_drvdata(p->pdev);
457 if (pdata) {
458 delete_sensor_attr(pdata);
459
460 hwmon_device_unregister(pdata->hwmon_dev);
461 kfree(pdata);
462 }
463 platform_device_unregister(p->pdev);
464 list_del(&p->list);
465 kfree(p);
466 }
467}
468
469static int __init powernv_hwmon_init(void)
470{
471 struct device_node *opal, *np = NULL;
472 enum attributes attr_type;
473 enum sensors type;
474 const u32 *sensor_id;
475 u32 sensor_index;
476 int err;
477
478 opal = of_find_node_by_path("/ibm,opal/sensors");
479 if (!opal) {
480 pr_err("%s: Opal 'sensors' node not found\n", __func__);
481 return -ENXIO;
482 }
483
484 for_each_child_of_node(opal, np) {
485 if (np->name == NULL)
486 continue;
487
488 for (type = 0; type < MAX_SENSOR_TYPE; type++)
489 if (of_device_is_compatible(np,
490 sensor_names[type].compaible))
491 break;
492
493 if (type == MAX_SENSOR_TYPE)
494 continue;
495
496 if (get_sensor_attr_properties(np->name, type, &attr_type,
497 &sensor_index))
498 continue;
499
500 sensor_id = of_get_property(np, "sensor-id", NULL);
501 if (!sensor_id) {
502 pr_info("%s: %s doesn't have sensor-id\n", __func__,
503 np->name);
504 continue;
505 }
506
507 err = powernv_sensor_init(*sensor_id, np, type, attr_type,
508 sensor_index);
509 if (err) {
510 of_node_put(opal);
511 goto exit;
512 }
513 }
514 of_node_put(opal);
515
516 return 0;
517exit:
518 delete_unregister_sensors();
519 return err;
520
521}
522
523static void powernv_hwmon_exit(void)
524{
525 delete_unregister_sensors();
526}
527
528module_init(powernv_hwmon_init);
529module_exit(powernv_hwmon_exit);
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 6b579387c67a..aa0406895b53 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -70,8 +70,11 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
70 if (grp->bin_attrs) { 70 if (grp->bin_attrs) {
71 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { 71 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
72 if (update) 72 if (update)
73 sysfs_remove_bin_file(kobj, *bin_attr); 73 kernfs_remove_by_name(parent,
74 error = sysfs_create_bin_file(kobj, *bin_attr); 74 (*bin_attr)->attr.name);
75 error = sysfs_add_file_mode_ns(parent,
76 &(*bin_attr)->attr, true,
77 (*bin_attr)->attr.mode, NULL);
75 if (error) 78 if (error)
76 break; 79 break;
77 } 80 }