2 * Copyright 2015 IBM Corp.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/slab.h>
14 #include <linux/of_address.h>
15 #include <linux/of_platform.h>
20 static const __be32
*read_prop_string(const struct device_node
*np
,
21 const char *prop_name
)
25 prop
= of_get_property(np
, prop_name
, NULL
);
26 if (cxl_verbose
&& prop
)
27 pr_info("%s: %s\n", prop_name
, (char *) prop
);
31 static const __be32
*read_prop_dword(const struct device_node
*np
,
32 const char *prop_name
, u32
*val
)
36 prop
= of_get_property(np
, prop_name
, NULL
);
38 *val
= be32_to_cpu(prop
[0]);
39 if (cxl_verbose
&& prop
)
40 pr_info("%s: %#x (%u)\n", prop_name
, *val
, *val
);
44 static const __be64
*read_prop64_dword(const struct device_node
*np
,
45 const char *prop_name
, u64
*val
)
49 prop
= of_get_property(np
, prop_name
, NULL
);
51 *val
= be64_to_cpu(prop
[0]);
52 if (cxl_verbose
&& prop
)
53 pr_info("%s: %#llx (%llu)\n", prop_name
, *val
, *val
);
58 static int read_handle(struct device_node
*np
, u64
*handle
)
63 /* Get address and size of the node */
64 prop
= of_get_address(np
, 0, &size
, NULL
);
68 /* Helper to read a big number; size is in cells (not bytes) */
69 *handle
= of_read_number(prop
, of_n_addr_cells(np
));
73 static int read_phys_addr(struct device_node
*np
, char *prop_name
,
76 int i
, len
, entry_size
, naddr
, nsize
, type
;
80 naddr
= of_n_addr_cells(np
);
81 nsize
= of_n_size_cells(np
);
83 prop
= of_get_property(np
, prop_name
, &len
);
85 entry_size
= naddr
+ nsize
;
86 for (i
= 0; i
< (len
/ 4); i
+= entry_size
, prop
+= entry_size
) {
87 type
= be32_to_cpu(prop
[0]);
88 addr
= of_read_number(prop
, naddr
);
89 size
= of_read_number(&prop
[naddr
], nsize
);
91 case 0: /* unit address */
92 afu
->guest
->handle
= addr
;
95 afu
->guest
->p2n_phys
+= addr
;
96 afu
->guest
->p2n_size
= size
;
98 case 2: /* problem state area */
99 afu
->psn_phys
+= addr
;
100 afu
->adapter
->ps_size
= size
;
103 pr_err("Invalid address type %d found in %s property of AFU\n",
108 pr_info("%s: %#x %#llx (size %#llx)\n",
109 prop_name
, type
, addr
, size
);
115 static int read_vpd(struct cxl
*adapter
, struct cxl_afu
*afu
)
119 size_t len
= sizeof(vpd
);
124 rc
= cxl_guest_read_adapter_vpd(adapter
, vpd
, len
);
126 rc
= cxl_guest_read_afu_vpd(afu
, vpd
, len
);
129 cxl_dump_debug_buffer(vpd
, rc
);
135 int cxl_of_read_afu_handle(struct cxl_afu
*afu
, struct device_node
*afu_np
)
137 if (read_handle(afu_np
, &afu
->guest
->handle
))
139 pr_devel("AFU handle: 0x%.16llx\n", afu
->guest
->handle
);
144 int cxl_of_read_afu_properties(struct cxl_afu
*afu
, struct device_node
*np
)
149 u16 device_id
, vendor_id
;
150 u32 val
= 0, class_code
;
152 /* Properties are read in the same order as listed in PAPR */
155 pr_info("Dump of the 'ibm,coherent-platform-function' node properties:\n");
157 prop
= of_get_property(np
, "compatible", &len
);
160 p
= (char *) prop
+ i
;
161 pr_info("compatible: %s\n", p
);
164 read_prop_string(np
, "name");
167 rc
= read_phys_addr(np
, "reg", afu
);
171 rc
= read_phys_addr(np
, "assigned-addresses", afu
);
175 if (afu
->psn_phys
== 0)
181 read_prop_string(np
, "ibm,loc-code");
182 read_prop_string(np
, "device_type");
185 read_prop_dword(np
, "ibm,#processes", &afu
->max_procs_virtualised
);
188 read_prop_dword(np
, "ibm,scratchpad-size", &val
);
189 read_prop_dword(np
, "ibm,programmable", &val
);
190 read_prop_string(np
, "ibm,phandle");
194 read_prop_dword(np
, "ibm,max-ints-per-process", &afu
->guest
->max_ints
);
195 afu
->irqs_max
= afu
->guest
->max_ints
;
197 prop
= read_prop_dword(np
, "ibm,min-ints-per-process", &afu
->pp_irqs
);
199 /* One extra interrupt for the PSL interrupt is already
200 * included. Remove it now to keep only AFU interrupts and
201 * match the native case.
207 read_prop_dword(np
, "ibm,max-ints", &val
);
208 read_prop_dword(np
, "ibm,vpd-size", &val
);
211 read_prop64_dword(np
, "ibm,error-buffer-size", &afu
->eb_len
);
215 read_prop_dword(np
, "ibm,config-record-type", &val
);
217 read_prop64_dword(np
, "ibm,config-record-size", &afu
->crs_len
);
220 read_prop_dword(np
, "ibm,#config-records", &afu
->crs_num
);
223 for (i
= 0; i
< afu
->crs_num
; i
++) {
224 rc
= cxl_ops
->afu_cr_read16(afu
, i
, PCI_DEVICE_ID
,
227 pr_info("record %d - device-id: %#x\n",
229 rc
= cxl_ops
->afu_cr_read16(afu
, i
, PCI_VENDOR_ID
,
232 pr_info("record %d - vendor-id: %#x\n",
234 rc
= cxl_ops
->afu_cr_read32(afu
, i
, PCI_CLASS_REVISION
,
238 pr_info("record %d - class-code: %#x\n",
243 read_prop_dword(np
, "ibm,function-number", &val
);
244 read_prop_dword(np
, "ibm,privileged-function", &val
);
245 read_prop_dword(np
, "vendor-id", &val
);
246 read_prop_dword(np
, "device-id", &val
);
247 read_prop_dword(np
, "revision-id", &val
);
248 read_prop_dword(np
, "class-code", &val
);
249 read_prop_dword(np
, "subsystem-vendor-id", &val
);
250 read_prop_dword(np
, "subsystem-id", &val
);
253 * if "ibm,process-mmio" doesn't exist then per-process mmio is
257 prop
= read_prop_dword(np
, "ibm,process-mmio", &val
);
258 if (prop
&& val
== 1)
264 read_prop_dword(np
, "ibm,supports-aur", &val
);
265 read_prop_dword(np
, "ibm,supports-csrp", &val
);
266 read_prop_dword(np
, "ibm,supports-prr", &val
);
269 prop
= read_prop_dword(np
, "ibm,function-error-interrupt", &val
);
271 afu
->serr_hwirq
= val
;
273 pr_devel("AFU handle: %#llx\n", afu
->guest
->handle
);
274 pr_devel("p2n_phys: %#llx (size %#llx)\n",
275 afu
->guest
->p2n_phys
, afu
->guest
->p2n_size
);
276 pr_devel("psn_phys: %#llx (size %#llx)\n",
277 afu
->psn_phys
, afu
->adapter
->ps_size
);
278 pr_devel("Max number of processes virtualised=%i\n",
279 afu
->max_procs_virtualised
);
280 pr_devel("Per-process irqs min=%i, max=%i\n", afu
->pp_irqs
,
282 pr_devel("Slice error interrupt=%#lx\n", afu
->serr_hwirq
);
287 static int read_adapter_irq_config(struct cxl
*adapter
, struct device_node
*np
)
289 const __be32
*ranges
;
291 struct irq_avail
*cur
;
293 ranges
= of_get_property(np
, "interrupt-ranges", &len
);
294 if (ranges
== NULL
|| len
< (2 * sizeof(int)))
298 * encoded array of two cells per entry, each cell encoded as
301 nranges
= len
/ (2 * sizeof(int));
302 if (nranges
== 0 || (nranges
* 2 * sizeof(int)) != len
)
305 adapter
->guest
->irq_avail
= kcalloc(nranges
, sizeof(struct irq_avail
),
307 if (adapter
->guest
->irq_avail
== NULL
)
310 adapter
->guest
->irq_base_offset
= be32_to_cpu(ranges
[0]);
311 for (i
= 0; i
< nranges
; i
++) {
312 cur
= &adapter
->guest
->irq_avail
[i
];
313 cur
->offset
= be32_to_cpu(ranges
[i
* 2]);
314 cur
->range
= be32_to_cpu(ranges
[i
* 2 + 1]);
315 cur
->bitmap
= kcalloc(BITS_TO_LONGS(cur
->range
),
316 sizeof(*cur
->bitmap
), GFP_KERNEL
);
317 if (cur
->bitmap
== NULL
)
319 if (cur
->offset
< adapter
->guest
->irq_base_offset
)
320 adapter
->guest
->irq_base_offset
= cur
->offset
;
322 pr_info("available IRQ range: %#lx-%#lx (%lu)\n",
323 cur
->offset
, cur
->offset
+ cur
->range
- 1,
326 adapter
->guest
->irq_nranges
= nranges
;
327 spin_lock_init(&adapter
->guest
->irq_alloc_lock
);
331 for (i
--; i
>= 0; i
--) {
332 cur
= &adapter
->guest
->irq_avail
[i
];
335 kfree(adapter
->guest
->irq_avail
);
336 adapter
->guest
->irq_avail
= NULL
;
340 int cxl_of_read_adapter_handle(struct cxl
*adapter
, struct device_node
*np
)
342 if (read_handle(np
, &adapter
->guest
->handle
))
344 pr_devel("Adapter handle: 0x%.16llx\n", adapter
->guest
->handle
);
349 int cxl_of_read_adapter_properties(struct cxl
*adapter
, struct device_node
*np
)
351 int rc
, len
, naddr
, i
;
356 /* Properties are read in the same order as listed in PAPR */
358 naddr
= of_n_addr_cells(np
);
361 pr_info("Dump of the 'ibm,coherent-platform-facility' node properties:\n");
363 read_prop_dword(np
, "#address-cells", &val
);
364 read_prop_dword(np
, "#size-cells", &val
);
366 prop
= of_get_property(np
, "compatible", &len
);
369 p
= (char *) prop
+ i
;
370 pr_info("compatible: %s\n", p
);
373 read_prop_string(np
, "name");
374 read_prop_string(np
, "model");
376 prop
= of_get_property(np
, "reg", NULL
);
378 pr_info("reg: addr:%#llx size:%#x\n",
379 of_read_number(prop
, naddr
),
380 be32_to_cpu(prop
[naddr
]));
383 read_prop_string(np
, "ibm,loc-code");
386 if ((rc
= read_adapter_irq_config(adapter
, np
)))
390 read_prop_string(np
, "device_type");
391 read_prop_string(np
, "ibm,phandle");
394 prop
= read_prop_dword(np
, "ibm,caia-version", &val
);
396 adapter
->caia_major
= (val
& 0xFF00) >> 8;
397 adapter
->caia_minor
= val
& 0xFF;
400 prop
= read_prop_dword(np
, "ibm,psl-revision", &val
);
402 adapter
->psl_rev
= val
;
404 prop
= read_prop_string(np
, "status");
406 adapter
->guest
->status
= kasprintf(GFP_KERNEL
, "%s", (char *) prop
);
407 if (adapter
->guest
->status
== NULL
)
411 prop
= read_prop_dword(np
, "vendor-id", &val
);
413 adapter
->guest
->vendor
= val
;
415 prop
= read_prop_dword(np
, "device-id", &val
);
417 adapter
->guest
->device
= val
;
420 read_prop_dword(np
, "ibm,privileged-facility", &val
);
421 read_prop_dword(np
, "revision-id", &val
);
422 read_prop_dword(np
, "class-code", &val
);
425 prop
= read_prop_dword(np
, "subsystem-vendor-id", &val
);
427 adapter
->guest
->subsystem_vendor
= val
;
429 prop
= read_prop_dword(np
, "subsystem-id", &val
);
431 adapter
->guest
->subsystem
= val
;
434 read_vpd(adapter
, NULL
);
439 static int cxl_of_remove(struct platform_device
*pdev
)
444 adapter
= dev_get_drvdata(&pdev
->dev
);
445 for (afu
= 0; afu
< adapter
->slices
; afu
++)
446 cxl_guest_remove_afu(adapter
->afu
[afu
]);
448 cxl_guest_remove_adapter(adapter
);
452 static void cxl_of_shutdown(struct platform_device
*pdev
)
457 int cxl_of_probe(struct platform_device
*pdev
)
459 struct device_node
*np
= NULL
;
460 struct device_node
*afu_np
= NULL
;
461 struct cxl
*adapter
= NULL
;
463 int slice
= 0, slice_ok
= 0;
465 pr_devel("in %s\n", __func__
);
467 np
= pdev
->dev
.of_node
;
472 adapter
= cxl_guest_init_adapter(np
, pdev
);
473 if (IS_ERR(adapter
)) {
474 dev_err(&pdev
->dev
, "guest_init_adapter failed: %li\n", PTR_ERR(adapter
));
475 return PTR_ERR(adapter
);
479 for_each_child_of_node(np
, afu_np
) {
480 if ((ret
= cxl_guest_init_afu(adapter
, slice
, afu_np
)))
481 dev_err(&pdev
->dev
, "AFU %i failed to initialise: %i\n",
489 dev_info(&pdev
->dev
, "No active AFU");
496 static const struct of_device_id cxl_of_match
[] = {
497 { .compatible
= "ibm,coherent-platform-facility",},
500 MODULE_DEVICE_TABLE(of
, cxl_of_match
);
502 struct platform_driver cxl_of_driver
= {
505 .of_match_table
= cxl_of_match
,
508 .probe
= cxl_of_probe
,
509 .remove
= cxl_of_remove
,
510 .shutdown
= cxl_of_shutdown
,