This source file includes following definitions.
- opal_lpc_inb
- __opal_lpc_inw
- opal_lpc_inw
- __opal_lpc_inl
- opal_lpc_inl
- opal_lpc_outb
- __opal_lpc_outw
- opal_lpc_outw
- __opal_lpc_outl
- opal_lpc_outl
- opal_lpc_insb
- opal_lpc_insw
- opal_lpc_insl
- opal_lpc_outsb
- opal_lpc_outsw
- opal_lpc_outsl
- lpc_debug_read
- lpc_debug_write
- opal_lpc_debugfs_create_type
- opal_lpc_init_debugfs
- opal_lpc_init
1
2
3
4
5
6
7
8 #include <linux/kernel.h>
9 #include <linux/of.h>
10 #include <linux/bug.h>
11 #include <linux/io.h>
12 #include <linux/slab.h>
13
14 #include <asm/machdep.h>
15 #include <asm/firmware.h>
16 #include <asm/opal.h>
17 #include <asm/prom.h>
18 #include <linux/uaccess.h>
19 #include <asm/debugfs.h>
20 #include <asm/isa-bridge.h>
21
22 static int opal_lpc_chip_id = -1;
23
24 static u8 opal_lpc_inb(unsigned long port)
25 {
26 int64_t rc;
27 __be32 data;
28
29 if (opal_lpc_chip_id < 0 || port > 0xffff)
30 return 0xff;
31 rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 1);
32 return rc ? 0xff : be32_to_cpu(data);
33 }
34
35 static __le16 __opal_lpc_inw(unsigned long port)
36 {
37 int64_t rc;
38 __be32 data;
39
40 if (opal_lpc_chip_id < 0 || port > 0xfffe)
41 return 0xffff;
42 if (port & 1)
43 return (__le16)opal_lpc_inb(port) << 8 | opal_lpc_inb(port + 1);
44 rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 2);
45 return rc ? 0xffff : be32_to_cpu(data);
46 }
47 static u16 opal_lpc_inw(unsigned long port)
48 {
49 return le16_to_cpu(__opal_lpc_inw(port));
50 }
51
52 static __le32 __opal_lpc_inl(unsigned long port)
53 {
54 int64_t rc;
55 __be32 data;
56
57 if (opal_lpc_chip_id < 0 || port > 0xfffc)
58 return 0xffffffff;
59 if (port & 3)
60 return (__le32)opal_lpc_inb(port ) << 24 |
61 (__le32)opal_lpc_inb(port + 1) << 16 |
62 (__le32)opal_lpc_inb(port + 2) << 8 |
63 opal_lpc_inb(port + 3);
64 rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 4);
65 return rc ? 0xffffffff : be32_to_cpu(data);
66 }
67
68 static u32 opal_lpc_inl(unsigned long port)
69 {
70 return le32_to_cpu(__opal_lpc_inl(port));
71 }
72
73 static void opal_lpc_outb(u8 val, unsigned long port)
74 {
75 if (opal_lpc_chip_id < 0 || port > 0xffff)
76 return;
77 opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 1);
78 }
79
80 static void __opal_lpc_outw(__le16 val, unsigned long port)
81 {
82 if (opal_lpc_chip_id < 0 || port > 0xfffe)
83 return;
84 if (port & 1) {
85 opal_lpc_outb(val >> 8, port);
86 opal_lpc_outb(val , port + 1);
87 return;
88 }
89 opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 2);
90 }
91
92 static void opal_lpc_outw(u16 val, unsigned long port)
93 {
94 __opal_lpc_outw(cpu_to_le16(val), port);
95 }
96
97 static void __opal_lpc_outl(__le32 val, unsigned long port)
98 {
99 if (opal_lpc_chip_id < 0 || port > 0xfffc)
100 return;
101 if (port & 3) {
102 opal_lpc_outb(val >> 24, port);
103 opal_lpc_outb(val >> 16, port + 1);
104 opal_lpc_outb(val >> 8, port + 2);
105 opal_lpc_outb(val , port + 3);
106 return;
107 }
108 opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 4);
109 }
110
111 static void opal_lpc_outl(u32 val, unsigned long port)
112 {
113 __opal_lpc_outl(cpu_to_le32(val), port);
114 }
115
116 static void opal_lpc_insb(unsigned long p, void *b, unsigned long c)
117 {
118 u8 *ptr = b;
119
120 while(c--)
121 *(ptr++) = opal_lpc_inb(p);
122 }
123
124 static void opal_lpc_insw(unsigned long p, void *b, unsigned long c)
125 {
126 __le16 *ptr = b;
127
128 while(c--)
129 *(ptr++) = __opal_lpc_inw(p);
130 }
131
132 static void opal_lpc_insl(unsigned long p, void *b, unsigned long c)
133 {
134 __le32 *ptr = b;
135
136 while(c--)
137 *(ptr++) = __opal_lpc_inl(p);
138 }
139
140 static void opal_lpc_outsb(unsigned long p, const void *b, unsigned long c)
141 {
142 const u8 *ptr = b;
143
144 while(c--)
145 opal_lpc_outb(*(ptr++), p);
146 }
147
148 static void opal_lpc_outsw(unsigned long p, const void *b, unsigned long c)
149 {
150 const __le16 *ptr = b;
151
152 while(c--)
153 __opal_lpc_outw(*(ptr++), p);
154 }
155
156 static void opal_lpc_outsl(unsigned long p, const void *b, unsigned long c)
157 {
158 const __le32 *ptr = b;
159
160 while(c--)
161 __opal_lpc_outl(*(ptr++), p);
162 }
163
164 static const struct ppc_pci_io opal_lpc_io = {
165 .inb = opal_lpc_inb,
166 .inw = opal_lpc_inw,
167 .inl = opal_lpc_inl,
168 .outb = opal_lpc_outb,
169 .outw = opal_lpc_outw,
170 .outl = opal_lpc_outl,
171 .insb = opal_lpc_insb,
172 .insw = opal_lpc_insw,
173 .insl = opal_lpc_insl,
174 .outsb = opal_lpc_outsb,
175 .outsw = opal_lpc_outsw,
176 .outsl = opal_lpc_outsl,
177 };
178
179 #ifdef CONFIG_DEBUG_FS
180 struct lpc_debugfs_entry {
181 enum OpalLPCAddressType lpc_type;
182 };
183
184 static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf,
185 size_t count, loff_t *ppos)
186 {
187 struct lpc_debugfs_entry *lpc = filp->private_data;
188 u32 data, pos, len, todo;
189 int rc;
190
191 if (!access_ok(ubuf, count))
192 return -EFAULT;
193
194 todo = count;
195 while (todo) {
196 pos = *ppos;
197
198
199
200
201
202
203 len = 1;
204 if (lpc->lpc_type == OPAL_LPC_FW) {
205 if (todo > 3 && (pos & 3) == 0)
206 len = 4;
207 else if (todo > 1 && (pos & 1) == 0)
208 len = 2;
209 }
210 rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos,
211 &data, len);
212 if (rc)
213 return -ENXIO;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248 switch(len) {
249 case 4:
250 rc = __put_user((u32)data, (u32 __user *)ubuf);
251 break;
252 case 2:
253 #ifdef __LITTLE_ENDIAN__
254 data >>= 16;
255 #endif
256 rc = __put_user((u16)data, (u16 __user *)ubuf);
257 break;
258 default:
259 #ifdef __LITTLE_ENDIAN__
260 data >>= 24;
261 #endif
262 rc = __put_user((u8)data, (u8 __user *)ubuf);
263 break;
264 }
265 if (rc)
266 return -EFAULT;
267 *ppos += len;
268 ubuf += len;
269 todo -= len;
270 }
271
272 return count;
273 }
274
275 static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf,
276 size_t count, loff_t *ppos)
277 {
278 struct lpc_debugfs_entry *lpc = filp->private_data;
279 u32 data, pos, len, todo;
280 int rc;
281
282 if (!access_ok(ubuf, count))
283 return -EFAULT;
284
285 todo = count;
286 while (todo) {
287 pos = *ppos;
288
289
290
291
292
293
294 len = 1;
295 if (lpc->lpc_type == OPAL_LPC_FW) {
296 if (todo > 3 && (pos & 3) == 0)
297 len = 4;
298 else if (todo > 1 && (pos & 1) == 0)
299 len = 2;
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 switch(len) {
319 case 4:
320 rc = __get_user(data, (u32 __user *)ubuf);
321 data = cpu_to_be32(data);
322 break;
323 case 2:
324 rc = __get_user(data, (u16 __user *)ubuf);
325 data = cpu_to_be16(data);
326 break;
327 default:
328 rc = __get_user(data, (u8 __user *)ubuf);
329 break;
330 }
331 if (rc)
332 return -EFAULT;
333
334 rc = opal_lpc_write(opal_lpc_chip_id, lpc->lpc_type, pos,
335 data, len);
336 if (rc)
337 return -ENXIO;
338 *ppos += len;
339 ubuf += len;
340 todo -= len;
341 }
342
343 return count;
344 }
345
346 static const struct file_operations lpc_fops = {
347 .read = lpc_debug_read,
348 .write = lpc_debug_write,
349 .open = simple_open,
350 .llseek = default_llseek,
351 };
352
353 static int opal_lpc_debugfs_create_type(struct dentry *folder,
354 const char *fname,
355 enum OpalLPCAddressType type)
356 {
357 struct lpc_debugfs_entry *entry;
358 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
359 if (!entry)
360 return -ENOMEM;
361 entry->lpc_type = type;
362 debugfs_create_file(fname, 0600, folder, entry, &lpc_fops);
363 return 0;
364 }
365
366 static int opal_lpc_init_debugfs(void)
367 {
368 struct dentry *root;
369 int rc = 0;
370
371 if (opal_lpc_chip_id < 0)
372 return -ENODEV;
373
374 root = debugfs_create_dir("lpc", powerpc_debugfs_root);
375
376 rc |= opal_lpc_debugfs_create_type(root, "io", OPAL_LPC_IO);
377 rc |= opal_lpc_debugfs_create_type(root, "mem", OPAL_LPC_MEM);
378 rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW);
379 return rc;
380 }
381 machine_device_initcall(powernv, opal_lpc_init_debugfs);
382 #endif
383
384 void __init opal_lpc_init(void)
385 {
386 struct device_node *np;
387
388
389
390
391
392
393 for_each_compatible_node(np, NULL, "ibm,power8-lpc") {
394 if (!of_device_is_available(np))
395 continue;
396 if (!of_get_property(np, "primary", NULL))
397 continue;
398 opal_lpc_chip_id = of_get_ibm_chip_id(np);
399 break;
400 }
401 if (opal_lpc_chip_id < 0)
402 return;
403
404
405 if (of_get_property(np, "ranges", NULL)) {
406 pr_info("OPAL: Found memory mapped LPC bus on chip %d\n",
407 opal_lpc_chip_id);
408 isa_bridge_init_non_pci(np);
409 } else {
410 pr_info("OPAL: Found non-mapped LPC bus on chip %d\n",
411 opal_lpc_chip_id);
412
413
414 ppc_pci_io = opal_lpc_io;
415 isa_io_special = true;
416 }
417 }