cdx: add sysfs for subsystem, class and revision

CDX controller provides subsystem vendor, subsystem device, class and
revision info of the device along with vendor and device ID in native
endian format. CDX Bus system uses this information to bind the cdx
device to the cdx device driver.

Co-developed-by: Puneet Gupta <puneet.gupta@amd.com>
Signed-off-by: Puneet Gupta <puneet.gupta@amd.com>
Co-developed-by: Nipun Gupta <nipun.gupta@amd.com>
Signed-off-by: Nipun Gupta <nipun.gupta@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
Reviewed-by: Pieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
Tested-by: Nikhil Agarwal <nikhil.agarwal@amd.com>
Link: https://lore.kernel.org/r/20231017160505.10640-8-abhijit.gangurde@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Abhijit Gangurde 2023-10-17 21:35:05 +05:30 committed by Greg Kroah-Hartman
parent 0174f58104
commit fa10f41309
8 changed files with 135 additions and 3 deletions

View File

@ -28,6 +28,36 @@ Description:
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
@ -67,3 +97,18 @@ Description:
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.

View File

@ -179,7 +179,10 @@ cdx_match_one_device(const struct cdx_device_id *id,
{
/* 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;
}
@ -329,6 +332,10 @@ static DEVICE_ATTR_RO(field)
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,
@ -377,6 +384,17 @@ static ssize_t reset_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)
@ -467,6 +485,11 @@ static struct attribute *cdx_dev_attrs[] = {
&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,
};
@ -604,6 +627,10 @@ int cdx_device_add(struct cdx_dev_params *dev_params)
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;

View File

@ -16,22 +16,30 @@
* @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;
};
/**

View File

@ -120,6 +120,13 @@ int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx,
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;
}

View File

@ -38,6 +38,19 @@ typedef int (*cdx_dev_configure_cb)(struct cdx_controller *cdx,
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.
@ -46,10 +59,12 @@ typedef int (*cdx_dev_configure_cb)(struct cdx_controller *cdx,
* @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.
@ -88,6 +103,10 @@ struct 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
@ -107,6 +126,10 @@ struct cdx_device {
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];

View File

@ -935,6 +935,12 @@ enum {
* 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
@ -943,6 +949,10 @@ enum {
struct cdx_device_id {
__u16 vendor;
__u16 device;
__u16 subvendor;
__u16 subdevice;
__u32 class;
__u32 class_mask;
__u32 override_only;
};

View File

@ -265,6 +265,10 @@ int main(void)
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;

View File

@ -1458,6 +1458,10 @@ static int do_cdx_entry(const char *filename, void *symval,
{
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) {
@ -1475,6 +1479,10 @@ static int do_cdx_entry(const char *filename, void *symval,
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;
}