new file mode 100644
@@ -0,0 +1,34 @@
+What: /sys/devices/platform/cdxbus/rescan
+Date: August 2022
+Contact: puneet.gupta@amd.com
+Description:
+ Writing 1 to this would cause rescan of the bus
+ and devices on the CDX bus. Any new devices would
+ be scanned and added to the list of linux devices
+ and any devices removed are also deleted from linux.
+
+ For example::
+
+ # echo 1 > /sys/devices/platform/cdxbus/rescan
+
+What: /sys/devices/platform/cdxbus/reset_all
+Date: August 2022
+Contact: puneet.gupta@amd.com
+Description:
+ Writing 1 to this would reset all the devices present
+ on the CDX bus
+
+ For example::
+
+ # echo 1 > /sys/devices/platform/cdxbus/reset_all
+
+What: /sys/devices/platform/cdxbus/<device>/reset
+Date: August 2022
+Contact: puneet.gupta@amd.com
+Description:
+ Writing 1 to this would reset the specific device
+ for which the reset is set.
+
+ For example::
+
+ # echo 1 > /sys/devices/platform/cdxbus/.../reset
@@ -25,10 +25,57 @@ static struct cdx_device_types_t dev_types[MAX_CDX_DEVICE_TYPES] = {
{"cdx-cdma-1.0", "xlnx,cdx-cdma-1.0"}
};
+static int reset_cdx_device(struct device *dev, void * __always_unused data)
+{
+ struct platform_device *cdx_bus_pdev = to_platform_device(dev->parent);
+ struct cdx_device_data *dev_data = dev->platform_data;
+
+ /* TODO: Call reset from firmware using dev_data->bus_id and
+ * dev_data->dev_id.
+ */
+ return 0;
+}
+
+static ssize_t reset_all_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ bool reset = count > 0 && *buf != '0';
+
+ if (!reset)
+ return count;
+
+ /* Reset all the devices attached to cdx bus */
+ ret = device_for_each_child(dev, NULL, reset_cdx_device);
+ if (ret)
+ return ret;
+
+ return count;
+}
+static DEVICE_ATTR_WO(reset_all);
+
+static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ bool reset = count > 0 && *buf != '0';
+
+ if (!reset)
+ return count;
+
+ ret = reset_cdx_device(dev, NULL);
+ if (ret)
+ return ret;
+
+ return count;
+}
+static DEVICE_ATTR_WO(reset);
+
static int cdx_populate_one(struct platform_device *pdev_parent,
- struct cdx_dev_params_t *dev_params)
+ struct cdx_dev_params_t *dev_params)
{
- struct platform_device *new_pdev;
+ struct platform_device *new_pdev = NULL;
struct fwnode_handle *swnode;
struct platform_device_info pdevinfo;
struct cdx_device_data dev_data;
@@ -84,6 +131,9 @@ static int cdx_populate_one(struct platform_device *pdev_parent,
dev_set_msi_domain(&new_pdev->dev,
irq_find_host(pdev_parent->dev.of_node));
+ /* Creating reset entry */
+ device_create_file(&new_pdev->dev, &dev_attr_reset);
+
return 0;
out:
@@ -101,6 +151,7 @@ static int cdx_unregister_device(struct device *dev,
{
struct platform_device *pdev = to_platform_device(dev);
+ device_remove_file(dev, &dev_attr_reset);
platform_device_unregister(pdev);
fwnode_remove_software_node(pdev->dev.fwnode);
@@ -215,6 +266,28 @@ static int cdx_bus_device_discovery(struct platform_device *pdev)
return ret;
}
+static ssize_t rescan_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ struct platform_device *pdev = to_platform_device(dev);
+ bool rescan = count > 0 && *buf != '0';
+
+ if (!rescan)
+ return count;
+
+ /* Unregister all the devices */
+ cdx_unregister_devices(dev);
+
+ /* do the device discovery again */
+ ret = cdx_bus_device_discovery(pdev);
+ if (ret)
+ return ret;
+
+ return count;
+}
+static DEVICE_ATTR_WO(rescan);
+
static int cdx_probe(struct platform_device *pdev)
{
int ret;
@@ -225,6 +298,10 @@ static int cdx_probe(struct platform_device *pdev)
if (ret)
return ret;
+ /* Creating reset_all entry */
+ device_create_file(&pdev->dev, &dev_attr_reset_all);
+ device_create_file(&pdev->dev, &dev_attr_rescan);
+
return 0;
}