Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cdx: add the cdx bus driver

Introduce AMD CDX bus, which provides a mechanism for scanning
and probing CDX devices. These devices are memory mapped on
system bus for Application Processors(APUs).

CDX devices can be changed dynamically in the Fabric and CDX
bus interacts with CDX controller to rescan the bus and
rediscover the devices.

Signed-off-by: Nipun Gupta <nipun.gupta@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/20230313132636.31850-2-nipun.gupta@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Nipun Gupta and committed by
Greg Kroah-Hartman
2959ab24 71d74aaa

+695
+12
Documentation/ABI/testing/sysfs-bus-cdx
··· 1 + What: /sys/bus/cdx/rescan 2 + Date: March 2023 3 + Contact: nipun.gupta@amd.com 4 + Description: 5 + Writing y/1/on to this file will cause rescan of the bus 6 + and devices on the CDX bus. Any new devices are scanned and 7 + added to the list of Linux devices and any devices removed are 8 + also deleted from Linux. 9 + 10 + For example:: 11 + 12 + # echo 1 > /sys/bus/cdx/rescan
+7
MAINTAINERS
··· 964 964 F: drivers/infiniband/hw/efa/ 965 965 F: include/uapi/rdma/efa-abi.h 966 966 967 + AMD CDX BUS DRIVER 968 + M: Nipun Gupta <nipun.gupta@amd.com> 969 + M: Nikhil Agarwal <nikhil.agarwal@amd.com> 970 + S: Maintained 971 + F: drivers/cdx/* 972 + F: include/linux/cdx/* 973 + 967 974 AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER 968 975 M: Tom Lendacky <thomas.lendacky@amd.com> 969 976 M: John Allen <john.allen@amd.com>
+2
drivers/Kconfig
··· 241 241 242 242 source "drivers/hte/Kconfig" 243 243 244 + source "drivers/cdx/Kconfig" 245 + 244 246 endmenu
+1
drivers/Makefile
··· 194 194 obj-$(CONFIG_PECI) += peci/ 195 195 obj-$(CONFIG_HTE) += hte/ 196 196 obj-$(CONFIG_DRM_ACCEL) += accel/ 197 + obj-$(CONFIG_CDX_BUS) += cdx/
+17
drivers/cdx/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # CDX bus configuration 4 + # 5 + # Copyright (C) 2022-2023, Advanced Micro Devices, Inc. 6 + # 7 + 8 + config CDX_BUS 9 + bool "CDX Bus driver" 10 + depends on OF && ARM64 11 + help 12 + Driver to enable Composable DMA Transfer(CDX) Bus. CDX bus 13 + exposes Fabric devices which uses composable DMA IP to the 14 + APU. CDX bus provides a mechanism for scanning and probing 15 + of CDX devices. CDX devices are memory mapped on system bus 16 + for embedded CPUs. CDX bus uses CDX controller and firmware 17 + to scan these CDX devices.
+8
drivers/cdx/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Makefile for CDX 4 + # 5 + # Copyright (C) 2022-2023, Advanced Micro Devices, Inc. 6 + # 7 + 8 + obj-$(CONFIG_CDX_BUS) += cdx.o
+408
drivers/cdx/cdx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * CDX bus driver. 4 + * 5 + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. 6 + */ 7 + 8 + /* 9 + * Architecture Overview 10 + * ===================== 11 + * CDX is a Hardware Architecture designed for AMD FPGA devices. It 12 + * consists of sophisticated mechanism for interaction between FPGA, 13 + * Firmware and the APUs (Application CPUs). 14 + * 15 + * Firmware resides on RPU (Realtime CPUs) which interacts with 16 + * the FPGA program manager and the APUs. The RPU provides memory-mapped 17 + * interface (RPU if) which is used to communicate with APUs. 18 + * 19 + * The diagram below shows an overview of the CDX architecture: 20 + * 21 + * +--------------------------------------+ 22 + * | Application CPUs (APU) | 23 + * | | 24 + * | CDX device drivers| 25 + * | Linux OS | | 26 + * | CDX bus | 27 + * | | | 28 + * | CDX controller | 29 + * | | | 30 + * +-----------------------------|--------+ 31 + * | (discover, config, 32 + * | reset, rescan) 33 + * | 34 + * +------------------------| RPU if |----+ 35 + * | | | 36 + * | V | 37 + * | Realtime CPUs (RPU) | 38 + * | | 39 + * +--------------------------------------+ 40 + * | 41 + * +---------------------|----------------+ 42 + * | FPGA | | 43 + * | +-----------------------+ | 44 + * | | | | | 45 + * | +-------+ +-------+ +-------+ | 46 + * | | dev 1 | | dev 2 | | dev 3 | | 47 + * | +-------+ +-------+ +-------+ | 48 + * +--------------------------------------+ 49 + * 50 + * The RPU firmware extracts the device information from the loaded FPGA 51 + * image and implements a mechanism that allows the APU drivers to 52 + * enumerate such devices (device personality and resource details) via 53 + * a dedicated communication channel. RPU mediates operations such as 54 + * discover, reset and rescan of the FPGA devices for the APU. This is 55 + * done using memory mapped interface provided by the RPU to APU. 56 + */ 57 + 58 + #include <linux/init.h> 59 + #include <linux/kernel.h> 60 + #include <linux/of_device.h> 61 + #include <linux/slab.h> 62 + #include <linux/mm.h> 63 + #include <linux/xarray.h> 64 + #include <linux/cdx/cdx_bus.h> 65 + #include "cdx.h" 66 + 67 + /* Default DMA mask for devices on a CDX bus */ 68 + #define CDX_DEFAULT_DMA_MASK (~0ULL) 69 + #define MAX_CDX_CONTROLLERS 16 70 + 71 + /* CDX controllers registered with the CDX bus */ 72 + static DEFINE_XARRAY_ALLOC(cdx_controllers); 73 + 74 + /** 75 + * cdx_unregister_device - Unregister a CDX device 76 + * @dev: CDX device 77 + * @data: This is always passed as NULL, and is not used in this API, 78 + * but is required here as the bus_for_each_dev() API expects 79 + * the passed function (cdx_unregister_device) to have this 80 + * as an argument. 81 + * 82 + * Return: 0 on success. 83 + */ 84 + static int cdx_unregister_device(struct device *dev, 85 + void *data) 86 + { 87 + struct cdx_device *cdx_dev = to_cdx_device(dev); 88 + 89 + kfree(cdx_dev->driver_override); 90 + cdx_dev->driver_override = NULL; 91 + /* 92 + * Do not free cdx_dev here as it would be freed in 93 + * cdx_device_release() called from within put_device(). 94 + */ 95 + device_del(&cdx_dev->dev); 96 + put_device(&cdx_dev->dev); 97 + 98 + return 0; 99 + } 100 + 101 + static void cdx_unregister_devices(struct bus_type *bus) 102 + { 103 + /* Reset all the devices attached to cdx bus */ 104 + bus_for_each_dev(bus, NULL, NULL, cdx_unregister_device); 105 + } 106 + 107 + /** 108 + * cdx_match_one_device - Tell if a CDX device structure has a matching 109 + * CDX device id structure 110 + * @id: single CDX device id structure to match 111 + * @dev: the CDX device structure to match against 112 + * 113 + * Return: matching cdx_device_id structure or NULL if there is no match. 114 + */ 115 + static inline const struct cdx_device_id * 116 + cdx_match_one_device(const struct cdx_device_id *id, 117 + const struct cdx_device *dev) 118 + { 119 + /* Use vendor ID and device ID for matching */ 120 + if ((id->vendor == CDX_ANY_ID || id->vendor == dev->vendor) && 121 + (id->device == CDX_ANY_ID || id->device == dev->device)) 122 + return id; 123 + return NULL; 124 + } 125 + 126 + /** 127 + * cdx_match_id - See if a CDX device matches a given cdx_id table 128 + * @ids: array of CDX device ID structures to search in 129 + * @dev: the CDX device structure to match against. 130 + * 131 + * Used by a driver to check whether a CDX device is in its list of 132 + * supported devices. Returns the matching cdx_device_id structure or 133 + * NULL if there is no match. 134 + * 135 + * Return: matching cdx_device_id structure or NULL if there is no match. 136 + */ 137 + static inline const struct cdx_device_id * 138 + cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev) 139 + { 140 + if (ids) { 141 + while (ids->vendor || ids->device) { 142 + if (cdx_match_one_device(ids, dev)) 143 + return ids; 144 + ids++; 145 + } 146 + } 147 + return NULL; 148 + } 149 + 150 + /** 151 + * cdx_bus_match - device to driver matching callback 152 + * @dev: the cdx device to match against 153 + * @drv: the device driver to search for matching cdx device 154 + * structures 155 + * 156 + * Return: true on success, false otherwise. 157 + */ 158 + static int cdx_bus_match(struct device *dev, struct device_driver *drv) 159 + { 160 + struct cdx_device *cdx_dev = to_cdx_device(dev); 161 + struct cdx_driver *cdx_drv = to_cdx_driver(drv); 162 + const struct cdx_device_id *found_id = NULL; 163 + const struct cdx_device_id *ids; 164 + 165 + ids = cdx_drv->match_id_table; 166 + 167 + /* When driver_override is set, only bind to the matching driver */ 168 + if (cdx_dev->driver_override && strcmp(cdx_dev->driver_override, drv->name)) 169 + return false; 170 + 171 + found_id = cdx_match_id(ids, cdx_dev); 172 + if (!found_id) 173 + return false; 174 + 175 + do { 176 + /* 177 + * In case override_only was set, enforce driver_override 178 + * matching. 179 + */ 180 + if (!found_id->override_only) 181 + return true; 182 + if (cdx_dev->driver_override) 183 + return true; 184 + 185 + ids = found_id + 1; 186 + found_id = cdx_match_id(ids, cdx_dev); 187 + } while (found_id); 188 + 189 + return false; 190 + } 191 + 192 + static int cdx_probe(struct device *dev) 193 + { 194 + struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); 195 + struct cdx_device *cdx_dev = to_cdx_device(dev); 196 + int error; 197 + 198 + error = cdx_drv->probe(cdx_dev); 199 + if (error) { 200 + dev_err_probe(dev, error, "%s failed\n", __func__); 201 + return error; 202 + } 203 + 204 + return 0; 205 + } 206 + 207 + static void cdx_remove(struct device *dev) 208 + { 209 + struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); 210 + struct cdx_device *cdx_dev = to_cdx_device(dev); 211 + 212 + if (cdx_drv && cdx_drv->remove) 213 + cdx_drv->remove(cdx_dev); 214 + } 215 + 216 + static void cdx_shutdown(struct device *dev) 217 + { 218 + struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); 219 + struct cdx_device *cdx_dev = to_cdx_device(dev); 220 + 221 + if (cdx_drv && cdx_drv->shutdown) 222 + cdx_drv->shutdown(cdx_dev); 223 + } 224 + 225 + static int cdx_dma_configure(struct device *dev) 226 + { 227 + struct cdx_device *cdx_dev = to_cdx_device(dev); 228 + u32 input_id = cdx_dev->req_id; 229 + int ret; 230 + 231 + ret = of_dma_configure_id(dev, dev->parent->of_node, 0, &input_id); 232 + if (ret && ret != -EPROBE_DEFER) { 233 + dev_err(dev, "of_dma_configure_id() failed\n"); 234 + return ret; 235 + } 236 + 237 + return 0; 238 + } 239 + 240 + static ssize_t rescan_store(struct bus_type *bus, 241 + const char *buf, size_t count) 242 + { 243 + struct cdx_controller *cdx; 244 + unsigned long index; 245 + bool val; 246 + 247 + if (kstrtobool(buf, &val) < 0) 248 + return -EINVAL; 249 + 250 + if (!val) 251 + return -EINVAL; 252 + 253 + /* Unregister all the devices on the bus */ 254 + cdx_unregister_devices(&cdx_bus_type); 255 + 256 + /* Rescan all the devices */ 257 + xa_for_each(&cdx_controllers, index, cdx) { 258 + int ret; 259 + 260 + ret = cdx->ops->scan(cdx); 261 + if (ret) 262 + dev_err(cdx->dev, "cdx bus scanning failed\n"); 263 + } 264 + 265 + return count; 266 + } 267 + static BUS_ATTR_WO(rescan); 268 + 269 + static struct attribute *cdx_bus_attrs[] = { 270 + &bus_attr_rescan.attr, 271 + NULL, 272 + }; 273 + ATTRIBUTE_GROUPS(cdx_bus); 274 + 275 + struct bus_type cdx_bus_type = { 276 + .name = "cdx", 277 + .match = cdx_bus_match, 278 + .probe = cdx_probe, 279 + .remove = cdx_remove, 280 + .shutdown = cdx_shutdown, 281 + .dma_configure = cdx_dma_configure, 282 + .bus_groups = cdx_bus_groups, 283 + }; 284 + EXPORT_SYMBOL_GPL(cdx_bus_type); 285 + 286 + int __cdx_driver_register(struct cdx_driver *cdx_driver, 287 + struct module *owner) 288 + { 289 + int error; 290 + 291 + cdx_driver->driver.owner = owner; 292 + cdx_driver->driver.bus = &cdx_bus_type; 293 + 294 + error = driver_register(&cdx_driver->driver); 295 + if (error) { 296 + pr_err("driver_register() failed for %s: %d\n", 297 + cdx_driver->driver.name, error); 298 + return error; 299 + } 300 + 301 + return 0; 302 + } 303 + EXPORT_SYMBOL_GPL(__cdx_driver_register); 304 + 305 + void cdx_driver_unregister(struct cdx_driver *cdx_driver) 306 + { 307 + driver_unregister(&cdx_driver->driver); 308 + } 309 + EXPORT_SYMBOL_GPL(cdx_driver_unregister); 310 + 311 + static void cdx_device_release(struct device *dev) 312 + { 313 + struct cdx_device *cdx_dev = to_cdx_device(dev); 314 + 315 + kfree(cdx_dev); 316 + } 317 + 318 + int cdx_device_add(struct cdx_dev_params *dev_params) 319 + { 320 + struct cdx_controller *cdx = dev_params->cdx; 321 + struct device *parent = cdx->dev; 322 + struct cdx_device *cdx_dev; 323 + int ret; 324 + 325 + cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL); 326 + if (!cdx_dev) 327 + return -ENOMEM; 328 + 329 + /* Populate resource */ 330 + memcpy(cdx_dev->res, dev_params->res, sizeof(struct resource) * 331 + dev_params->res_count); 332 + cdx_dev->res_count = dev_params->res_count; 333 + 334 + /* Populate CDX dev params */ 335 + cdx_dev->req_id = dev_params->req_id; 336 + cdx_dev->vendor = dev_params->vendor; 337 + cdx_dev->device = dev_params->device; 338 + cdx_dev->bus_num = dev_params->bus_num; 339 + cdx_dev->dev_num = dev_params->dev_num; 340 + cdx_dev->cdx = dev_params->cdx; 341 + cdx_dev->dma_mask = CDX_DEFAULT_DMA_MASK; 342 + 343 + /* Initialize generic device */ 344 + device_initialize(&cdx_dev->dev); 345 + cdx_dev->dev.parent = parent; 346 + cdx_dev->dev.bus = &cdx_bus_type; 347 + cdx_dev->dev.dma_mask = &cdx_dev->dma_mask; 348 + cdx_dev->dev.release = cdx_device_release; 349 + 350 + /* Set Name */ 351 + dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x", 352 + ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (cdx_dev->bus_num & CDX_BUS_NUM_MASK)), 353 + cdx_dev->dev_num); 354 + 355 + ret = device_add(&cdx_dev->dev); 356 + if (ret) { 357 + dev_err(&cdx_dev->dev, 358 + "cdx device add failed: %d", ret); 359 + goto fail; 360 + } 361 + 362 + return 0; 363 + fail: 364 + /* 365 + * Do not free cdx_dev here as it would be freed in 366 + * cdx_device_release() called from put_device(). 367 + */ 368 + put_device(&cdx_dev->dev); 369 + 370 + return ret; 371 + } 372 + EXPORT_SYMBOL_GPL(cdx_device_add); 373 + 374 + int cdx_register_controller(struct cdx_controller *cdx) 375 + { 376 + int ret; 377 + 378 + ret = xa_alloc(&cdx_controllers, &cdx->id, cdx, 379 + XA_LIMIT(0, MAX_CDX_CONTROLLERS - 1), GFP_KERNEL); 380 + if (ret) { 381 + dev_err(cdx->dev, 382 + "No free index available. Maximum controllers already registered\n"); 383 + cdx->id = (u8)MAX_CDX_CONTROLLERS; 384 + return ret; 385 + } 386 + 387 + /* Scan all the devices */ 388 + cdx->ops->scan(cdx); 389 + 390 + return 0; 391 + } 392 + EXPORT_SYMBOL_GPL(cdx_register_controller); 393 + 394 + void cdx_unregister_controller(struct cdx_controller *cdx) 395 + { 396 + if (cdx->id >= MAX_CDX_CONTROLLERS) 397 + return; 398 + 399 + device_for_each_child(cdx->dev, NULL, cdx_unregister_device); 400 + xa_erase(&cdx_controllers, cdx->id); 401 + } 402 + EXPORT_SYMBOL_GPL(cdx_unregister_controller); 403 + 404 + static int __init cdx_bus_init(void) 405 + { 406 + return bus_register(&cdx_bus_type); 407 + } 408 + postcore_initcall(cdx_bus_init);
+62
drivers/cdx/cdx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * Header file for the CDX Bus 4 + * 5 + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. 6 + */ 7 + 8 + #ifndef _CDX_H_ 9 + #define _CDX_H_ 10 + 11 + #include <linux/cdx/cdx_bus.h> 12 + 13 + /** 14 + * struct cdx_dev_params - CDX device parameters 15 + * @cdx: CDX controller associated with the device 16 + * @parent: Associated CDX controller 17 + * @vendor: Vendor ID for CDX device 18 + * @device: Device ID for CDX device 19 + * @bus_num: Bus number for this CDX device 20 + * @dev_num: Device number for this device 21 + * @res: array of MMIO region entries 22 + * @res_count: number of valid MMIO regions 23 + * @req_id: Requestor ID associated with CDX device 24 + */ 25 + struct cdx_dev_params { 26 + struct cdx_controller *cdx; 27 + u16 vendor; 28 + u16 device; 29 + u8 bus_num; 30 + u8 dev_num; 31 + struct resource res[MAX_CDX_DEV_RESOURCES]; 32 + u8 res_count; 33 + u32 req_id; 34 + }; 35 + 36 + /** 37 + * cdx_register_controller - Register a CDX controller and its ports 38 + * on the CDX bus. 39 + * @cdx: The CDX controller to register 40 + * 41 + * Return: -errno on failure, 0 on success. 42 + */ 43 + int cdx_register_controller(struct cdx_controller *cdx); 44 + 45 + /** 46 + * cdx_unregister_controller - Unregister a CDX controller 47 + * @cdx: The CDX controller to unregister 48 + */ 49 + void cdx_unregister_controller(struct cdx_controller *cdx); 50 + 51 + /** 52 + * cdx_device_add - Add a CDX device. This function adds a CDX device 53 + * on the CDX bus as per the device parameters provided 54 + * by caller. It also creates and registers an associated 55 + * Linux generic device. 56 + * @dev_params: device parameters associated with the device to be created. 57 + * 58 + * Return: -errno on failure, 0 on success. 59 + */ 60 + int cdx_device_add(struct cdx_dev_params *dev_params); 61 + 62 + #endif /* _CDX_H_ */
+147
include/linux/cdx/cdx_bus.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * CDX bus public interface 4 + * 5 + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. 6 + * 7 + */ 8 + 9 + #ifndef _CDX_BUS_H_ 10 + #define _CDX_BUS_H_ 11 + 12 + #include <linux/device.h> 13 + #include <linux/list.h> 14 + #include <linux/mod_devicetable.h> 15 + 16 + #define MAX_CDX_DEV_RESOURCES 4 17 + #define CDX_ANY_ID (0xFFFF) 18 + #define CDX_CONTROLLER_ID_SHIFT 4 19 + #define CDX_BUS_NUM_MASK 0xF 20 + 21 + /* Forward declaration for CDX controller */ 22 + struct cdx_controller; 23 + 24 + typedef int (*cdx_scan_cb)(struct cdx_controller *cdx); 25 + 26 + /** 27 + * CDX_DEVICE_DRIVER_OVERRIDE - macro used to describe a CDX device with 28 + * override_only flags. 29 + * @vend: the 16 bit CDX Vendor ID 30 + * @dev: the 16 bit CDX Device ID 31 + * @driver_override: the 32 bit CDX Device override_only 32 + * 33 + * This macro is used to create a struct cdx_device_id that matches only a 34 + * driver_override device. 35 + */ 36 + #define CDX_DEVICE_DRIVER_OVERRIDE(vend, dev, driver_override) \ 37 + .vendor = (vend), .device = (dev), .override_only = (driver_override) 38 + 39 + /** 40 + * struct cdx_ops - Callbacks supported by CDX controller. 41 + * @scan: scan the devices on the controller 42 + */ 43 + struct cdx_ops { 44 + cdx_scan_cb scan; 45 + }; 46 + 47 + /** 48 + * struct cdx_controller: CDX controller object 49 + * @dev: Linux device associated with the CDX controller. 50 + * @priv: private data 51 + * @id: Controller ID 52 + * @ops: CDX controller ops 53 + */ 54 + struct cdx_controller { 55 + struct device *dev; 56 + void *priv; 57 + u32 id; 58 + struct cdx_ops *ops; 59 + }; 60 + 61 + /** 62 + * struct cdx_device - CDX device object 63 + * @dev: Linux driver model device object 64 + * @cdx: CDX controller associated with the device 65 + * @vendor: Vendor ID for CDX device 66 + * @device: Device ID for CDX device 67 + * @bus_num: Bus number for this CDX device 68 + * @dev_num: Device number for this device 69 + * @res: array of MMIO region entries 70 + * @res_attr: resource binary attribute 71 + * @res_count: number of valid MMIO regions 72 + * @dma_mask: Default DMA mask 73 + * @flags: CDX device flags 74 + * @req_id: Requestor ID associated with CDX device 75 + * @driver_override: driver name to force a match; do not set directly, 76 + * because core frees it; use driver_set_override() to 77 + * set or clear it. 78 + */ 79 + struct cdx_device { 80 + struct device dev; 81 + struct cdx_controller *cdx; 82 + u16 vendor; 83 + u16 device; 84 + u8 bus_num; 85 + u8 dev_num; 86 + struct resource res[MAX_CDX_DEV_RESOURCES]; 87 + u8 res_count; 88 + u64 dma_mask; 89 + u16 flags; 90 + u32 req_id; 91 + const char *driver_override; 92 + }; 93 + 94 + #define to_cdx_device(_dev) \ 95 + container_of(_dev, struct cdx_device, dev) 96 + 97 + /** 98 + * struct cdx_driver - CDX device driver 99 + * @driver: Generic device driver 100 + * @match_id_table: table of supported device matching Ids 101 + * @probe: Function called when a device is added 102 + * @remove: Function called when a device is removed 103 + * @shutdown: Function called at shutdown time to quiesce the device 104 + * @driver_managed_dma: Device driver doesn't use kernel DMA API for DMA. 105 + * For most device drivers, no need to care about this flag 106 + * as long as all DMAs are handled through the kernel DMA API. 107 + * For some special ones, for example VFIO drivers, they know 108 + * how to manage the DMA themselves and set this flag so that 109 + * the IOMMU layer will allow them to setup and manage their 110 + * own I/O address space. 111 + */ 112 + struct cdx_driver { 113 + struct device_driver driver; 114 + const struct cdx_device_id *match_id_table; 115 + int (*probe)(struct cdx_device *dev); 116 + int (*remove)(struct cdx_device *dev); 117 + void (*shutdown)(struct cdx_device *dev); 118 + bool driver_managed_dma; 119 + }; 120 + 121 + #define to_cdx_driver(_drv) \ 122 + container_of(_drv, struct cdx_driver, driver) 123 + 124 + /* Macro to avoid include chaining to get THIS_MODULE */ 125 + #define cdx_driver_register(drv) \ 126 + __cdx_driver_register(drv, THIS_MODULE) 127 + 128 + /** 129 + * __cdx_driver_register - registers a CDX device driver 130 + * @cdx_driver: CDX driver to register 131 + * @owner: module owner 132 + * 133 + * Return: -errno on failure, 0 on success. 134 + */ 135 + int __must_check __cdx_driver_register(struct cdx_driver *cdx_driver, 136 + struct module *owner); 137 + 138 + /** 139 + * cdx_driver_unregister - unregisters a device driver from the 140 + * CDX bus. 141 + * @cdx_driver: CDX driver to register 142 + */ 143 + void cdx_driver_unregister(struct cdx_driver *cdx_driver); 144 + 145 + extern struct bus_type cdx_bus_type; 146 + 147 + #endif /* _CDX_BUS_H_ */
+15
include/linux/mod_devicetable.h
··· 912 912 kernel_ulong_t driver_data; 913 913 }; 914 914 915 + /** 916 + * struct cdx_device_id - CDX device identifier 917 + * @vendor: Vendor ID 918 + * @device: Device ID 919 + * @override_only: Match only when dev->driver_override is this driver. 920 + * 921 + * Type of entries in the "device Id" table for CDX devices supported by 922 + * a CDX device driver. 923 + */ 924 + struct cdx_device_id { 925 + __u16 vendor; 926 + __u16 device; 927 + __u32 override_only; 928 + }; 929 + 915 930 #endif /* LINUX_MOD_DEVICETABLE_H */
+4
scripts/mod/devicetable-offsets.c
··· 262 262 DEVID(ishtp_device_id); 263 263 DEVID_FIELD(ishtp_device_id, guid); 264 264 265 + DEVID(cdx_device_id); 266 + DEVID_FIELD(cdx_device_id, vendor); 267 + DEVID_FIELD(cdx_device_id, device); 268 + 265 269 return 0; 266 270 }
+12
scripts/mod/file2alias.c
··· 1452 1452 return 1; 1453 1453 } 1454 1454 1455 + /* Looks like: cdx:vNdN */ 1456 + static int do_cdx_entry(const char *filename, void *symval, 1457 + char *alias) 1458 + { 1459 + DEF_FIELD(symval, cdx_device_id, vendor); 1460 + DEF_FIELD(symval, cdx_device_id, device); 1461 + 1462 + sprintf(alias, "cdx:v%08Xd%08Xd", vendor, device); 1463 + return 1; 1464 + } 1465 + 1455 1466 /* Does namelen bytes of name exactly match the symbol? */ 1456 1467 static bool sym_is(const char *name, unsigned namelen, const char *symbol) 1457 1468 { ··· 1542 1531 {"ssam", SIZE_ssam_device_id, do_ssam_entry}, 1543 1532 {"dfl", SIZE_dfl_device_id, do_dfl_entry}, 1544 1533 {"ishtp", SIZE_ishtp_device_id, do_ishtp_entry}, 1534 + {"cdx", SIZE_cdx_device_id, do_cdx_entry}, 1545 1535 }; 1546 1536 1547 1537 /* Create MODULE_ALIAS() statements.