1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-11-07 GuEe-GUI first version
9 */
10
11 #include <rtthread.h>
12
13 #define DBG_TAG "pci.irq"
14 #define DBG_LVL DBG_INFO
15 #include <rtdbg.h>
16
17 #include <drivers/pci.h>
18
rt_pci_assign_irq(struct rt_pci_device * pdev)19 void rt_pci_assign_irq(struct rt_pci_device *pdev)
20 {
21 int irq = 0;
22 rt_uint8_t pin, slot = -1;
23 struct rt_pci_host_bridge *host_bridge = rt_pci_find_host_bridge(pdev->bus);
24
25 if (!host_bridge->irq_map)
26 {
27 LOG_D("PCI-Device<%s> runtime IRQ mapping not provided by platform",
28 rt_dm_dev_get_name(&pdev->parent));
29
30 return;
31 }
32
33 /* Must try the swizzle when interrupt line passes through a P2P bridge */
34 rt_pci_read_config_u8(pdev, PCIR_INTPIN, &pin);
35
36 if (pin > RT_PCI_INTX_PIN_MAX)
37 {
38 pin = 1;
39 }
40
41 if (pin)
42 {
43 if (host_bridge->irq_slot)
44 {
45 slot = host_bridge->irq_slot(pdev, &pin);
46 }
47
48 /* Map IRQ */
49 if ((irq = host_bridge->irq_map(pdev, slot, pin)) == -1)
50 {
51 irq = 0;
52 }
53 }
54 pdev->irq = irq;
55
56 LOG_D("PCI-Device<%s> assign IRQ: got %d", rt_dm_dev_get_name(&pdev->parent), pdev->irq);
57
58 /* Save IRQ */
59 rt_pci_write_config_u8(pdev, PCIR_INTLINE, irq);
60 }
61