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 | #include <linux/msi.h> |
16 | |
17 | #define MAX_CDX_DEV_RESOURCES 4 |
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 | enum { |
25 | CDX_DEV_MSI_CONF, |
26 | CDX_DEV_BUS_MASTER_CONF, |
27 | CDX_DEV_RESET_CONF, |
28 | CDX_DEV_MSI_ENABLE, |
29 | }; |
30 | |
31 | struct cdx_msi_config { |
32 | u64 addr; |
33 | u32 data; |
34 | u16 msi_index; |
35 | }; |
36 | |
37 | struct cdx_device_config { |
38 | u8 type; |
39 | union { |
40 | struct cdx_msi_config msi; |
41 | bool bus_master_enable; |
42 | bool msi_enable; |
43 | }; |
44 | }; |
45 | |
46 | typedef int (*cdx_bus_enable_cb)(struct cdx_controller *cdx, u8 bus_num); |
47 | |
48 | typedef int (*cdx_bus_disable_cb)(struct cdx_controller *cdx, u8 bus_num); |
49 | |
50 | typedef int (*cdx_scan_cb)(struct cdx_controller *cdx); |
51 | |
52 | typedef int (*cdx_dev_configure_cb)(struct cdx_controller *cdx, |
53 | u8 bus_num, u8 dev_num, |
54 | struct cdx_device_config *dev_config); |
55 | |
56 | /** |
57 | * CDX_DEVICE - macro used to describe a specific CDX device |
58 | * @vend: the 16 bit CDX Vendor ID |
59 | * @dev: the 16 bit CDX Device ID |
60 | * |
61 | * This macro is used to create a struct cdx_device_id that matches a |
62 | * specific device. The subvendor and subdevice fields will be set to |
63 | * CDX_ANY_ID. |
64 | */ |
65 | #define CDX_DEVICE(vend, dev) \ |
66 | .vendor = (vend), .device = (dev), \ |
67 | .subvendor = CDX_ANY_ID, .subdevice = CDX_ANY_ID |
68 | |
69 | /** |
70 | * CDX_DEVICE_DRIVER_OVERRIDE - macro used to describe a CDX device with |
71 | * override_only flags. |
72 | * @vend: the 16 bit CDX Vendor ID |
73 | * @dev: the 16 bit CDX Device ID |
74 | * @driver_override: the 32 bit CDX Device override_only |
75 | * |
76 | * This macro is used to create a struct cdx_device_id that matches only a |
77 | * driver_override device. The subvendor and subdevice fields will be set to |
78 | * CDX_ANY_ID. |
79 | */ |
80 | #define CDX_DEVICE_DRIVER_OVERRIDE(vend, dev, driver_override) \ |
81 | .vendor = (vend), .device = (dev), .subvendor = CDX_ANY_ID,\ |
82 | .subdevice = CDX_ANY_ID, .override_only = (driver_override) |
83 | |
84 | /** |
85 | * struct cdx_ops - Callbacks supported by CDX controller. |
86 | * @bus_enable: enable bus on the controller |
87 | * @bus_disable: disable bus on the controller |
88 | * @scan: scan the devices on the controller |
89 | * @dev_configure: configuration like reset, master_enable, |
90 | * msi_config etc for a CDX device |
91 | */ |
92 | struct cdx_ops { |
93 | cdx_bus_enable_cb bus_enable; |
94 | cdx_bus_disable_cb bus_disable; |
95 | cdx_scan_cb scan; |
96 | cdx_dev_configure_cb dev_configure; |
97 | }; |
98 | |
99 | /** |
100 | * struct cdx_controller: CDX controller object |
101 | * @dev: Linux device associated with the CDX controller. |
102 | * @priv: private data |
103 | * @msi_domain: MSI domain |
104 | * @id: Controller ID |
105 | * @controller_registered: controller registered with bus |
106 | * @ops: CDX controller ops |
107 | */ |
108 | struct cdx_controller { |
109 | struct device *dev; |
110 | void *priv; |
111 | struct irq_domain *msi_domain; |
112 | u32 id; |
113 | bool controller_registered; |
114 | struct cdx_ops *ops; |
115 | }; |
116 | |
117 | /** |
118 | * struct cdx_device - CDX device object |
119 | * @dev: Linux driver model device object |
120 | * @cdx: CDX controller associated with the device |
121 | * @vendor: Vendor ID for CDX device |
122 | * @device: Device ID for CDX device |
123 | * @subsystem_vendor: Subsystem Vendor ID for CDX device |
124 | * @subsystem_device: Subsystem Device ID for CDX device |
125 | * @class: Class for the CDX device |
126 | * @revision: Revision of the CDX device |
127 | * @bus_num: Bus number for this CDX device |
128 | * @dev_num: Device number for this device |
129 | * @res: array of MMIO region entries |
130 | * @res_attr: resource binary attribute |
131 | * @debugfs_dir: debugfs directory for this device |
132 | * @res_count: number of valid MMIO regions |
133 | * @dma_mask: Default DMA mask |
134 | * @flags: CDX device flags |
135 | * @req_id: Requestor ID associated with CDX device |
136 | * @is_bus: Is this bus device |
137 | * @enabled: is this bus enabled |
138 | * @msi_dev_id: MSI Device ID associated with CDX device |
139 | * @num_msi: Number of MSI's supported by the device |
140 | * @driver_override: driver name to force a match; do not set directly, |
141 | * because core frees it; use driver_set_override() to |
142 | * set or clear it. |
143 | * @irqchip_lock: lock to synchronize irq/msi configuration |
144 | * @msi_write_pending: MSI write pending for this device |
145 | */ |
146 | struct cdx_device { |
147 | struct device dev; |
148 | struct cdx_controller *cdx; |
149 | u16 vendor; |
150 | u16 device; |
151 | u16 subsystem_vendor; |
152 | u16 subsystem_device; |
153 | u32 class; |
154 | u8 revision; |
155 | u8 bus_num; |
156 | u8 dev_num; |
157 | struct resource res[MAX_CDX_DEV_RESOURCES]; |
158 | struct bin_attribute *res_attr[MAX_CDX_DEV_RESOURCES]; |
159 | struct dentry *debugfs_dir; |
160 | u8 res_count; |
161 | u64 dma_mask; |
162 | u16 flags; |
163 | u32 req_id; |
164 | bool is_bus; |
165 | bool enabled; |
166 | u32 msi_dev_id; |
167 | u32 num_msi; |
168 | const char *driver_override; |
169 | struct mutex irqchip_lock; |
170 | bool msi_write_pending; |
171 | }; |
172 | |
173 | #define to_cdx_device(_dev) \ |
174 | container_of(_dev, struct cdx_device, dev) |
175 | |
176 | #define cdx_resource_start(dev, num) ((dev)->res[(num)].start) |
177 | #define cdx_resource_end(dev, num) ((dev)->res[(num)].end) |
178 | #define cdx_resource_flags(dev, num) ((dev)->res[(num)].flags) |
179 | #define cdx_resource_len(dev, num) \ |
180 | ((cdx_resource_start((dev), (num)) == 0 && \ |
181 | cdx_resource_end((dev), (num)) == \ |
182 | cdx_resource_start((dev), (num))) ? 0 : \ |
183 | (cdx_resource_end((dev), (num)) - \ |
184 | cdx_resource_start((dev), (num)) + 1)) |
185 | /** |
186 | * struct cdx_driver - CDX device driver |
187 | * @driver: Generic device driver |
188 | * @match_id_table: table of supported device matching Ids |
189 | * @probe: Function called when a device is added |
190 | * @remove: Function called when a device is removed |
191 | * @shutdown: Function called at shutdown time to quiesce the device |
192 | * @reset_prepare: Function called before is reset to notify driver |
193 | * @reset_done: Function called after reset is complete to notify driver |
194 | * @driver_managed_dma: Device driver doesn't use kernel DMA API for DMA. |
195 | * For most device drivers, no need to care about this flag |
196 | * as long as all DMAs are handled through the kernel DMA API. |
197 | * For some special ones, for example VFIO drivers, they know |
198 | * how to manage the DMA themselves and set this flag so that |
199 | * the IOMMU layer will allow them to setup and manage their |
200 | * own I/O address space. |
201 | */ |
202 | struct cdx_driver { |
203 | struct device_driver driver; |
204 | const struct cdx_device_id *match_id_table; |
205 | int (*probe)(struct cdx_device *dev); |
206 | int (*remove)(struct cdx_device *dev); |
207 | void (*shutdown)(struct cdx_device *dev); |
208 | void (*reset_prepare)(struct cdx_device *dev); |
209 | void (*reset_done)(struct cdx_device *dev); |
210 | bool driver_managed_dma; |
211 | }; |
212 | |
213 | #define to_cdx_driver(_drv) \ |
214 | container_of(_drv, struct cdx_driver, driver) |
215 | |
216 | /* Macro to avoid include chaining to get THIS_MODULE */ |
217 | #define cdx_driver_register(drv) \ |
218 | __cdx_driver_register(drv, THIS_MODULE) |
219 | |
220 | /** |
221 | * __cdx_driver_register - registers a CDX device driver |
222 | * @cdx_driver: CDX driver to register |
223 | * @owner: module owner |
224 | * |
225 | * Return: -errno on failure, 0 on success. |
226 | */ |
227 | int __must_check __cdx_driver_register(struct cdx_driver *cdx_driver, |
228 | struct module *owner); |
229 | |
230 | /** |
231 | * cdx_driver_unregister - unregisters a device driver from the |
232 | * CDX bus. |
233 | * @cdx_driver: CDX driver to register |
234 | */ |
235 | void cdx_driver_unregister(struct cdx_driver *cdx_driver); |
236 | |
237 | extern struct bus_type cdx_bus_type; |
238 | |
239 | /** |
240 | * cdx_dev_reset - Reset CDX device |
241 | * @dev: device pointer |
242 | * |
243 | * Return: 0 for success, -errno on failure |
244 | */ |
245 | int cdx_dev_reset(struct device *dev); |
246 | |
247 | /** |
248 | * cdx_set_master - enables bus-mastering for CDX device |
249 | * @cdx_dev: the CDX device to enable |
250 | * |
251 | * Return: 0 for success, -errno on failure |
252 | */ |
253 | int cdx_set_master(struct cdx_device *cdx_dev); |
254 | |
255 | /** |
256 | * cdx_clear_master - disables bus-mastering for CDX device |
257 | * @cdx_dev: the CDX device to disable |
258 | * |
259 | * Return: 0 for success, -errno on failure |
260 | */ |
261 | int cdx_clear_master(struct cdx_device *cdx_dev); |
262 | |
263 | #ifdef CONFIG_GENERIC_MSI_IRQ |
264 | /** |
265 | * cdx_enable_msi - Enable MSI for the CDX device. |
266 | * @cdx_dev: device pointer |
267 | * |
268 | * Return: 0 for success, -errno on failure |
269 | */ |
270 | int cdx_enable_msi(struct cdx_device *cdx_dev); |
271 | |
272 | /** |
273 | * cdx_disable_msi - Disable MSI for the CDX device. |
274 | * @cdx_dev: device pointer |
275 | */ |
276 | void cdx_disable_msi(struct cdx_device *cdx_dev); |
277 | |
278 | #else /* CONFIG_GENERIC_MSI_IRQ */ |
279 | |
280 | static inline int cdx_enable_msi(struct cdx_device *cdx_dev) |
281 | { |
282 | return -ENODEV; |
283 | } |
284 | |
285 | static inline void cdx_disable_msi(struct cdx_device *cdx_dev) |
286 | { |
287 | } |
288 | |
289 | #endif /* CONFIG_GENERIC_MSI_IRQ */ |
290 | |
291 | #endif /* _CDX_BUS_H_ */ |
292 | |