of a device manufacturer.
                Combination of Vendor ID and Device ID identifies a device.
 
+What:          /sys/bus/cdx/devices/.../subsystem_vendor
+Date:          July 2023
+Contact:       puneet.gupta@amd.com
+Description:
+               Subsystem Vendor ID for this CDX device, in hexadecimal.
+               Subsystem Vendor ID is 16 bit identifier specific to the
+               card manufacturer.
+
+What:          /sys/bus/cdx/devices/.../subsystem_device
+Date:          July 2023
+Contact:       puneet.gupta@amd.com
+Description:
+               Subsystem Device ID for this CDX device, in hexadecimal
+               Subsystem Device ID is 16 bit identifier specific to the
+               card manufacturer.
+
+What:          /sys/bus/cdx/devices/.../class
+Date:          July 2023
+Contact:       puneet.gupta@amd.com
+Description:
+               This file contains the class of the CDX device, in hexadecimal.
+               Class is 24 bit identifier specifies the functionality of the device.
+
+What:          /sys/bus/cdx/devices/.../revision
+Date:          July 2023
+Contact:       puneet.gupta@amd.com
+Description:
+               This file contains the revision field of the CDX device, in hexadecimal.
+               Revision is 8 bit revision identifier of the device.
+
 What:          /sys/bus/cdx/devices/.../enable
 Date:          October 2023
 Contact:       abhijit.gangurde@amd.com
                For example::
 
                  # echo 1 > /sys/bus/cdx/devices/.../remove
+
+What:          /sys/bus/cdx/devices/.../modalias
+Date:          July 2023
+Contact:       nipun.gupta@amd.com
+Description:
+               This attribute indicates the CDX ID of the device.
+               That is in the format:
+               cdx:vXXXXdXXXXsvXXXXsdXXXXcXXXXXX,
+               where:
+
+                   - vXXXX contains the vendor ID;
+                   - dXXXX contains the device ID;
+                   - svXXXX contains the subsystem vendor ID;
+                   - sdXXXX contains the subsystem device ID;
+                   - cXXXXXX contains the device class.
 
 {
        /* Use vendor ID and device ID for matching */
        if ((id->vendor == CDX_ANY_ID || id->vendor == dev->vendor) &&
-           (id->device == CDX_ANY_ID || id->device == dev->device))
+           (id->device == CDX_ANY_ID || id->device == dev->device) &&
+           (id->subvendor == CDX_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
+           (id->subdevice == CDX_ANY_ID || id->subdevice == dev->subsystem_device) &&
+           !((id->class ^ dev->class) & id->class_mask))
                return id;
        return NULL;
 }
 
 cdx_config_attr(vendor, "0x%04x\n");
 cdx_config_attr(device, "0x%04x\n");
+cdx_config_attr(subsystem_vendor, "0x%04x\n");
+cdx_config_attr(subsystem_device, "0x%04x\n");
+cdx_config_attr(revision, "0x%02x\n");
+cdx_config_attr(class, "0x%06x\n");
 
 static ssize_t remove_store(struct device *dev,
                            struct device_attribute *attr,
 }
 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%04Xd%04Xsv%04Xsd%04Xc%06X\n", cdx_dev->vendor,
+                       cdx_dev->device, cdx_dev->subsystem_vendor, cdx_dev->subsystem_device,
+                       cdx_dev->class);
+}
+static DEVICE_ATTR_RO(modalias);
+
 static ssize_t driver_override_store(struct device *dev,
                                     struct device_attribute *attr,
                                     const char *buf, size_t count)
        &dev_attr_reset.attr,
        &dev_attr_vendor.attr,
        &dev_attr_device.attr,
+       &dev_attr_subsystem_vendor.attr,
+       &dev_attr_subsystem_device.attr,
+       &dev_attr_class.attr,
+       &dev_attr_revision.attr,
+       &dev_attr_modalias.attr,
        &dev_attr_driver_override.attr,
        NULL,
 };
        cdx_dev->req_id = dev_params->req_id;
        cdx_dev->vendor = dev_params->vendor;
        cdx_dev->device = dev_params->device;
+       cdx_dev->subsystem_vendor = dev_params->subsys_vendor;
+       cdx_dev->subsystem_device = dev_params->subsys_device;
+       cdx_dev->class = dev_params->class;
+       cdx_dev->revision = dev_params->revision;
        cdx_dev->bus_num = dev_params->bus_num;
        cdx_dev->dev_num = dev_params->dev_num;
        cdx_dev->cdx = dev_params->cdx;
 
  * @parent: Associated CDX Bus device
  * @vendor: Vendor ID for CDX device
  * @device: Device ID for CDX device
+ * @subsys_vendor: Sub vendor ID for CDX device
+ * @subsys_device: Sub device ID for CDX device
  * @bus_num: Bus number for this CDX device
  * @dev_num: Device number for this device
  * @res: array of MMIO region entries
  * @res_count: number of valid MMIO regions
  * @req_id: Requestor ID associated with CDX device
