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