1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2015 IBM Corp.
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/slab.h>
11 #include <linux/of_address.h>
12 #include <linux/of_platform.h>
16 static int read_phys_addr(struct device_node
*np
, char *prop_name
,
19 int i
, len
, entry_size
, naddr
, nsize
, type
;
23 naddr
= of_n_addr_cells(np
);
24 nsize
= of_n_size_cells(np
);
26 prop
= of_get_property(np
, prop_name
, &len
);
28 entry_size
= naddr
+ nsize
;
29 for (i
= 0; i
< (len
/ 4); i
+= entry_size
, prop
+= entry_size
) {
30 type
= be32_to_cpu(prop
[0]);
31 addr
= of_read_number(prop
, naddr
);
32 size
= of_read_number(&prop
[naddr
], nsize
);
34 case 0: /* unit address */
35 afu
->guest
->handle
= addr
;
38 afu
->guest
->p2n_phys
+= addr
;
39 afu
->guest
->p2n_size
= size
;
41 case 2: /* problem state area */
42 afu
->psn_phys
+= addr
;
43 afu
->adapter
->ps_size
= size
;
46 pr_err("Invalid address type %d found in %s property of AFU\n",
55 static int read_vpd(struct cxl
*adapter
, struct cxl_afu
*afu
)
59 size_t len
= sizeof(vpd
);
64 rc
= cxl_guest_read_adapter_vpd(adapter
, vpd
, len
);
66 rc
= cxl_guest_read_afu_vpd(afu
, vpd
, len
);
69 cxl_dump_debug_buffer(vpd
, rc
);
75 int cxl_of_read_afu_handle(struct cxl_afu
*afu
, struct device_node
*afu_np
)
77 return of_property_read_reg(afu_np
, 0, &afu
->guest
->handle
, NULL
);
80 int cxl_of_read_afu_properties(struct cxl_afu
*afu
, struct device_node
*np
)
83 u16 device_id
, vendor_id
;
84 u32 val
= 0, class_code
;
86 /* Properties are read in the same order as listed in PAPR */
88 rc
= read_phys_addr(np
, "reg", afu
);
92 rc
= read_phys_addr(np
, "assigned-addresses", afu
);
96 if (afu
->psn_phys
== 0)
101 of_property_read_u32(np
, "ibm,#processes", &afu
->max_procs_virtualised
);
106 of_property_read_u32(np
, "ibm,max-ints-per-process", &afu
->guest
->max_ints
);
107 afu
->irqs_max
= afu
->guest
->max_ints
;
109 if (!of_property_read_u32(np
, "ibm,min-ints-per-process", &afu
->pp_irqs
)) {
110 /* One extra interrupt for the PSL interrupt is already
111 * included. Remove it now to keep only AFU interrupts and
112 * match the native case.
117 of_property_read_u64(np
, "ibm,error-buffer-size", &afu
->eb_len
);
120 of_property_read_u64(np
, "ibm,config-record-size", &afu
->crs_len
);
123 of_property_read_u32(np
, "ibm,#config-records", &afu
->crs_num
);
126 for (i
= 0; i
< afu
->crs_num
; i
++) {
127 rc
= cxl_ops
->afu_cr_read16(afu
, i
, PCI_DEVICE_ID
,
130 pr_info("record %d - device-id: %#x\n",
132 rc
= cxl_ops
->afu_cr_read16(afu
, i
, PCI_VENDOR_ID
,
135 pr_info("record %d - vendor-id: %#x\n",
137 rc
= cxl_ops
->afu_cr_read32(afu
, i
, PCI_CLASS_REVISION
,
141 pr_info("record %d - class-code: %#x\n",
147 * if "ibm,process-mmio" doesn't exist then per-process mmio is
151 if (!of_property_read_u32(np
, "ibm,process-mmio", &val
) && val
== 1)
156 if (!of_property_read_u32(np
, "ibm,function-error-interrupt", &val
))
157 afu
->serr_hwirq
= val
;
159 pr_devel("AFU handle: %#llx\n", afu
->guest
->handle
);
160 pr_devel("p2n_phys: %#llx (size %#llx)\n",
161 afu
->guest
->p2n_phys
, afu
->guest
->p2n_size
);
162 pr_devel("psn_phys: %#llx (size %#llx)\n",
163 afu
->psn_phys
, afu
->adapter
->ps_size
);
164 pr_devel("Max number of processes virtualised=%i\n",
165 afu
->max_procs_virtualised
);
166 pr_devel("Per-process irqs min=%i, max=%i\n", afu
->pp_irqs
,
168 pr_devel("Slice error interrupt=%#lx\n", afu
->serr_hwirq
);
173 static int read_adapter_irq_config(struct cxl
*adapter
, struct device_node
*np
)
175 const __be32
*ranges
;
177 struct irq_avail
*cur
;
179 ranges
= of_get_property(np
, "interrupt-ranges", &len
);
180 if (ranges
== NULL
|| len
< (2 * sizeof(int)))
184 * encoded array of two cells per entry, each cell encoded as
187 nranges
= len
/ (2 * sizeof(int));
188 if (nranges
== 0 || (nranges
* 2 * sizeof(int)) != len
)
191 adapter
->guest
->irq_avail
= kcalloc(nranges
, sizeof(struct irq_avail
),
193 if (adapter
->guest
->irq_avail
== NULL
)
196 adapter
->guest
->irq_base_offset
= be32_to_cpu(ranges
[0]);
197 for (i
= 0; i
< nranges
; i
++) {
198 cur
= &adapter
->guest
->irq_avail
[i
];
199 cur
->offset
= be32_to_cpu(ranges
[i
* 2]);
200 cur
->range
= be32_to_cpu(ranges
[i
* 2 + 1]);
201 cur
->bitmap
= bitmap_zalloc(cur
->range
, GFP_KERNEL
);
202 if (cur
->bitmap
== NULL
)
204 if (cur
->offset
< adapter
->guest
->irq_base_offset
)
205 adapter
->guest
->irq_base_offset
= cur
->offset
;
207 pr_info("available IRQ range: %#lx-%#lx (%lu)\n",
208 cur
->offset
, cur
->offset
+ cur
->range
- 1,
211 adapter
->guest
->irq_nranges
= nranges
;
212 spin_lock_init(&adapter
->guest
->irq_alloc_lock
);
216 for (i
--; i
>= 0; i
--) {
217 cur
= &adapter
->guest
->irq_avail
[i
];
218 bitmap_free(cur
->bitmap
);
220 kfree(adapter
->guest
->irq_avail
);
221 adapter
->guest
->irq_avail
= NULL
;
225 int cxl_of_read_adapter_handle(struct cxl
*adapter
, struct device_node
*np
)
227 return of_property_read_reg(np
, 0, &adapter
->guest
->handle
, NULL
);
230 int cxl_of_read_adapter_properties(struct cxl
*adapter
, struct device_node
*np
)
236 /* Properties are read in the same order as listed in PAPR */
238 if ((rc
= read_adapter_irq_config(adapter
, np
)))
241 if (!of_property_read_u32(np
, "ibm,caia-version", &val
)) {
242 adapter
->caia_major
= (val
& 0xFF00) >> 8;
243 adapter
->caia_minor
= val
& 0xFF;
246 if (!of_property_read_u32(np
, "ibm,psl-revision", &val
))
247 adapter
->psl_rev
= val
;
249 if (!of_property_read_string(np
, "status", &p
)) {
250 adapter
->guest
->status
= kasprintf(GFP_KERNEL
, "%s", p
);
251 if (adapter
->guest
->status
== NULL
)
255 if (!of_property_read_u32(np
, "vendor-id", &val
))
256 adapter
->guest
->vendor
= val
;
258 if (!of_property_read_u32(np
, "device-id", &val
))
259 adapter
->guest
->device
= val
;
261 if (!of_property_read_u32(np
, "subsystem-vendor-id", &val
))
262 adapter
->guest
->subsystem_vendor
= val
;
264 if (!of_property_read_u32(np
, "subsystem-id", &val
))
265 adapter
->guest
->subsystem
= val
;
268 read_vpd(adapter
, NULL
);
273 static void cxl_of_remove(struct platform_device
*pdev
)
278 adapter
= dev_get_drvdata(&pdev
->dev
);
279 for (afu
= 0; afu
< adapter
->slices
; afu
++)
280 cxl_guest_remove_afu(adapter
->afu
[afu
]);
282 cxl_guest_remove_adapter(adapter
);
285 static void cxl_of_shutdown(struct platform_device
*pdev
)
290 int cxl_of_probe(struct platform_device
*pdev
)
292 struct device_node
*np
= NULL
;
293 struct device_node
*afu_np
= NULL
;
294 struct cxl
*adapter
= NULL
;
296 int slice
= 0, slice_ok
= 0;
298 pr_devel("in %s\n", __func__
);
300 np
= pdev
->dev
.of_node
;
305 adapter
= cxl_guest_init_adapter(np
, pdev
);
306 if (IS_ERR(adapter
)) {
307 dev_err(&pdev
->dev
, "guest_init_adapter failed: %li\n", PTR_ERR(adapter
));
308 return PTR_ERR(adapter
);
312 for_each_child_of_node(np
, afu_np
) {
313 if ((ret
= cxl_guest_init_afu(adapter
, slice
, afu_np
)))
314 dev_err(&pdev
->dev
, "AFU %i failed to initialise: %i\n",
322 dev_info(&pdev
->dev
, "No active AFU");
329 static const struct of_device_id cxl_of_match
[] = {
330 { .compatible
= "ibm,coherent-platform-facility",},
333 MODULE_DEVICE_TABLE(of
, cxl_of_match
);
335 struct platform_driver cxl_of_driver
= {
338 .of_match_table
= cxl_of_match
,
341 .probe
= cxl_of_probe
,
342 .remove
= cxl_of_remove
,
343 .shutdown
= cxl_of_shutdown
,