drivers/pcie: Use the generic arch-interface for allocating IRQs
PCIE now uses the new interface. And pcie_alloc_irq() is only made available when CONFIG_PCIE_CONTROLLER is unset. So only for x86 atm. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
88bac5d0b5
commit
c1bc5db795
|
@ -216,87 +216,34 @@ bool pcie_probe_mbar(pcie_bdf_t bdf,
|
|||
return pcie_get_mbar(bdf, reg - PCIE_CONF_BAR0, mbar);
|
||||
}
|
||||
|
||||
/* The first bit is used to indicate whether the list of reserved interrupts
|
||||
* have been initialized based on content stored in the irq_alloc linker
|
||||
* section in ROM.
|
||||
*/
|
||||
#define IRQ_LIST_INITIALIZED 0
|
||||
|
||||
#ifndef CONFIG_MAX_IRQ_LINES
|
||||
#warning TOFIX for non-x86
|
||||
#define CONFIG_MAX_IRQ_LINES 0
|
||||
#endif
|
||||
|
||||
static ATOMIC_DEFINE(irq_reserved, CONFIG_MAX_IRQ_LINES);
|
||||
|
||||
static unsigned int irq_alloc(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(irq_reserved); i++) {
|
||||
unsigned int fz, irq;
|
||||
|
||||
while ((fz = find_lsb_set(~atomic_get(&irq_reserved[i])))) {
|
||||
irq = (fz - 1) + (i * sizeof(atomic_val_t) * 8);
|
||||
if (irq >= CONFIG_MAX_IRQ_LINES) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!atomic_test_and_set_bit(irq_reserved, irq)) {
|
||||
return irq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PCIE_CONF_INTR_IRQ_NONE;
|
||||
}
|
||||
|
||||
static bool irq_is_reserved(unsigned int irq)
|
||||
{
|
||||
return atomic_test_bit(irq_reserved, irq);
|
||||
}
|
||||
|
||||
static void irq_init(void)
|
||||
{
|
||||
extern uint8_t __irq_alloc_start[];
|
||||
extern uint8_t __irq_alloc_end[];
|
||||
const uint8_t *irq;
|
||||
|
||||
for (irq = __irq_alloc_start; irq < __irq_alloc_end; irq++) {
|
||||
__ASSERT_NO_MSG(*irq < CONFIG_MAX_IRQ_LINES);
|
||||
atomic_set_bit(irq_reserved, *irq);
|
||||
}
|
||||
}
|
||||
#ifndef CONFIG_PCIE_CONTROLLER
|
||||
|
||||
unsigned int pcie_alloc_irq(pcie_bdf_t bdf)
|
||||
{
|
||||
unsigned int irq;
|
||||
uint32_t data;
|
||||
|
||||
if (!atomic_test_and_set_bit(irq_reserved, IRQ_LIST_INITIALIZED)) {
|
||||
irq_init();
|
||||
}
|
||||
|
||||
data = pcie_conf_read(bdf, PCIE_CONF_INTR);
|
||||
irq = PCIE_CONF_INTR_IRQ(data);
|
||||
|
||||
if (irq == PCIE_CONF_INTR_IRQ_NONE || irq >= CONFIG_MAX_IRQ_LINES ||
|
||||
irq_is_reserved(irq)) {
|
||||
|
||||
irq = irq_alloc();
|
||||
if (irq == PCIE_CONF_INTR_IRQ_NONE) {
|
||||
return irq;
|
||||
if (irq == PCIE_CONF_INTR_IRQ_NONE ||
|
||||
irq >= CONFIG_MAX_IRQ_LINES ||
|
||||
arch_irq_is_used(irq)) {
|
||||
irq = arch_irq_allocate();
|
||||
if (irq == UINT_MAX) {
|
||||
return PCIE_CONF_INTR_IRQ_NONE;
|
||||
}
|
||||
|
||||
data &= ~0xffU;
|
||||
data |= irq;
|
||||
pcie_conf_write(bdf, PCIE_CONF_INTR, data);
|
||||
} else {
|
||||
atomic_set_bit(irq_reserved, irq);
|
||||
arch_irq_set_used(irq);
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
#endif /* CONFIG_PCIE_CONTROLLER */
|
||||
|
||||
unsigned int pcie_get_irq(pcie_bdf_t bdf)
|
||||
{
|
||||
|
|
|
@ -124,17 +124,22 @@ extern bool pcie_probe_mbar(pcie_bdf_t bdf,
|
|||
*/
|
||||
extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on);
|
||||
|
||||
#ifndef CONFIG_PCIE_CONTROLLER
|
||||
/**
|
||||
* @brief Allocate an IRQ for an endpoint.
|
||||
*
|
||||
* This function first checks the IRQ register and if it contains a valid
|
||||
* value this is returned. If the register does not contain a valid value
|
||||
* allocation of a new one is attempted.
|
||||
* Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset.
|
||||
* It is thus available where architecture tied dynamic IRQ allocation for
|
||||
* PCIe device makes sense.
|
||||
*
|
||||
* @param bdf the PCI(e) endpoint
|
||||
* @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed.
|
||||
*/
|
||||
extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf);
|
||||
#endif /* CONFIG_PCIE_CONTROLLER */
|
||||
|
||||
/**
|
||||
* @brief Return the IRQ assigned by the firmware/board to an endpoint.
|
||||
|
|
Loading…
Reference in a new issue