2 * PowerNV LPC bus handling.
4 * Copyright 2013 IBM Corp.
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.
12 #include <linux/kernel.h>
14 #include <linux/bug.h>
15 #include <linux/debugfs.h>
17 #include <linux/slab.h>
19 #include <asm/machdep.h>
20 #include <asm/firmware.h>
24 #include <asm/uaccess.h>
25 #include <asm/debug.h>
27 static int opal_lpc_chip_id
= -1;
29 static u8
opal_lpc_inb(unsigned long port
)
34 if (opal_lpc_chip_id
< 0 || port
> 0xffff)
36 rc
= opal_lpc_read(opal_lpc_chip_id
, OPAL_LPC_IO
, port
, &data
, 1);
37 return rc
? 0xff : be32_to_cpu(data
);
40 static __le16
__opal_lpc_inw(unsigned long port
)
45 if (opal_lpc_chip_id
< 0 || port
> 0xfffe)
48 return (__le16
)opal_lpc_inb(port
) << 8 | opal_lpc_inb(port
+ 1);
49 rc
= opal_lpc_read(opal_lpc_chip_id
, OPAL_LPC_IO
, port
, &data
, 2);
50 return rc
? 0xffff : be32_to_cpu(data
);
52 static u16
opal_lpc_inw(unsigned long port
)
54 return le16_to_cpu(__opal_lpc_inw(port
));
57 static __le32
__opal_lpc_inl(unsigned long port
)
62 if (opal_lpc_chip_id
< 0 || port
> 0xfffc)
65 return (__le32
)opal_lpc_inb(port
) << 24 |
66 (__le32
)opal_lpc_inb(port
+ 1) << 16 |
67 (__le32
)opal_lpc_inb(port
+ 2) << 8 |
68 opal_lpc_inb(port
+ 3);
69 rc
= opal_lpc_read(opal_lpc_chip_id
, OPAL_LPC_IO
, port
, &data
, 4);
70 return rc
? 0xffffffff : be32_to_cpu(data
);
73 static u32
opal_lpc_inl(unsigned long port
)
75 return le32_to_cpu(__opal_lpc_inl(port
));
78 static void opal_lpc_outb(u8 val
, unsigned long port
)
80 if (opal_lpc_chip_id
< 0 || port
> 0xffff)
82 opal_lpc_write(opal_lpc_chip_id
, OPAL_LPC_IO
, port
, val
, 1);
85 static void __opal_lpc_outw(__le16 val
, unsigned long port
)
87 if (opal_lpc_chip_id
< 0 || port
> 0xfffe)
90 opal_lpc_outb(val
>> 8, port
);
91 opal_lpc_outb(val
, port
+ 1);
94 opal_lpc_write(opal_lpc_chip_id
, OPAL_LPC_IO
, port
, val
, 2);
97 static void opal_lpc_outw(u16 val
, unsigned long port
)
99 __opal_lpc_outw(cpu_to_le16(val
), port
);
102 static void __opal_lpc_outl(__le32 val
, unsigned long port
)
104 if (opal_lpc_chip_id
< 0 || port
> 0xfffc)
107 opal_lpc_outb(val
>> 24, port
);
108 opal_lpc_outb(val
>> 16, port
+ 1);
109 opal_lpc_outb(val
>> 8, port
+ 2);
110 opal_lpc_outb(val
, port
+ 3);
113 opal_lpc_write(opal_lpc_chip_id
, OPAL_LPC_IO
, port
, val
, 4);
116 static void opal_lpc_outl(u32 val
, unsigned long port
)
118 __opal_lpc_outl(cpu_to_le32(val
), port
);
121 static void opal_lpc_insb(unsigned long p
, void *b
, unsigned long c
)
126 *(ptr
++) = opal_lpc_inb(p
);
129 static void opal_lpc_insw(unsigned long p
, void *b
, unsigned long c
)
134 *(ptr
++) = __opal_lpc_inw(p
);
137 static void opal_lpc_insl(unsigned long p
, void *b
, unsigned long c
)
142 *(ptr
++) = __opal_lpc_inl(p
);
145 static void opal_lpc_outsb(unsigned long p
, const void *b
, unsigned long c
)
150 opal_lpc_outb(*(ptr
++), p
);
153 static void opal_lpc_outsw(unsigned long p
, const void *b
, unsigned long c
)
155 const __le16
*ptr
= b
;
158 __opal_lpc_outw(*(ptr
++), p
);
161 static void opal_lpc_outsl(unsigned long p
, const void *b
, unsigned long c
)
163 const __le32
*ptr
= b
;
166 __opal_lpc_outl(*(ptr
++), p
);
169 static const struct ppc_pci_io opal_lpc_io
= {
173 .outb
= opal_lpc_outb
,
174 .outw
= opal_lpc_outw
,
175 .outl
= opal_lpc_outl
,
176 .insb
= opal_lpc_insb
,
177 .insw
= opal_lpc_insw
,
178 .insl
= opal_lpc_insl
,
179 .outsb
= opal_lpc_outsb
,
180 .outsw
= opal_lpc_outsw
,
181 .outsl
= opal_lpc_outsl
,
184 #ifdef CONFIG_DEBUG_FS
185 struct lpc_debugfs_entry
{
186 enum OpalLPCAddressType lpc_type
;
189 static ssize_t
lpc_debug_read(struct file
*filp
, char __user
*ubuf
,
190 size_t count
, loff_t
*ppos
)
192 struct lpc_debugfs_entry
*lpc
= filp
->private_data
;
193 u32 data
, pos
, len
, todo
;
197 if (!access_ok(VERIFY_WRITE
, ubuf
, count
))
205 * Select access size based on count and alignment and
206 * access type. IO and MEM only support byte acceses,
210 if (lpc
->lpc_type
== OPAL_LPC_FW
) {
211 if (todo
> 3 && (pos
& 3) == 0)
213 else if (todo
> 1 && (pos
& 1) == 0)
216 rc
= opal_lpc_read(opal_lpc_chip_id
, lpc
->lpc_type
, pos
,
220 data
= be32_to_cpu(bedata
);
223 rc
= __put_user((u32
)data
, (u32 __user
*)ubuf
);
226 rc
= __put_user((u16
)data
, (u16 __user
*)ubuf
);
229 rc
= __put_user((u8
)data
, (u8 __user
*)ubuf
);
242 static ssize_t
lpc_debug_write(struct file
*filp
, const char __user
*ubuf
,
243 size_t count
, loff_t
*ppos
)
245 struct lpc_debugfs_entry
*lpc
= filp
->private_data
;
246 u32 data
, pos
, len
, todo
;
249 if (!access_ok(VERIFY_READ
, ubuf
, count
))
257 * Select access size based on count and alignment and
258 * access type. IO and MEM only support byte acceses,
262 if (lpc
->lpc_type
== OPAL_LPC_FW
) {
263 if (todo
> 3 && (pos
& 3) == 0)
265 else if (todo
> 1 && (pos
& 1) == 0)
270 rc
= __get_user(data
, (u32 __user
*)ubuf
);
273 rc
= __get_user(data
, (u16 __user
*)ubuf
);
276 rc
= __get_user(data
, (u8 __user
*)ubuf
);
282 rc
= opal_lpc_write(opal_lpc_chip_id
, lpc
->lpc_type
, pos
,
294 static const struct file_operations lpc_fops
= {
295 .read
= lpc_debug_read
,
296 .write
= lpc_debug_write
,
298 .llseek
= default_llseek
,
301 static int opal_lpc_debugfs_create_type(struct dentry
*folder
,
303 enum OpalLPCAddressType type
)
305 struct lpc_debugfs_entry
*entry
;
306 entry
= kzalloc(sizeof(*entry
), GFP_KERNEL
);
309 entry
->lpc_type
= type
;
310 debugfs_create_file(fname
, 0600, folder
, entry
, &lpc_fops
);
314 static int opal_lpc_init_debugfs(void)
319 if (opal_lpc_chip_id
< 0)
322 root
= debugfs_create_dir("lpc", powerpc_debugfs_root
);
324 rc
|= opal_lpc_debugfs_create_type(root
, "io", OPAL_LPC_IO
);
325 rc
|= opal_lpc_debugfs_create_type(root
, "mem", OPAL_LPC_MEM
);
326 rc
|= opal_lpc_debugfs_create_type(root
, "fw", OPAL_LPC_FW
);
329 machine_device_initcall(powernv
, opal_lpc_init_debugfs
);
330 #endif /* CONFIG_DEBUG_FS */
332 void opal_lpc_init(void)
334 struct device_node
*np
;
337 * Look for a Power8 LPC bus tagged as "primary",
338 * we currently support only one though the OPAL APIs
339 * support any number.
341 for_each_compatible_node(np
, NULL
, "ibm,power8-lpc") {
342 if (!of_device_is_available(np
))
344 if (!of_get_property(np
, "primary", NULL
))
346 opal_lpc_chip_id
= of_get_ibm_chip_id(np
);
349 if (opal_lpc_chip_id
< 0)
352 /* Setup special IO ops */
353 ppc_pci_io
= opal_lpc_io
;
354 isa_io_special
= true;
356 pr_info("OPAL: Power8 LPC bus found, chip ID %d\n", opal_lpc_chip_id
);