1 /* 2 * Copyright (c) 2019 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ 8 #define ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ 9 10 /** 11 * @brief PCIe Host Interface 12 * @defgroup pcie_host_interface PCIe Host Interface 13 * @ingroup io_interfaces 14 * @{ 15 */ 16 17 #include <stddef.h> 18 #include <zephyr/devicetree.h> 19 #include <zephyr/dt-bindings/pcie/pcie.h> 20 #include <zephyr/types.h> 21 #include <zephyr/kernel.h> 22 #include <zephyr/sys/iterable_sections.h> 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 /** 29 * @typedef pcie_bdf_t 30 * @brief A unique PCI(e) endpoint (bus, device, function). 31 * 32 * A PCI(e) endpoint is uniquely identified topologically using a 33 * (bus, device, function) tuple. The internal structure is documented 34 * in include/dt-bindings/pcie/pcie.h: see PCIE_BDF() and friends, since 35 * these tuples are referenced from devicetree. 36 */ 37 typedef uint32_t pcie_bdf_t; 38 39 /** 40 * @typedef pcie_id_t 41 * @brief A unique PCI(e) identifier (vendor ID, device ID). 42 * 43 * The PCIE_CONF_ID register for each endpoint is a (vendor ID, device ID) 44 * pair, which is meant to tell the system what the PCI(e) endpoint is. Again, 45 * look to PCIE_ID_* macros in include/dt-bindings/pcie/pcie.h for more. 46 */ 47 typedef uint32_t pcie_id_t; 48 49 /* Helper macro to exclude invalid PCIe identifiers. We should really only 50 * need to look for PCIE_ID_NONE, but because of some broken PCI host controllers 51 * we have try cases where both VID & DID are zero or just one of them is 52 * zero (0x0000) and the other is all ones (0xFFFF). 53 */ 54 #define PCIE_ID_IS_VALID(id) ((id != PCIE_ID_NONE) && \ 55 (id != PCIE_ID(0x0000, 0x0000)) && \ 56 (id != PCIE_ID(0xFFFF, 0x0000)) && \ 57 (id != PCIE_ID(0x0000, 0xFFFF))) 58 59 struct pcie_dev { 60 pcie_bdf_t bdf; 61 pcie_id_t id; 62 uint32_t class_rev; 63 uint32_t class_rev_mask; 64 }; 65 66 #define Z_DEVICE_PCIE_NAME(node_id) _CONCAT(pcie_dev_, DT_DEP_ORD(node_id)) 67 68 /** 69 * @brief Get the PCIe Vendor and Device ID for a node 70 * 71 * @param node_id DTS node identifier 72 * @return The VID/DID combination as pcie_id_t 73 */ 74 #define PCIE_DT_ID(node_id) PCIE_ID(DT_PROP_OR(node_id, vendor_id, 0xffff), \ 75 DT_PROP_OR(node_id, device_id, 0xffff)) 76 77 /** 78 * @brief Get the PCIe Vendor and Device ID for a node 79 * 80 * This is equivalent to 81 * <tt>PCIE_DT_ID(DT_DRV_INST(inst))</tt> 82 * 83 * @param inst Devicetree instance number 84 * @return The VID/DID combination as pcie_id_t 85 */ 86 #define PCIE_DT_INST_ID(inst) PCIE_DT_ID(DT_DRV_INST(inst)) 87 88 /** 89 * @brief Declare a PCIe context variable for a DTS node 90 * 91 * Declares a PCIe context for a DTS node. This must be done before 92 * using the DEVICE_PCIE_INIT() macro for the same node. 93 * 94 * @param node_id DTS node identifier 95 */ 96 #define DEVICE_PCIE_DECLARE(node_id) \ 97 STRUCT_SECTION_ITERABLE(pcie_dev, Z_DEVICE_PCIE_NAME(node_id)) = { \ 98 .bdf = PCIE_BDF_NONE, \ 99 .id = PCIE_DT_ID(node_id), \ 100 .class_rev = DT_PROP_OR(node_id, class_rev, 0), \ 101 .class_rev_mask = DT_PROP_OR(node_id, class_rev_mask, 0), \ 102 } 103 104 /** 105 * @brief Declare a PCIe context variable for a DTS node 106 * 107 * This is equivalent to 108 * <tt>DEVICE_PCIE_DECLARE(DT_DRV_INST(inst))</tt> 109 * 110 * @param inst Devicetree instance number 111 */ 112 #define DEVICE_PCIE_INST_DECLARE(inst) DEVICE_PCIE_DECLARE(DT_DRV_INST(inst)) 113 114 /** 115 * @brief Initialize a named struct member to point at a PCIe context 116 * 117 * Initialize PCIe-related information within a specific instance of 118 * a device config struct, using information from DTS. Using the macro 119 * requires having first created PCIe context struct using the 120 * DEVICE_PCIE_DECLARE() macro. 121 * 122 * Example for an instance of a driver belonging to the "foo" subsystem 123 * 124 * struct foo_config { 125 * struct pcie_dev *pcie; 126 * ... 127 *}; 128 * 129 * DEVICE_PCIE_ID_DECLARE(DT_DRV_INST(...)); 130 * struct foo_config my_config = { 131 DEVICE_PCIE_INIT(pcie, DT_DRV_INST(...)), 132 * ... 133 * }; 134 * 135 * @param node_id DTS node identifier 136 * @param name Member name within config for the MMIO region 137 */ 138 #define DEVICE_PCIE_INIT(node_id, name) .name = &Z_DEVICE_PCIE_NAME(node_id) 139 140 /** 141 * @brief Initialize a named struct member to point at a PCIe context 142 * 143 * This is equivalent to 144 * <tt>DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)</tt> 145 * 146 * @param inst Devicetree instance number 147 * @param name Name of the struct member (of type struct pcie_dev *) 148 */ 149 #define DEVICE_PCIE_INST_INIT(inst, name) \ 150 DEVICE_PCIE_INIT(DT_DRV_INST(inst), name) 151 152 struct pcie_bar { 153 uintptr_t phys_addr; 154 size_t size; 155 }; 156 157 /* 158 * These functions are arch-, board-, or SoC-specific. 159 */ 160 161 /** 162 * @brief Read a 32-bit word from an endpoint's configuration space. 163 * 164 * This function is exported by the arch/SoC/board code. 165 * 166 * @param bdf PCI(e) endpoint 167 * @param reg the configuration word index (not address) 168 * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word) 169 */ 170 extern uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg); 171 172 /** 173 * @brief Write a 32-bit word to an endpoint's configuration space. 174 * 175 * This function is exported by the arch/SoC/board code. 176 * 177 * @param bdf PCI(e) endpoint 178 * @param reg the configuration word index (not address) 179 * @param data the value to write 180 */ 181 extern void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data); 182 183 /** Callback type used for scanning for PCI endpoints 184 * 185 * @param bdf BDF value for a found endpoint. 186 * @param id Vendor & Device ID for the found endpoint. 187 * @param cb_data Custom, use case specific data. 188 * 189 * @return true to continue scanning, false to stop scanning. 190 */ 191 typedef bool (*pcie_scan_cb_t)(pcie_bdf_t bdf, pcie_id_t id, void *cb_data); 192 193 enum { 194 /** Scan all available PCI host controllers and sub-busses */ 195 PCIE_SCAN_RECURSIVE = BIT(0), 196 /** Do the callback for all endpoint types, including bridges */ 197 PCIE_SCAN_CB_ALL = BIT(1), 198 }; 199 200 /** Options for performing a scan for PCI devices */ 201 struct pcie_scan_opt { 202 /** Initial bus number to scan */ 203 uint8_t bus; 204 205 /** Function to call for each found endpoint */ 206 pcie_scan_cb_t cb; 207 208 /** Custom data to pass to the scan callback */ 209 void *cb_data; 210 211 /** Scan flags */ 212 uint32_t flags; 213 }; 214 215 /** Scan for PCIe devices. 216 * 217 * Scan the PCI bus (or buses) for available endpoints. 218 * 219 * @param opt Options determining how to perform the scan. 220 * @return 0 on success, negative POSIX error number on failure. 221 */ 222 int pcie_scan(const struct pcie_scan_opt *opt); 223 224 /** 225 * @brief Get the MBAR at a specific BAR index 226 * @param bdf the PCI(e) endpoint 227 * @param bar_index 0-based BAR index 228 * @param mbar Pointer to struct pcie_bar 229 * @return true if the mbar was found and is valid, false otherwise 230 */ 231 extern bool pcie_get_mbar(pcie_bdf_t bdf, 232 unsigned int bar_index, 233 struct pcie_bar *mbar); 234 235 /** 236 * @brief Probe the nth MMIO address assigned to an endpoint. 237 * @param bdf the PCI(e) endpoint 238 * @param index (0-based) index 239 * @param mbar Pointer to struct pcie_bar 240 * @return true if the mbar was found and is valid, false otherwise 241 * 242 * A PCI(e) endpoint has 0 or more memory-mapped regions. This function 243 * allows the caller to enumerate them by calling with index=0..n. 244 * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices 245 * are order-preserving with respect to the endpoint BARs: e.g., index 0 246 * will return the lowest-numbered memory BAR on the endpoint. 247 */ 248 extern bool pcie_probe_mbar(pcie_bdf_t bdf, 249 unsigned int index, 250 struct pcie_bar *mbar); 251 252 /** 253 * @brief Get the I/O BAR at a specific BAR index 254 * @param bdf the PCI(e) endpoint 255 * @param bar_index 0-based BAR index 256 * @param iobar Pointer to struct pcie_bar 257 * @return true if the I/O BAR was found and is valid, false otherwise 258 */ 259 extern bool pcie_get_iobar(pcie_bdf_t bdf, 260 unsigned int bar_index, 261 struct pcie_bar *iobar); 262 263 /** 264 * @brief Probe the nth I/O BAR address assigned to an endpoint. 265 * @param bdf the PCI(e) endpoint 266 * @param index (0-based) index 267 * @param iobar Pointer to struct pcie_bar 268 * @return true if the I/O BAR was found and is valid, false otherwise 269 * 270 * A PCI(e) endpoint has 0 or more I/O regions. This function 271 * allows the caller to enumerate them by calling with index=0..n. 272 * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices 273 * are order-preserving with respect to the endpoint BARs: e.g., index 0 274 * will return the lowest-numbered I/O BAR on the endpoint. 275 */ 276 extern bool pcie_probe_iobar(pcie_bdf_t bdf, 277 unsigned int index, 278 struct pcie_bar *iobar); 279 280 /** 281 * @brief Set or reset bits in the endpoint command/status register. 282 * 283 * @param bdf the PCI(e) endpoint 284 * @param bits the powerset of bits of interest 285 * @param on use true to set bits, false to reset them 286 */ 287 extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on); 288 289 #ifndef CONFIG_PCIE_CONTROLLER 290 /** 291 * @brief Allocate an IRQ for an endpoint. 292 * 293 * This function first checks the IRQ register and if it contains a valid 294 * value this is returned. If the register does not contain a valid value 295 * allocation of a new one is attempted. 296 * Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset. 297 * It is thus available where architecture tied dynamic IRQ allocation for 298 * PCIe device makes sense. 299 * 300 * @param bdf the PCI(e) endpoint 301 * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed. 302 */ 303 extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf); 304 #endif /* CONFIG_PCIE_CONTROLLER */ 305 306 /** 307 * @brief Return the IRQ assigned by the firmware/board to an endpoint. 308 * 309 * @param bdf the PCI(e) endpoint 310 * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if unknown. 311 */ 312 extern unsigned int pcie_get_irq(pcie_bdf_t bdf); 313 314 /** 315 * @brief Enable the PCI(e) endpoint to generate the specified IRQ. 316 * 317 * @param bdf the PCI(e) endpoint 318 * @param irq the IRQ to generate 319 * 320 * If MSI is enabled and the endpoint supports it, the endpoint will 321 * be configured to generate the specified IRQ via MSI. Otherwise, it 322 * is assumed that the IRQ has been routed by the boot firmware 323 * to the specified IRQ, and the IRQ is enabled (at the I/O APIC, or 324 * wherever appropriate). 325 */ 326 extern void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq); 327 328 /** 329 * @brief Find a PCI(e) capability in an endpoint's configuration space. 330 * 331 * @param bdf the PCI endpoint to examine 332 * @param cap_id the capability ID of interest 333 * @return the index of the configuration word, or 0 if no capability. 334 */ 335 extern uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id); 336 337 /** 338 * @brief Find an Extended PCI(e) capability in an endpoint's configuration space. 339 * 340 * @param bdf the PCI endpoint to examine 341 * @param cap_id the capability ID of interest 342 * @return the index of the configuration word, or 0 if no capability. 343 */ 344 extern uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id); 345 346 /** 347 * @brief Dynamically connect a PCIe endpoint IRQ to an ISR handler 348 * 349 * @param bdf the PCI endpoint to examine 350 * @param irq the IRQ to connect (see pcie_alloc_irq()) 351 * @param priority priority of the IRQ 352 * @param routine the ISR handler to connect to the IRQ 353 * @param parameter the parameter to provide to the handler 354 * @param flags IRQ connection flags 355 * @return true if connected, false otherwise 356 */ 357 extern bool pcie_connect_dynamic_irq(pcie_bdf_t bdf, 358 unsigned int irq, 359 unsigned int priority, 360 void (*routine)(const void *parameter), 361 const void *parameter, 362 uint32_t flags); 363 364 /** 365 * @brief Get the BDF for a given PCI host controller 366 * 367 * This macro is useful when the PCI host controller behind PCIE_BDF(0, 0, 0) 368 * indicates a multifunction device. In such a case each function of this 369 * endpoint is a potential host controller itself. 370 * 371 * @param n Bus number 372 * @return BDF value of the given host controller 373 */ 374 #define PCIE_HOST_CONTROLLER(n) PCIE_BDF(0, 0, n) 375 376 /* 377 * Configuration word 13 contains the head of the capabilities list. 378 */ 379 380 #define PCIE_CONF_CAPPTR 13U /* capabilities pointer */ 381 #define PCIE_CONF_CAPPTR_FIRST(w) (((w) >> 2) & 0x3FU) 382 383 /* 384 * The first word of every capability contains a capability identifier, 385 * and a link to the next capability (or 0) in configuration space. 386 */ 387 388 #define PCIE_CONF_CAP_ID(w) ((w) & 0xFFU) 389 #define PCIE_CONF_CAP_NEXT(w) (((w) >> 10) & 0x3FU) 390 391 /* 392 * The extended PCI Express capabilities lie at the end of the PCI configuration space 393 */ 394 395 #define PCIE_CONF_EXT_CAPPTR 64U 396 397 /* 398 * The first word of every capability contains an extended capability identifier, 399 * and a link to the next capability (or 0) in the extended configuration space. 400 */ 401 402 #define PCIE_CONF_EXT_CAP_ID(w) ((w) & 0xFFFFU) 403 #define PCIE_CONF_EXT_CAP_VER(w) (((w) >> 16) & 0xFU) 404 #define PCIE_CONF_EXT_CAP_NEXT(w) (((w) >> 20) & 0xFFFU) 405 406 /* 407 * Configuration word 0 aligns directly with pcie_id_t. 408 */ 409 410 #define PCIE_CONF_ID 0U 411 412 /* 413 * Configuration word 1 contains command and status bits. 414 */ 415 416 #define PCIE_CONF_CMDSTAT 1U /* command/status register */ 417 418 #define PCIE_CONF_CMDSTAT_IO 0x00000001U /* I/O access enable */ 419 #define PCIE_CONF_CMDSTAT_MEM 0x00000002U /* mem access enable */ 420 #define PCIE_CONF_CMDSTAT_MASTER 0x00000004U /* bus master enable */ 421 #define PCIE_CONF_CMDSTAT_INTERRUPT 0x00080000U /* interrupt status */ 422 #define PCIE_CONF_CMDSTAT_CAPS 0x00100000U /* capabilities list */ 423 424 /* 425 * Configuration word 2 has additional function identification that 426 * we only care about for debug output (PCIe shell commands). 427 */ 428 429 #define PCIE_CONF_CLASSREV 2U /* class/revision register */ 430 431 #define PCIE_CONF_CLASSREV_CLASS(w) (((w) >> 24) & 0xFFU) 432 #define PCIE_CONF_CLASSREV_SUBCLASS(w) (((w) >> 16) & 0xFFU) 433 #define PCIE_CONF_CLASSREV_PROGIF(w) (((w) >> 8) & 0xFFU) 434 #define PCIE_CONF_CLASSREV_REV(w) ((w) & 0xFFU) 435 436 /* 437 * The only part of configuration word 3 that is of interest to us is 438 * the header type, as we use it to distinguish functional endpoints 439 * from bridges (which are, for our purposes, transparent). 440 */ 441 442 #define PCIE_CONF_TYPE 3U 443 444 #define PCIE_CONF_MULTIFUNCTION(w) (((w) & 0x00800000U) != 0U) 445 #define PCIE_CONF_TYPE_BRIDGE(w) (((w) & 0x007F0000U) != 0U) 446 #define PCIE_CONF_TYPE_GET(w) (((w) >> 16) & 0x7F) 447 448 #define PCIE_CONF_TYPE_STANDARD 0x0U 449 #define PCIE_CONF_TYPE_PCI_BRIDGE 0x1U 450 #define PCIE_CONF_TYPE_CARDBUS_BRIDGE 0x2U 451 452 /* 453 * Words 4-9 are BARs are I/O or memory decoders. Memory decoders may 454 * be 64-bit decoders, in which case the next configuration word holds 455 * the high-order bits (and is, thus, not a BAR itself). 456 */ 457 458 #define PCIE_CONF_BAR0 4U 459 #define PCIE_CONF_BAR1 5U 460 #define PCIE_CONF_BAR2 6U 461 #define PCIE_CONF_BAR3 7U 462 #define PCIE_CONF_BAR4 8U 463 #define PCIE_CONF_BAR5 9U 464 465 #define PCIE_CONF_BAR_IO(w) (((w) & 0x00000001U) == 0x00000001U) 466 #define PCIE_CONF_BAR_MEM(w) (((w) & 0x00000001U) != 0x00000001U) 467 #define PCIE_CONF_BAR_64(w) (((w) & 0x00000006U) == 0x00000004U) 468 #define PCIE_CONF_BAR_ADDR(w) ((w) & ~0xfUL) 469 #define PCIE_CONF_BAR_IO_ADDR(w) ((w) & ~0x3UL) 470 #define PCIE_CONF_BAR_FLAGS(w) ((w) & 0xfUL) 471 #define PCIE_CONF_BAR_NONE 0U 472 473 #define PCIE_CONF_BAR_INVAL 0xFFFFFFF0U 474 #define PCIE_CONF_BAR_INVAL64 0xFFFFFFFFFFFFFFF0UL 475 476 #define PCIE_CONF_BAR_INVAL_FLAGS(w) \ 477 ((((w) & 0x00000006U) == 0x00000006U) || \ 478 (((w) & 0x00000006U) == 0x00000002U)) 479 480 /* 481 * Type 1 Header has files related to bus management 482 */ 483 #define PCIE_BUS_NUMBER 6U 484 485 #define PCIE_BUS_PRIMARY_NUMBER(w) ((w) & 0xffUL) 486 #define PCIE_BUS_SECONDARY_NUMBER(w) (((w) >> 8) & 0xffUL) 487 #define PCIE_BUS_SUBORDINATE_NUMBER(w) (((w) >> 16) & 0xffUL) 488 #define PCIE_SECONDARY_LATENCY_TIMER(w) (((w) >> 24) & 0xffUL) 489 490 #define PCIE_BUS_NUMBER_VAL(prim, sec, sub, lat) \ 491 (((prim) & 0xffUL) | \ 492 (((sec) & 0xffUL) << 8) | \ 493 (((sub) & 0xffUL) << 16) | \ 494 (((lat) & 0xffUL) << 24)) 495 496 /* 497 * Type 1 words 7 to 12 setups Bridge Memory base and limits 498 */ 499 #define PCIE_IO_SEC_STATUS 7U 500 501 #define PCIE_IO_BASE(w) ((w) & 0xffUL) 502 #define PCIE_IO_LIMIT(w) (((w) >> 8) & 0xffUL) 503 #define PCIE_SEC_STATUS(w) (((w) >> 16) & 0xffffUL) 504 505 #define PCIE_IO_SEC_STATUS_VAL(iob, iol, sec_status) \ 506 (((iob) & 0xffUL) | \ 507 (((iol) & 0xffUL) << 8) | \ 508 (((sec_status) & 0xffffUL) << 16)) 509 510 #define PCIE_MEM_BASE_LIMIT 8U 511 512 #define PCIE_MEM_BASE(w) ((w) & 0xffffUL) 513 #define PCIE_MEM_LIMIT(w) (((w) >> 16) & 0xffffUL) 514 515 #define PCIE_MEM_BASE_LIMIT_VAL(memb, meml) \ 516 (((memb) & 0xffffUL) | \ 517 (((meml) & 0xffffUL) << 16)) 518 519 #define PCIE_PREFETCH_BASE_LIMIT 9U 520 521 #define PCIE_PREFETCH_BASE(w) ((w) & 0xffffUL) 522 #define PCIE_PREFETCH_LIMIT(w) (((w) >> 16) & 0xffffUL) 523 524 #define PCIE_PREFETCH_BASE_LIMIT_VAL(pmemb, pmeml) \ 525 (((pmemb) & 0xffffUL) | \ 526 (((pmeml) & 0xffffUL) << 16)) 527 528 #define PCIE_PREFETCH_BASE_UPPER 10U 529 530 #define PCIE_PREFETCH_LIMIT_UPPER 11U 531 532 #define PCIE_IO_BASE_LIMIT_UPPER 12U 533 534 #define PCIE_IO_BASE_UPPER(w) ((w) & 0xffffUL) 535 #define PCIE_IO_LIMIT_UPPER(w) (((w) >> 16) & 0xffffUL) 536 537 #define PCIE_IO_BASE_LIMIT_UPPER_VAL(iobu, iolu) \ 538 (((iobu) & 0xffffUL) | \ 539 (((iolu) & 0xffffUL) << 16)) 540 541 /* 542 * Word 15 contains information related to interrupts. 543 * 544 * We're only interested in the low byte, which is [supposed to be] set by 545 * the firmware to indicate which wire IRQ the device interrupt is routed to. 546 */ 547 548 #define PCIE_CONF_INTR 15U 549 550 #define PCIE_CONF_INTR_IRQ(w) ((w) & 0xFFU) 551 #define PCIE_CONF_INTR_IRQ_NONE 0xFFU /* no interrupt routed */ 552 553 #define PCIE_MAX_BUS (0xFFFFFFFFU & PCIE_BDF_BUS_MASK) 554 #define PCIE_MAX_DEV (0xFFFFFFFFU & PCIE_BDF_DEV_MASK) 555 #define PCIE_MAX_FUNC (0xFFFFFFFFU & PCIE_BDF_FUNC_MASK) 556 557 /** 558 * @brief Initialize an interrupt handler for a PCIe endpoint IRQ 559 * 560 * This routine is only meant to be used by drivers using PCIe bus and having 561 * fixed or MSI based IRQ (so no runtime detection of the IRQ). In case 562 * of runtime detection see pcie_connect_dynamic_irq() 563 * 564 * @param bdf_p PCIe endpoint BDF 565 * @param irq_p IRQ line number. 566 * @param priority_p Interrupt priority. 567 * @param isr_p Address of interrupt service routine. 568 * @param isr_param_p Parameter passed to interrupt service routine. 569 * @param flags_p Architecture-specific IRQ configuration flags.. 570 */ 571 #define PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p, \ 572 isr_p, isr_param_p, flags_p) \ 573 ARCH_PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p, \ 574 isr_p, isr_param_p, flags_p) 575 576 #ifdef __cplusplus 577 } 578 #endif 579 580 /** 581 * @} 582 */ 583 584 #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ */ 585