+ * @class: Class of the CDX Device
+ * @revision: Revision of the CDX device
  */
 struct cdx_dev_params {
        struct cdx_controller *cdx;
        struct device *parent;
        u16 vendor;
        u16 device;
+       u16 subsys_vendor;
+       u16 subsys_device;
        u8 bus_num;
        u8 dev_num;
        struct resource res[MAX_CDX_DEV_RESOURCES];
        u8 res_count;
        u32 req_id;
+       u32 class;
+       u8 revision;
 };
 
 /**
 
 
        dev_params->vendor = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_VENDOR_ID);
        dev_params->device = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_ID);
+       dev_params->subsys_vendor = MCDI_WORD(outbuf,
+                                             CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_VENDOR_ID);
+       dev_params->subsys_device = MCDI_WORD(outbuf,
+                                             CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_DEVICE_ID);
+       dev_params->class = MCDI_DWORD(outbuf,
+                                      CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_CLASS) & 0xFFFFFF;
+       dev_params->revision = MCDI_BYTE(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_REVISION);
 
        return 0;
 }
 
                                    u8 bus_num, u8 dev_num,
                                    struct cdx_device_config *dev_config);
 
+/**
+ * CDX_DEVICE - macro used to describe a specific CDX device
+ * @vend: the 16 bit CDX Vendor ID
+ * @dev: the 16 bit CDX Device ID
+ *
+ * This macro is used to create a struct cdx_device_id that matches a
+ * specific device. The subvendor and subdevice fields will be set to
+ * CDX_ANY_ID.
+ */
+#define CDX_DEVICE(vend, dev) \
+       .vendor = (vend), .device = (dev), \
+       .subvendor = CDX_ANY_ID, .subdevice = CDX_ANY_ID
+
 /**
  * CDX_DEVICE_DRIVER_OVERRIDE - macro used to describe a CDX device with
  *                              override_only flags.
  * @driver_override: the 32 bit CDX Device override_only
  *
  * This macro is used to create a struct cdx_device_id that matches only a
- * driver_override device.
+ * driver_override device. The subvendor and subdevice fields will be set to
+ * CDX_ANY_ID.
  */
 #define CDX_DEVICE_DRIVER_OVERRIDE(vend, dev, driver_override) \
-       .vendor = (vend), .device = (dev), .override_only = (driver_override)
+       .vendor = (vend), .device = (dev), .subvendor = CDX_ANY_ID,\
+       .subdevice = CDX_ANY_ID, .override_only = (driver_override)
 
 /**
  * struct cdx_ops - Callbacks supported by CDX controller.
  * @cdx: CDX controller associated with the device
  * @vendor: Vendor ID for CDX device
  * @device: Device ID for CDX device
+ * @subsystem_vendor: Subsystem Vendor ID for CDX device
+ * @subsystem_device: Subsystem Device ID for CDX device
+ * @class: Class for the CDX device
+ * @revision: Revision of the CDX device
  * @bus_num: Bus number for this CDX device
  * @dev_num: Device number for this device
  * @res: array of MMIO region entries
        struct cdx_controller *cdx;
        u16 vendor;
        u16 device;
+       u16 subsystem_vendor;
+       u16 subsystem_device;
+       u32 class;
+       u8 revision;
        u8 bus_num;
        u8 dev_num;
        struct resource res[MAX_CDX_DEV_RESOURCES];
 
  * struct cdx_device_id - CDX device identifier
  * @vendor: Vendor ID
  * @device: Device ID
+ * @subvendor: Subsystem vendor ID (or CDX_ANY_ID)
+ * @subdevice: Subsystem device ID (or CDX_ANY_ID)
+ * @class: Device class
+ *         Most drivers do not need to specify class/class_mask
+ *         as vendor/device is normally sufficient.
+ * @class_mask: Limit which sub-fields of the class field are compared.
  * @override_only: Match only when dev->driver_override is this driver.
  *
  * Type of entries in the "device Id" table for CDX devices supported by
 struct cdx_device_id {
        __u16 vendor;
        __u16 device;
+       __u16 subvendor;
+       __u16 subdevice;
+       __u32 class;
+       __u32 class_mask;
        __u32 override_only;
 };
 
 
        DEVID(cdx_device_id);
        DEVID_FIELD(cdx_device_id, vendor);
        DEVID_FIELD(cdx_device_id, device);
+       DEVID_FIELD(cdx_device_id, subvendor);
+       DEVID_FIELD(cdx_device_id, subdevice);
+       DEVID_FIELD(cdx_device_id, class);
+       DEVID_FIELD(cdx_device_id, class_mask);
        DEVID_FIELD(cdx_device_id, override_only);
 
        return 0;
 
 {
        DEF_FIELD(symval, cdx_device_id, vendor);
        DEF_FIELD(symval, cdx_device_id, device);
+       DEF_FIELD(symval, cdx_device_id, subvendor);
+       DEF_FIELD(symval, cdx_device_id, subdevice);
+       DEF_FIELD(symval, cdx_device_id, class);
+       DEF_FIELD(symval, cdx_device_id, class_mask);
        DEF_FIELD(symval, cdx_device_id, override_only);
 
        switch (override_only) {
 
        ADD(alias, "v", vendor != CDX_ANY_ID, vendor);
        ADD(alias, "d", device != CDX_ANY_ID, device);
+       ADD(alias, "sv", subvendor != CDX_ANY_ID, subvendor);
+       ADD(alias, "sd", subdevice != CDX_ANY_ID, subdevice);
+       ADD(alias, "c", class_mask == 0xFFFFFF, class);
+
        return 1;
 }