diff --git a/Documentation/ABI/testing/sysfs-bus-cdx b/Documentation/ABI/testing/sysfs-bus-cdx
new file mode 100644
index 000000000000..5f84f0a93a66
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-cdx
@@ -0,0 +1,54 @@
+What:		/sys/bus/cdx/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/bus/cdx/rescan
+
+What:		/sys/bus/cdx/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/bus/cdx/reset_all
+
+What:		/sys/bus/cdx/devices/.../vendor
+Date:		August 2022
+Contact:	nipun.gupta@amd.com
+Description:
+		Vendor ID for this CDX device
+
+What:		/sys/bus/cdx/devices/.../device
+Date:		August 2022
+Contact:	nipun.gupta@amd.com
+Description:
+		Device ID for this CDX device
+
+What:		/sys/bus/cdx/devices/.../reset
+What:		/sys/bus/cdx/devices/.../reset
+Date:		August 2022
+Contact:	nipun.gupta@amd.com
+Description:
+		Writing 1 to this would reset the CDX device
+
+                For example::
+
+		  # echo 1 > /sys/bus/cdx/.../reset
+
+What:		/sys/bus/cdx/devices/.../modalias
+Date:		August 2022
+Contact:	nipun.gupta@amd.com
+Description:
+		A CDX device has modalias:
+
+			- v`vendor`d`device`
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index 02ececce1c84..9b7a69de6a8f 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -32,6 +32,23 @@ struct platform_device *cdx_controller_pdev;
 
 static int cdx_bus_device_discovery(struct platform_device *pdev);
 
+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 *cdx_dev = to_cdx_device(dev);
+	struct cdx_mcdi_t *cdx_mcdi = platform_get_drvdata(cdx_bus_pdev);
+
+	/* MCDI FW: reset particular device represented by bus:func */
+	cdx_mcdi_func_reset(cdx_mcdi, cdx_dev->bus_id, cdx_dev->func_id);
+
+	return 0;
+}
+
+int cdx_dev_reset(struct device *dev)
+{
+	return reset_cdx_device(dev, NULL);
+}
+
 static int cdx_unregister_device(struct device *dev,
 				 void * __always_unused data)
 {
@@ -139,10 +156,141 @@ static int cdx_dma_configure(struct device *dev)
 	return 0;
 }
 
+static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct cdx_device *cdx_dev = to_cdx_device(dev);
+
+	return sprintf(buf, "0x%x\n", cdx_dev->vendor);
+}
+static DEVICE_ATTR_RO(vendor);
+
+static ssize_t device_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct cdx_device *cdx_dev = to_cdx_device(dev);
+
+	return sprintf(buf, "0x%x\n", cdx_dev->device);
+}
+static DEVICE_ATTR_RO(device);
+
+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 ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct cdx_device *cdx_dev = to_cdx_device(dev);
+
+	return sprintf(buf, "cdx:v%08Xd%d\n", cdx_dev->vendor,
+			cdx_dev->device);
+}
+static DEVICE_ATTR_RO(modalias);
+
+static ssize_t driver_override_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct cdx_device *cdx_dev = to_cdx_device(dev);
+	int ret;
+
+	if (WARN_ON(dev->bus != &cdx_bus_type))
+		return -EINVAL;
+
+	ret = driver_set_override(dev, &cdx_dev->driver_override, buf, count);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static ssize_t driver_override_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct cdx_device *cdx_dev = to_cdx_device(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", cdx_dev->driver_override);
+}
+static DEVICE_ATTR_RW(driver_override);
+
+static struct attribute *cdx_dev_attrs[] = {
+	&dev_attr_reset.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_device.attr,
+	&dev_attr_modalias.attr,
+	&dev_attr_driver_override.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(cdx_dev);
+
+static ssize_t rescan_store(struct bus_type *bus,
+			    const char *buf, size_t count)
+{
+	bool rescan = count > 0 && *buf != '0';
+	int ret = 0;
+
+	if (!rescan)
+		return count;
+
+	/* Unregister all the devices on the bus */
+	cdx_unregister_devices(&cdx_bus_type);
+
+	/* Rescan all the devices */
+	ret = cdx_bus_device_discovery(cdx_controller_pdev);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static BUS_ATTR_WO(rescan);
+
+static ssize_t reset_all_store(struct bus_type *bus,
+			       const char *buf, size_t count)
+{
+	bool reset = count > 0 && *buf != '0';
+	int ret = 0;
+
+	if (!reset)
+		return count;
+
+	/* Reset all the devices attached to cdx bus */
+	ret = bus_for_each_dev(bus, NULL, NULL, reset_cdx_device);
+	if (ret) {
+		pr_err("error in CDX bus reset\n");
+		return 0;
+	}
+
+	return count;
+}
+static BUS_ATTR_WO(reset_all);
+
+static struct attribute *cdx_bus_attrs[] = {
+	&bus_attr_rescan.attr,
+	&bus_attr_reset_all.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(cdx_bus);
+
 struct bus_type cdx_bus_type = {
 	.name = "cdx",
 	.match = cdx_bus_match,
 	.dma_configure  = cdx_dma_configure,
+	.dev_groups = cdx_dev_groups,
+	.bus_groups = cdx_bus_groups,
 };
 EXPORT_SYMBOL_GPL(cdx_bus_type);
 
diff --git a/drivers/bus/cdx/mcdi_stubs.c b/drivers/bus/cdx/mcdi_stubs.c
index 2c8db1f5a057..2bc042d2b061 100644
--- a/drivers/bus/cdx/mcdi_stubs.c
+++ b/drivers/bus/cdx/mcdi_stubs.c
@@ -53,3 +53,9 @@ int cdx_mcdi_get_func_config(struct cdx_mcdi_t *cdx_mcdi,
 
 	return 0;
 }
+
+int cdx_mcdi_func_reset(struct cdx_mcdi_t *cdx_mcdi,
+			uint8_t bus_id, uint8_t func_id)
+{
+	return 0;
+}
diff --git a/drivers/bus/cdx/mcdi_stubs.h b/drivers/bus/cdx/mcdi_stubs.h
index 7b6f79d48ce9..535218bcdce0 100644
--- a/drivers/bus/cdx/mcdi_stubs.h
+++ b/drivers/bus/cdx/mcdi_stubs.h
@@ -73,4 +73,15 @@ int cdx_mcdi_get_func_config(struct cdx_mcdi_t *cdx_mcdi,
 			     uint8_t bus_id, uint8_t func_id,
 			     struct cdx_dev_params_t *dev_params);
 
+/**
+ * cdx_mcdi_func_reset - Reset cdx device represented by bus_id:func_id
+ * @cdx_mcdi: pointer to MCDI interface.
+ * @bus_num: Bus number.
+ * @func_id: Function number.
+ *
+ * Return 0 on success, <0 on failure
+ */
+int cdx_mcdi_func_reset(struct cdx_mcdi_t *cdx_mcdi,
+			uint8_t bus_id, uint8_t func_id);
+
 #endif /* _MCDI_STUBS_H_ */
diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h
index bf86024783d2..8306b4d3fd82 100644
--- a/include/linux/cdx/cdx_bus.h
+++ b/include/linux/cdx/cdx_bus.h
@@ -109,4 +109,12 @@ int cdx_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count);
  */
 void cdx_msi_domain_free_irqs(struct device *dev);
 
+/**
+ * cdx_dev_reset - Reset CDX device
+ * @dev: device pointer
+ *
+ * Return 0 for success, -errno on failure
+ */
+int cdx_dev_reset(struct device *dev);
+
 #endif /* _CDX_BUS_H_ */
