Skip to content

Commit ce558a3

Browse files
abhijitG-xlnxgregkh
authored andcommitted
cdx: Register cdx bus as a device on cdx subsystem
While scanning for CDX devices, register newly discovered bus as a cdx device. CDX device attributes are visible based on device type. Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com> Link: https://lore.kernel.org/r/20231017160505.10640-5-abhijit.gangurde@amd.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e3ed12f commit ce558a3

File tree

4 files changed

+93
-7
lines changed

4 files changed

+93
-7
lines changed

drivers/cdx/cdx.c

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,13 @@ static int cdx_unregister_device(struct device *dev,
125125
{
126126
struct cdx_device *cdx_dev = to_cdx_device(dev);
127127

128-
kfree(cdx_dev->driver_override);
129-
cdx_dev->driver_override = NULL;
128+
if (cdx_dev->is_bus) {
129+
device_for_each_child(dev, NULL, cdx_unregister_device);
130+
} else {
131+
kfree(cdx_dev->driver_override);
132+
cdx_dev->driver_override = NULL;
133+
}
134+
130135
/*
131136
* Do not free cdx_dev here as it would be freed in
132137
* cdx_device_release() called from within put_device().
@@ -201,6 +206,9 @@ static int cdx_bus_match(struct device *dev, struct device_driver *drv)
201206
const struct cdx_device_id *found_id = NULL;
202207
const struct cdx_device_id *ids;
203208

209+
if (cdx_dev->is_bus)
210+
return false;
211+
204212
ids = cdx_drv->match_id_table;
205213

206214
/* When driver_override is set, only bind to the matching driver */
@@ -265,10 +273,11 @@ static int cdx_dma_configure(struct device *dev)
265273
{
266274
struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
267275
struct cdx_device *cdx_dev = to_cdx_device(dev);
276+
struct cdx_controller *cdx = cdx_dev->cdx;
268277
u32 input_id = cdx_dev->req_id;
269278
int ret;
270279

271-
ret = of_dma_configure_id(dev, dev->parent->of_node, 0, &input_id);
280+
ret = of_dma_configure_id(dev, cdx->dev->of_node, 0, &input_id);
272281
if (ret && ret != -EPROBE_DEFER) {
273282
dev_err(dev, "of_dma_configure_id() failed\n");
274283
return ret;
@@ -374,6 +383,18 @@ static ssize_t driver_override_show(struct device *dev,
374383
}
375384
static DEVICE_ATTR_RW(driver_override);
376385

386+
static umode_t cdx_dev_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)
387+
{
388+
struct device *dev = kobj_to_dev(kobj);
389+
struct cdx_device *cdx_dev;
390+
391+
cdx_dev = to_cdx_device(dev);
392+
if (!cdx_dev->is_bus)
393+
return a->mode;
394+
395+
return 0;
396+
}
397+
377398
static struct attribute *cdx_dev_attrs[] = {
378399
&dev_attr_remove.attr,
379400
&dev_attr_reset.attr,
@@ -382,7 +403,16 @@ static struct attribute *cdx_dev_attrs[] = {
382403
&dev_attr_driver_override.attr,
383404
NULL,
384405
};
385-
ATTRIBUTE_GROUPS(cdx_dev);
406+
407+
static const struct attribute_group cdx_dev_group = {
408+
.attrs = cdx_dev_attrs,
409+
.is_visible = cdx_dev_attrs_are_visible,
410+
};
411+
412+
static const struct attribute_group *cdx_dev_groups[] = {
413+
&cdx_dev_group,
414+
NULL,
415+
};
386416

387417
static ssize_t rescan_store(const struct bus_type *bus,
388418
const char *buf, size_t count)
@@ -479,7 +509,6 @@ static void cdx_device_release(struct device *dev)
479509
int cdx_device_add(struct cdx_dev_params *dev_params)
480510
{
481511
struct cdx_controller *cdx = dev_params->cdx;
482-
struct device *parent = cdx->dev;
483512
struct cdx_device *cdx_dev;
484513
int ret;
485514

@@ -503,7 +532,7 @@ int cdx_device_add(struct cdx_dev_params *dev_params)
503532

504533
/* Initialize generic device */
505534
device_initialize(&cdx_dev->dev);
506-
cdx_dev->dev.parent = parent;
535+
cdx_dev->dev.parent = dev_params->parent;
507536
cdx_dev->dev.bus = &cdx_bus_type;
508537
cdx_dev->dev.dma_mask = &cdx_dev->dma_mask;
509538
cdx_dev->dev.release = cdx_device_release;
@@ -532,6 +561,42 @@ int cdx_device_add(struct cdx_dev_params *dev_params)
532561
}
533562
EXPORT_SYMBOL_NS_GPL(cdx_device_add, CDX_BUS_CONTROLLER);
534563

564+
struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num)
565+
{
566+
struct cdx_device *cdx_dev;
567+
int ret;
568+
569+
cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL);
570+
if (!cdx_dev)
571+
return NULL;
572+
573+
device_initialize(&cdx_dev->dev);
574+
cdx_dev->cdx = cdx;
575+
576+
cdx_dev->dev.parent = cdx->dev;
577+
cdx_dev->dev.bus = &cdx_bus_type;
578+
cdx_dev->dev.release = cdx_device_release;
579+
cdx_dev->is_bus = true;
580+
cdx_dev->bus_num = bus_num;
581+
582+
dev_set_name(&cdx_dev->dev, "cdx-%02x",
583+
((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (bus_num & CDX_BUS_NUM_MASK)));
584+
585+
ret = device_add(&cdx_dev->dev);
586+
if (ret) {
587+
dev_err(&cdx_dev->dev, "cdx bus device add failed: %d\n", ret);
588+
goto device_add_fail;
589+
}
590+
591+
return &cdx_dev->dev;
592+
593+
device_add_fail:
594+
put_device(&cdx_dev->dev);
595+
596+
return NULL;
597+
}
598+
EXPORT_SYMBOL_NS_GPL(cdx_bus_add, CDX_BUS_CONTROLLER);
599+
535600
int cdx_register_controller(struct cdx_controller *cdx)
536601
{
537602
int ret;

drivers/cdx/cdx.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
/**
1414
* struct cdx_dev_params - CDX device parameters
1515
* @cdx: CDX controller associated with the device
16-
* @parent: Associated CDX controller
16+
* @parent: Associated CDX Bus device
1717
* @vendor: Vendor ID for CDX device
1818
* @device: Device ID for CDX device
1919
* @bus_num: Bus number for this CDX device
@@ -24,6 +24,7 @@
2424
*/
2525
struct cdx_dev_params {
2626
struct cdx_controller *cdx;
27+
struct device *parent;
2728
u16 vendor;
2829
u16 device;
2930
u8 bus_num;
@@ -59,4 +60,15 @@ void cdx_unregister_controller(struct cdx_controller *cdx);
5960
*/
6061
int cdx_device_add(struct cdx_dev_params *dev_params);
6162

63+
/**
64+
* cdx_bus_add - Add a CDX bus. This function adds a bus on the CDX bus
65+
* subsystem. It creates a CDX device for the corresponding bus and
66+
* also registers an associated Linux generic device.
67+
* @cdx: Associated CDX controller
68+
* @us_num: Bus number
69+
*
70+
* Return: associated Linux generic device pointer on success or NULL on failure.
71+
*/
72+
struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num);
73+
6274
#endif /* _CDX_H_ */

drivers/cdx/controller/cdx_controller.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,14 @@ static int cdx_scan_devices(struct cdx_controller *cdx)
7979
num_cdx_bus = (u8)ret;
8080

8181
for (bus_num = 0; bus_num < num_cdx_bus; bus_num++) {
82+
struct device *bus_dev;
8283
u8 num_cdx_dev;
8384

85+
/* Add the bus on cdx subsystem */
86+
bus_dev = cdx_bus_add(cdx, bus_num);
87+
if (!bus_dev)
88+
continue;
89+
8490
/* MCDI FW Read: Fetch the number of devices present */
8591
ret = cdx_mcdi_get_num_devs(cdx_mcdi, bus_num);
8692
if (ret < 0) {
@@ -103,6 +109,7 @@ static int cdx_scan_devices(struct cdx_controller *cdx)
103109
continue;
104110
}
105111
dev_params.cdx = cdx;
112+
dev_params.parent = bus_dev;
106113

107114
/* Add the device to the cdx bus */
108115
ret = cdx_device_add(&dev_params);

include/linux/cdx/cdx_bus.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct cdx_controller {
8888
* @dma_mask: Default DMA mask
8989
* @flags: CDX device flags
9090
* @req_id: Requestor ID associated with CDX device
91+
* @is_bus: Is this bus device
9192
* @driver_override: driver name to force a match; do not set directly,
9293
* because core frees it; use driver_set_override() to
9394
* set or clear it.
@@ -104,6 +105,7 @@ struct cdx_device {
104105
u64 dma_mask;
105106
u16 flags;
106107
u32 req_id;
108+
bool is_bus;
107109
const char *driver_override;
108110
};
109111

0 commit comments

Comments
 (0)