projects/linux·blob master · refs

944 lines · 24.5 KiB

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * CDX bus driver.
4 *
5 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
6 */
7
8/*
9 * Architecture Overview
10 * =====================
11 * CDX is a Hardware Architecture designed for AMD FPGA devices. It
12 * consists of sophisticated mechanism for interaction between FPGA,
13 * Firmware and the APUs (Application CPUs).
14 *
15 * Firmware resides on RPU (Realtime CPUs) which interacts with
16 * the FPGA program manager and the APUs. The RPU provides memory-mapped
17 * interface (RPU if) which is used to communicate with APUs.
18 *
19 * The diagram below shows an overview of the CDX architecture:
20 *
21 * +--------------------------------------+
22 * | Application CPUs (APU) |
23 * | |
24 * | CDX device drivers|
25 * | Linux OS | |
26 * | CDX bus |
27 * | | |
28 * | CDX controller |
29 * | | |
30 * +-----------------------------|--------+
31 * | (discover, config,
32 * | reset, rescan)
33 * |
34 * +------------------------| RPU if |----+
35 * | | |
36 * | V |
37 * | Realtime CPUs (RPU) |
38 * | |
39 * +--------------------------------------+
40 * |
41 * +---------------------|----------------+
42 * | FPGA | |
43 * | +-----------------------+ |
44 * | | | | |
45 * | +-------+ +-------+ +-------+ |
46 * | | dev 1 | | dev 2 | | dev 3 | |
47 * | +-------+ +-------+ +-------+ |
48 * +--------------------------------------+
49 *
50 * The RPU firmware extracts the device information from the loaded FPGA
51 * image and implements a mechanism that allows the APU drivers to
52 * enumerate such devices (device personality and resource details) via
53 * a dedicated communication channel. RPU mediates operations such as
54 * discover, reset and rescan of the FPGA devices for the APU. This is
55 * done using memory mapped interface provided by the RPU to APU.
56 */
57
58#include <linux/init.h>
59#include <linux/irqdomain.h>
60#include <linux/kernel.h>
61#include <linux/of.h>
62#include <linux/of_device.h>
63#include <linux/of_platform.h>
64#include <linux/platform_device.h>
65#include <linux/slab.h>
66#include <linux/mm.h>
67#include <linux/idr.h>
68#include <linux/cdx/cdx_bus.h>
69#include <linux/iommu.h>
70#include <linux/dma-map-ops.h>
71#include <linux/debugfs.h>
72#include "cdx.h"
73
74/* Default DMA mask for devices on a CDX bus */
75#define CDX_DEFAULT_DMA_MASK (~0ULL)
76#define MAX_CDX_CONTROLLERS 16
77
78/* IDA for CDX controllers registered with the CDX bus */
79static DEFINE_IDA(cdx_controller_ida);
80/* Lock to protect controller ops */
81static DEFINE_MUTEX(cdx_controller_lock);
82/* Debugfs dir for cdx bus */
83static struct dentry *cdx_debugfs_dir;
84
85static char *compat_node_name = "xlnx,versal-net-cdx";
86
87static void cdx_destroy_res_attr(struct cdx_device *cdx_dev, int num);
88
89/**
90 * cdx_dev_reset - Reset a CDX device
91 * @dev: CDX device
92 *
93 * Return: -errno on failure, 0 on success.
94 */
95int cdx_dev_reset(struct device *dev)
96{
97 struct cdx_device *cdx_dev = to_cdx_device(dev);
98 struct cdx_controller *cdx = cdx_dev->cdx;
99 struct cdx_device_config dev_config = {0};
100 struct cdx_driver *cdx_drv;
101 int ret;
102
103 cdx_drv = to_cdx_driver(dev->driver);
104 /* Notify driver that device is being reset */
105 if (cdx_drv && cdx_drv->reset_prepare)
106 cdx_drv->reset_prepare(cdx_dev);
107
108 dev_config.type = CDX_DEV_RESET_CONF;
109 ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
110 cdx_dev->dev_num, &dev_config);
111 if (ret)
112 dev_err(dev, "cdx device reset failed\n");
113
114 /* Notify driver that device reset is complete */
115 if (cdx_drv && cdx_drv->reset_done)
116 cdx_drv->reset_done(cdx_dev);
117
118 return ret;
119}
120EXPORT_SYMBOL_GPL(cdx_dev_reset);
121
122/**
123 * reset_cdx_device - Reset a CDX device
124 * @dev: CDX device
125 * @data: This is always passed as NULL, and is not used in this API,
126 * but is required here as the device_for_each_child() API expects
127 * the passed function to have this as an argument.
128 *
129 * Return: -errno on failure, 0 on success.
130 */
131static int reset_cdx_device(struct device *dev, void *data)
132{
133 return cdx_dev_reset(dev);
134}
135
136/**
137 * cdx_unregister_device - Unregister a CDX device
138 * @dev: CDX device
139 * @data: This is always passed as NULL, and is not used in this API,
140 * but is required here as the bus_for_each_dev() API expects
141 * the passed function (cdx_unregister_device) to have this
142 * as an argument.
143 *
144 * Return: 0 on success.
145 */
146static int cdx_unregister_device(struct device *dev,
147 void *data)
148{
149 struct cdx_device *cdx_dev = to_cdx_device(dev);
150 struct cdx_controller *cdx = cdx_dev->cdx;
151
152 if (cdx_dev->is_bus) {
153 device_for_each_child(dev, NULL, cdx_unregister_device);
154 if (cdx_dev->enabled && cdx->ops->bus_disable)
155 cdx->ops->bus_disable(cdx, cdx_dev->bus_num);
156 } else {
157 cdx_destroy_res_attr(cdx_dev, MAX_CDX_DEV_RESOURCES);
158 debugfs_remove_recursive(cdx_dev->debugfs_dir);
159 }
160
161 /*
162 * Do not free cdx_dev here as it would be freed in
163 * cdx_device_release() called from within put_device().
164 */
165 device_del(&cdx_dev->dev);
166 put_device(&cdx_dev->dev);
167
168 return 0;
169}
170
171static void cdx_unregister_devices(const struct bus_type *bus)
172{
173 /* Reset all the devices attached to cdx bus */
174 bus_for_each_dev(bus, NULL, NULL, cdx_unregister_device);
175}
176
177/**
178 * cdx_match_one_device - Tell if a CDX device structure has a matching
179 * CDX device id structure
180 * @id: single CDX device id structure to match
181 * @dev: the CDX device structure to match against
182 *
183 * Return: matching cdx_device_id structure or NULL if there is no match.
184 */
185static inline const struct cdx_device_id *
186cdx_match_one_device(const struct cdx_device_id *id,
187 const struct cdx_device *dev)
188{
189 /* Use vendor ID and device ID for matching */
190 if ((id->vendor == CDX_ANY_ID || id->vendor == dev->vendor) &&
191 (id->device == CDX_ANY_ID || id->device == dev->device) &&
192 (id->subvendor == CDX_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
193 (id->subdevice == CDX_ANY_ID || id->subdevice == dev->subsystem_device) &&
194 !((id->class ^ dev->class) & id->class_mask))
195 return id;
196 return NULL;
197}
198
199/**
200 * cdx_match_id - See if a CDX device matches a given cdx_id table
201 * @ids: array of CDX device ID structures to search in
202 * @dev: the CDX device structure to match against.
203 *
204 * Used by a driver to check whether a CDX device is in its list of
205 * supported devices. Returns the matching cdx_device_id structure or
206 * NULL if there is no match.
207 *
208 * Return: matching cdx_device_id structure or NULL if there is no match.
209 */
210static inline const struct cdx_device_id *
211cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev)
212{
213 if (ids) {
214 while (ids->vendor || ids->device) {
215 if (cdx_match_one_device(ids, dev))
216 return ids;
217 ids++;
218 }
219 }
220 return NULL;
221}
222
223int cdx_set_master(struct cdx_device *cdx_dev)
224{
225 struct cdx_controller *cdx = cdx_dev->cdx;
226 struct cdx_device_config dev_config;
227 int ret = -EOPNOTSUPP;
228
229 dev_config.type = CDX_DEV_BUS_MASTER_CONF;
230 dev_config.bus_master_enable = true;
231 if (cdx->ops->dev_configure)
232 ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
233 cdx_dev->dev_num, &dev_config);
234
235 return ret;
236}
237EXPORT_SYMBOL_GPL(cdx_set_master);
238
239int cdx_clear_master(struct cdx_device *cdx_dev)
240{
241 struct cdx_controller *cdx = cdx_dev->cdx;
242 struct cdx_device_config dev_config;
243 int ret = -EOPNOTSUPP;
244
245 dev_config.type = CDX_DEV_BUS_MASTER_CONF;
246 dev_config.bus_master_enable = false;
247 if (cdx->ops->dev_configure)
248 ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
249 cdx_dev->dev_num, &dev_config);
250
251 return ret;
252}
253EXPORT_SYMBOL_GPL(cdx_clear_master);
254
255/**
256 * cdx_bus_match - device to driver matching callback
257 * @dev: the cdx device to match against
258 * @drv: the device driver to search for matching cdx device
259 * structures
260 *
261 * Return: true on success, false otherwise.
262 */
263static int cdx_bus_match(struct device *dev, const struct device_driver *drv)
264{
265 struct cdx_device *cdx_dev = to_cdx_device(dev);
266 const struct cdx_driver *cdx_drv = to_cdx_driver(drv);
267 const struct cdx_device_id *found_id = NULL;
268 const struct cdx_device_id *ids;
269 int ret;
270
271 if (cdx_dev->is_bus)
272 return false;
273
274 ids = cdx_drv->match_id_table;
275
276 /* When driver_override is set, only bind to the matching driver */
277 ret = device_match_driver_override(dev, drv);
278 if (ret == 0)
279 return false;
280
281 found_id = cdx_match_id(ids, cdx_dev);
282 if (!found_id)
283 return false;
284
285 do {
286 /*
287 * In case override_only was set, enforce driver_override
288 * matching.
289 */
290 if (!found_id->override_only)
291 return true;
292 if (ret > 0)
293 return true;
294
295 ids = found_id + 1;
296 found_id = cdx_match_id(ids, cdx_dev);
297 } while (found_id);
298
299 return false;
300}
301
302static int cdx_probe(struct device *dev)
303{
304 struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
305 struct cdx_device *cdx_dev = to_cdx_device(dev);
306 struct cdx_controller *cdx = cdx_dev->cdx;
307 int error;
308
309 /*
310 * Setup MSI device data so that generic MSI alloc/free can
311 * be used by the device driver.
312 */
313 if (IS_ENABLED(CONFIG_GENERIC_MSI_IRQ) && cdx->msi_domain) {
314 error = msi_setup_device_data(&cdx_dev->dev);
315 if (error)
316 return error;
317 }
318
319 error = cdx_drv->probe(cdx_dev);
320 if (error) {
321 dev_err_probe(dev, error, "%s failed\n", __func__);
322 return error;
323 }
324
325 return 0;
326}
327
328static void cdx_remove(struct device *dev)
329{
330 struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
331 struct cdx_device *cdx_dev = to_cdx_device(dev);
332
333 if (cdx_drv && cdx_drv->remove)
334 cdx_drv->remove(cdx_dev);
335}
336
337static void cdx_shutdown(struct device *dev)
338{
339 struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
340 struct cdx_device *cdx_dev = to_cdx_device(dev);
341 struct cdx_controller *cdx = cdx_dev->cdx;
342
343 if (cdx_dev->is_bus && cdx_dev->enabled && cdx->ops->bus_disable)
344 cdx->ops->bus_disable(cdx, cdx_dev->bus_num);
345 if (cdx_drv && cdx_drv->shutdown)
346 cdx_drv->shutdown(cdx_dev);
347}
348
349static int cdx_dma_configure(struct device *dev)
350{
351 struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
352 struct cdx_device *cdx_dev = to_cdx_device(dev);
353 struct cdx_controller *cdx = cdx_dev->cdx;
354 u32 input_id = cdx_dev->req_id;
355 int ret;
356
357 ret = of_dma_configure_id(dev, cdx->dev->of_node, 0, &input_id);
358 if (ret && ret != -EPROBE_DEFER) {
359 dev_err(dev, "of_dma_configure_id() failed\n");
360 return ret;
361 }
362
363 /* @cdx_drv may not be valid when we're called from the IOMMU layer */
364 if (!ret && dev->driver && !cdx_drv->driver_managed_dma) {
365 ret = iommu_device_use_default_domain(dev);
366 if (ret)
367 arch_teardown_dma_ops(dev);
368 }
369
370 return 0;
371}
372
373static void cdx_dma_cleanup(struct device *dev)
374{
375 struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
376
377 if (!cdx_drv->driver_managed_dma)
378 iommu_device_unuse_default_domain(dev);
379}
380
381/* show configuration fields */
382#define cdx_config_attr(field, format_string) \
383static ssize_t \
384field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
385{ \
386 struct cdx_device *cdx_dev = to_cdx_device(dev); \
387 return sysfs_emit(buf, format_string, cdx_dev->field); \
388} \
389static DEVICE_ATTR_RO(field)
390
391cdx_config_attr(vendor, "0x%04x\n");
392cdx_config_attr(device, "0x%04x\n");
393cdx_config_attr(subsystem_vendor, "0x%04x\n");
394cdx_config_attr(subsystem_device, "0x%04x\n");
395cdx_config_attr(revision, "0x%02x\n");
396cdx_config_attr(class, "0x%06x\n");
397
398static ssize_t remove_store(struct device *dev,
399 struct device_attribute *attr,
400 const char *buf, size_t count)
401{
402 bool val;
403
404 if (kstrtobool(buf, &val) < 0)
405 return -EINVAL;
406
407 if (!val)
408 return -EINVAL;
409
410 if (device_remove_file_self(dev, attr)) {
411 int ret;
412
413 ret = cdx_unregister_device(dev, NULL);
414 if (ret)
415 return ret;
416 }
417
418 return count;
419}
420static DEVICE_ATTR_WO(remove);
421
422static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
423 const char *buf, size_t count)
424{
425 struct cdx_device *cdx_dev = to_cdx_device(dev);
426 bool val;
427 int ret;
428
429 if (kstrtobool(buf, &val) < 0)
430 return -EINVAL;
431
432 if (!val)
433 return -EINVAL;
434
435 if (cdx_dev->is_bus)
436 /* Reset all the devices attached to cdx bus */
437 ret = device_for_each_child(dev, NULL, reset_cdx_device);
438 else
439 ret = cdx_dev_reset(dev);
440
441 return ret < 0 ? ret : count;
442}
443static DEVICE_ATTR_WO(reset);
444
445static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
446 char *buf)
447{
448 struct cdx_device *cdx_dev = to_cdx_device(dev);
449
450 return sprintf(buf, "cdx:v%04Xd%04Xsv%04Xsd%04Xc%06X\n", cdx_dev->vendor,
451 cdx_dev->device, cdx_dev->subsystem_vendor, cdx_dev->subsystem_device,
452 cdx_dev->class);
453}
454static DEVICE_ATTR_RO(modalias);
455
456static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
457 const char *buf, size_t count)
458{
459 struct cdx_device *cdx_dev = to_cdx_device(dev);
460 struct cdx_controller *cdx = cdx_dev->cdx;
461 bool enable;
462 int ret;
463
464 if (kstrtobool(buf, &enable) < 0)
465 return -EINVAL;
466
467 if (enable == cdx_dev->enabled)
468 return count;
469
470 if (enable && cdx->ops->bus_enable)
471 ret = cdx->ops->bus_enable(cdx, cdx_dev->bus_num);
472 else if (!enable && cdx->ops->bus_disable)
473 ret = cdx->ops->bus_disable(cdx, cdx_dev->bus_num);
474 else
475 ret = -EOPNOTSUPP;
476
477 if (!ret)
478 cdx_dev->enabled = enable;
479
480 return ret < 0 ? ret : count;
481}
482
483static ssize_t enable_show(struct device *dev, struct device_attribute *attr, char *buf)
484{
485 struct cdx_device *cdx_dev = to_cdx_device(dev);
486
487 return sysfs_emit(buf, "%u\n", cdx_dev->enabled);
488}
489static DEVICE_ATTR_RW(enable);
490
491static umode_t cdx_dev_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)
492{
493 struct device *dev = kobj_to_dev(kobj);
494 struct cdx_device *cdx_dev;
495
496 cdx_dev = to_cdx_device(dev);
497 if (!cdx_dev->is_bus)
498 return a->mode;
499
500 return 0;
501}
502
503static umode_t cdx_bus_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)
504{
505 struct device *dev = kobj_to_dev(kobj);
506 struct cdx_device *cdx_dev;
507
508 cdx_dev = to_cdx_device(dev);
509 if (cdx_dev->is_bus)
510 return a->mode;
511
512 return 0;
513}
514
515static struct attribute *cdx_dev_attrs[] = {
516 &dev_attr_remove.attr,
517 &dev_attr_reset.attr,
518 &dev_attr_vendor.attr,
519 &dev_attr_device.attr,
520 &dev_attr_subsystem_vendor.attr,
521 &dev_attr_subsystem_device.attr,
522 &dev_attr_class.attr,
523 &dev_attr_revision.attr,
524 &dev_attr_modalias.attr,
525 NULL,
526};
527
528static const struct attribute_group cdx_dev_group = {
529 .attrs = cdx_dev_attrs,
530 .is_visible = cdx_dev_attrs_are_visible,
531};
532
533static struct attribute *cdx_bus_dev_attrs[] = {
534 &dev_attr_enable.attr,
535 &dev_attr_reset.attr,
536 NULL,
537};
538
539static const struct attribute_group cdx_bus_dev_group = {
540 .attrs = cdx_bus_dev_attrs,
541 .is_visible = cdx_bus_attrs_are_visible,
542};
543
544static const struct attribute_group *cdx_dev_groups[] = {
545 &cdx_dev_group,
546 &cdx_bus_dev_group,
547 NULL,
548};
549
550static int cdx_debug_resource_show(struct seq_file *s, void *data)
551{
552 struct cdx_device *cdx_dev = s->private;
553 int i;
554
555 for (i = 0; i < MAX_CDX_DEV_RESOURCES; i++) {
556 struct resource *res = &cdx_dev->res[i];
557
558 seq_printf(s, "%pr\n", res);
559 }
560
561 return 0;
562}
563DEFINE_SHOW_ATTRIBUTE(cdx_debug_resource);
564
565static void cdx_device_debugfs_init(struct cdx_device *cdx_dev)
566{
567 cdx_dev->debugfs_dir = debugfs_create_dir(dev_name(&cdx_dev->dev), cdx_debugfs_dir);
568 if (IS_ERR(cdx_dev->debugfs_dir))
569 return;
570
571 debugfs_create_file("resource", 0444, cdx_dev->debugfs_dir, cdx_dev,
572 &cdx_debug_resource_fops);
573}
574
575static ssize_t rescan_store(const struct bus_type *bus,
576 const char *buf, size_t count)
577{
578 struct cdx_controller *cdx;
579 struct platform_device *pd;
580 bool val;
581
582 if (kstrtobool(buf, &val) < 0)
583 return -EINVAL;
584
585 if (!val)
586 return -EINVAL;
587
588 guard(mutex)(&cdx_controller_lock);
589
590 /* Unregister all the devices on the bus */
591 cdx_unregister_devices(&cdx_bus_type);
592
593 /* Rescan all the devices */
594 for_each_compatible_node_scoped(np, NULL, compat_node_name) {
595 pd = of_find_device_by_node(np);
596 if (!pd)
597 return -EINVAL;
598
599 cdx = platform_get_drvdata(pd);
600 if (cdx && cdx->controller_registered && cdx->ops->scan)
601 cdx->ops->scan(cdx);
602
603 put_device(&pd->dev);
604 }
605
606 return count;
607}
608static BUS_ATTR_WO(rescan);
609
610static struct attribute *cdx_bus_attrs[] = {
611 &bus_attr_rescan.attr,
612 NULL,
613};
614ATTRIBUTE_GROUPS(cdx_bus);
615
616const struct bus_type cdx_bus_type = {
617 .name = "cdx",
618 .driver_override = true,
619 .match = cdx_bus_match,
620 .probe = cdx_probe,
621 .remove = cdx_remove,
622 .shutdown = cdx_shutdown,
623 .dma_configure = cdx_dma_configure,
624 .dma_cleanup = cdx_dma_cleanup,
625 .bus_groups = cdx_bus_groups,
626 .dev_groups = cdx_dev_groups,
627};
628EXPORT_SYMBOL_GPL(cdx_bus_type);
629
630int __cdx_driver_register(struct cdx_driver *cdx_driver,
631 struct module *owner)
632{
633 int error;
634
635 cdx_driver->driver.owner = owner;
636 cdx_driver->driver.bus = &cdx_bus_type;
637
638 error = driver_register(&cdx_driver->driver);
639 if (error) {
640 pr_err("driver_register() failed for %s: %d\n",
641 cdx_driver->driver.name, error);
642 return error;
643 }
644
645 return 0;
646}
647EXPORT_SYMBOL_GPL(__cdx_driver_register);
648
649void cdx_driver_unregister(struct cdx_driver *cdx_driver)
650{
651 driver_unregister(&cdx_driver->driver);
652}
653EXPORT_SYMBOL_GPL(cdx_driver_unregister);
654
655static void cdx_device_release(struct device *dev)
656{
657 struct cdx_device *cdx_dev = to_cdx_device(dev);
658
659 kfree(cdx_dev);
660}
661
662static const struct vm_operations_struct cdx_phys_vm_ops = {
663#ifdef CONFIG_HAVE_IOREMAP_PROT
664 .access = generic_access_phys,
665#endif
666};
667
668/**
669 * cdx_mmap_resource - map a CDX resource into user memory space
670 * @fp: File pointer. Not used in this function, but required where
671 * this API is registered as a callback.
672 * @kobj: kobject for mapping
673 * @attr: struct bin_attribute for the file being mapped
674 * @vma: struct vm_area_struct passed into the mmap
675 *
676 * Use the regular CDX mapping routines to map a CDX resource into userspace.
677 *
678 * Return: true on success, false otherwise.
679 */
680static int cdx_mmap_resource(struct file *fp, struct kobject *kobj,
681 const struct bin_attribute *attr,
682 struct vm_area_struct *vma)
683{
684 struct cdx_device *cdx_dev = to_cdx_device(kobj_to_dev(kobj));
685 int num = (unsigned long)attr->private;
686 struct resource *res;
687 unsigned long size;
688
689 res = &cdx_dev->res[num];
690 if (iomem_is_exclusive(res->start))
691 return -EINVAL;
692
693 /* Make sure the caller is mapping a valid resource for this device */
694 size = ((cdx_resource_len(cdx_dev, num) - 1) >> PAGE_SHIFT) + 1;
695 if (vma->vm_pgoff + vma_pages(vma) > size)
696 return -EINVAL;
697
698 /*
699 * Map memory region and vm->vm_pgoff is expected to be an
700 * offset within that region.
701 */
702 vma->vm_page_prot = pgprot_device(vma->vm_page_prot);
703 vma->vm_pgoff += (cdx_resource_start(cdx_dev, num) >> PAGE_SHIFT);
704 vma->vm_ops = &cdx_phys_vm_ops;
705 return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
706 vma->vm_end - vma->vm_start,
707 vma->vm_page_prot);
708}
709
710static void cdx_destroy_res_attr(struct cdx_device *cdx_dev, int num)
711{
712 int i;
713
714 /* removing the bin attributes */
715 for (i = 0; i < num; i++) {
716 struct bin_attribute *res_attr;
717
718 res_attr = cdx_dev->res_attr[i];
719 if (res_attr) {
720 sysfs_remove_bin_file(&cdx_dev->dev.kobj, res_attr);
721 kfree(res_attr);
722 }
723 }
724}
725
726#define CDX_RES_ATTR_NAME_LEN 10
727static int cdx_create_res_attr(struct cdx_device *cdx_dev, int num)
728{
729 struct bin_attribute *res_attr;
730 char *res_attr_name;
731 int ret;
732
733 res_attr = kzalloc(sizeof(*res_attr) + CDX_RES_ATTR_NAME_LEN, GFP_ATOMIC);
734 if (!res_attr)
735 return -ENOMEM;
736
737 res_attr_name = (char *)(res_attr + 1);
738
739 sysfs_bin_attr_init(res_attr);
740
741 sprintf(res_attr_name, "resource%d", num);
742
743 res_attr->mmap = cdx_mmap_resource;
744 res_attr->attr.name = res_attr_name;
745 res_attr->attr.mode = 0600;
746 res_attr->size = cdx_resource_len(cdx_dev, num);
747 res_attr->private = (void *)(unsigned long)num;
748 ret = sysfs_create_bin_file(&cdx_dev->dev.kobj, res_attr);
749 if (ret) {
750 kfree(res_attr);
751 return ret;
752 }
753
754 cdx_dev->res_attr[num] = res_attr;
755
756 return ret;
757}
758
759int cdx_device_add(struct cdx_dev_params *dev_params)
760{
761 struct cdx_controller *cdx = dev_params->cdx;
762 struct cdx_device *cdx_dev;
763 int ret, i;
764
765 cdx_dev = kzalloc_obj(*cdx_dev);
766 if (!cdx_dev)
767 return -ENOMEM;
768
769 /* Populate resource */
770 memcpy(cdx_dev->res, dev_params->res, sizeof(struct resource) *
771 dev_params->res_count);
772 cdx_dev->res_count = dev_params->res_count;
773
774 /* Populate CDX dev params */
775 cdx_dev->req_id = dev_params->req_id;
776 cdx_dev->msi_dev_id = dev_params->msi_dev_id;
777 cdx_dev->vendor = dev_params->vendor;
778 cdx_dev->device = dev_params->device;
779 cdx_dev->subsystem_vendor = dev_params->subsys_vendor;
780 cdx_dev->subsystem_device = dev_params->subsys_device;
781 cdx_dev->class = dev_params->class;
782 cdx_dev->revision = dev_params->revision;
783 cdx_dev->bus_num = dev_params->bus_num;
784 cdx_dev->dev_num = dev_params->dev_num;
785 cdx_dev->cdx = dev_params->cdx;
786 cdx_dev->dma_mask = CDX_DEFAULT_DMA_MASK;
787
788 /* Initialize generic device */
789 device_initialize(&cdx_dev->dev);
790 cdx_dev->dev.parent = dev_params->parent;
791 cdx_dev->dev.bus = &cdx_bus_type;
792 cdx_dev->dev.dma_mask = &cdx_dev->dma_mask;
793 cdx_dev->dev.release = cdx_device_release;
794 cdx_dev->msi_write_pending = false;
795 mutex_init(&cdx_dev->irqchip_lock);
796
797 /* Set Name */
798 dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x",
799 ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (cdx_dev->bus_num & CDX_BUS_NUM_MASK)),
800 cdx_dev->dev_num);
801
802 if (IS_ENABLED(CONFIG_GENERIC_MSI_IRQ) && cdx->msi_domain) {
803 cdx_dev->num_msi = dev_params->num_msi;
804 dev_set_msi_domain(&cdx_dev->dev, cdx->msi_domain);
805 }
806
807 ret = device_add(&cdx_dev->dev);
808 if (ret) {
809 dev_err(&cdx_dev->dev,
810 "cdx device add failed: %d", ret);
811 goto fail;
812 }
813
814 /* Create resource<N> attributes */
815 for (i = 0; i < MAX_CDX_DEV_RESOURCES; i++) {
816 if (cdx_resource_flags(cdx_dev, i) & IORESOURCE_MEM) {
817 /* skip empty resources */
818 if (!cdx_resource_len(cdx_dev, i))
819 continue;
820
821 ret = cdx_create_res_attr(cdx_dev, i);
822 if (ret != 0) {
823 dev_err(&cdx_dev->dev,
824 "cdx device resource<%d> file creation failed: %d", i, ret);
825 goto resource_create_fail;
826 }
827 }
828 }
829
830 cdx_device_debugfs_init(cdx_dev);
831
832 return 0;
833resource_create_fail:
834 cdx_destroy_res_attr(cdx_dev, i);
835 device_del(&cdx_dev->dev);
836fail:
837 /*
838 * Do not free cdx_dev here as it would be freed in
839 * cdx_device_release() called from put_device().
840 */
841 put_device(&cdx_dev->dev);
842
843 return ret;
844}
845EXPORT_SYMBOL_NS_GPL(cdx_device_add, "CDX_BUS_CONTROLLER");
846
847struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num)
848{
849 struct cdx_device *cdx_dev;
850 int ret;
851
852 cdx_dev = kzalloc_obj(*cdx_dev);
853 if (!cdx_dev)
854 return NULL;
855
856 device_initialize(&cdx_dev->dev);
857 cdx_dev->cdx = cdx;
858
859 cdx_dev->dev.parent = cdx->dev;
860 cdx_dev->dev.bus = &cdx_bus_type;
861 cdx_dev->dev.release = cdx_device_release;
862 cdx_dev->is_bus = true;
863 cdx_dev->bus_num = bus_num;
864
865 dev_set_name(&cdx_dev->dev, "cdx-%02x",
866 ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (bus_num & CDX_BUS_NUM_MASK)));
867
868 ret = device_add(&cdx_dev->dev);
869 if (ret) {
870 dev_err(&cdx_dev->dev, "cdx bus device add failed: %d\n", ret);
871 goto device_add_fail;
872 }
873
874 if (cdx->ops->bus_enable) {
875 ret = cdx->ops->bus_enable(cdx, bus_num);
876 if (ret && ret != -EALREADY) {
877 dev_err(cdx->dev, "cdx bus enable failed: %d\n", ret);
878 goto bus_enable_fail;
879 }
880 }
881
882 cdx_dev->enabled = true;
883 return &cdx_dev->dev;
884
885bus_enable_fail:
886 device_del(&cdx_dev->dev);
887device_add_fail:
888 put_device(&cdx_dev->dev);
889
890 return NULL;
891}
892EXPORT_SYMBOL_NS_GPL(cdx_bus_add, "CDX_BUS_CONTROLLER");
893
894int cdx_register_controller(struct cdx_controller *cdx)
895{
896 int ret;
897
898 ret = ida_alloc_range(&cdx_controller_ida, 0, MAX_CDX_CONTROLLERS - 1, GFP_KERNEL);
899 if (ret < 0) {
900 dev_err(cdx->dev,
901 "No free index available. Maximum controllers already registered\n");
902 cdx->id = (u8)MAX_CDX_CONTROLLERS;
903 return ret;
904 }
905
906 mutex_lock(&cdx_controller_lock);
907 cdx->id = ret;
908
909 /* Scan all the devices */
910 if (cdx->ops->scan)
911 cdx->ops->scan(cdx);
912 cdx->controller_registered = true;
913 mutex_unlock(&cdx_controller_lock);
914
915 return 0;
916}
917EXPORT_SYMBOL_NS_GPL(cdx_register_controller, "CDX_BUS_CONTROLLER");
918
919void cdx_unregister_controller(struct cdx_controller *cdx)
920{
921 if (cdx->id >= MAX_CDX_CONTROLLERS)
922 return;
923
924 mutex_lock(&cdx_controller_lock);
925
926 cdx->controller_registered = false;
927 device_for_each_child(cdx->dev, NULL, cdx_unregister_device);
928 ida_free(&cdx_controller_ida, cdx->id);
929
930 mutex_unlock(&cdx_controller_lock);
931}
932EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, "CDX_BUS_CONTROLLER");
933
934static int __init cdx_bus_init(void)
935{
936 int ret;
937
938 ret = bus_register(&cdx_bus_type);
939 if (!ret)
940 cdx_debugfs_dir = debugfs_create_dir(cdx_bus_type.name, NULL);
941
942 return ret;
943}
944postcore_initcall(cdx_bus_init);