mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
xen: events: add xen_allocate_irq_{dynamic, gsi} and xen_free_irq
This is neater than open-coded calls to irq_alloc_desc_at and irq_free_desc. No intended behavioural change. Note that we previously were not checking the return value of irq_alloc_desc_at which would be failing for GSI<NR_IRQS_LEGACY because the core architecture code has already allocated those for us. Hence the additional check against NR_IRQS_LEGACY in xen_allocate_irq_gsi. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Cc: Jeremy Fitzhardinge <jeremy@goop.org>
This commit is contained in:
parent
cbf6aa89fc
commit
c9df1ce585
@ -387,7 +387,7 @@ static int get_nr_hw_irqs(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int find_unbound_irq(void)
|
||||
static int xen_allocate_irq_dynamic(void)
|
||||
{
|
||||
struct irq_data *data;
|
||||
int irq, res;
|
||||
@ -436,6 +436,30 @@ static bool identity_mapped_irq(unsigned irq)
|
||||
return irq < get_nr_hw_irqs();
|
||||
}
|
||||
|
||||
static int xen_allocate_irq_gsi(unsigned gsi)
|
||||
{
|
||||
int irq;
|
||||
|
||||
if (!identity_mapped_irq(gsi) &&
|
||||
(xen_initial_domain() || !xen_pv_domain()))
|
||||
return xen_allocate_irq_dynamic();
|
||||
|
||||
/* Legacy IRQ descriptors are already allocated by the arch. */
|
||||
if (gsi < NR_IRQS_LEGACY)
|
||||
return gsi;
|
||||
|
||||
irq = irq_alloc_desc_at(gsi, -1);
|
||||
if (irq < 0)
|
||||
panic("Unable to allocate to IRQ%d (%d)\n", gsi, irq);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
static void xen_free_irq(unsigned irq)
|
||||
{
|
||||
irq_free_desc(irq);
|
||||
}
|
||||
|
||||
static void pirq_unmask_notify(int irq)
|
||||
{
|
||||
struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) };
|
||||
@ -621,14 +645,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
|
||||
goto out; /* XXX need refcount? */
|
||||
}
|
||||
|
||||
/* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore
|
||||
* we are using the !xen_initial_domain() to drop in the function.*/
|
||||
if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
|
||||
xen_pv_domain())) {
|
||||
irq = gsi;
|
||||
irq_alloc_desc_at(irq, -1);
|
||||
} else
|
||||
irq = find_unbound_irq();
|
||||
irq = xen_allocate_irq_gsi(gsi);
|
||||
|
||||
set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
|
||||
handle_level_irq, name);
|
||||
@ -641,7 +658,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
|
||||
* this in the priv domain. */
|
||||
if (xen_initial_domain() &&
|
||||
HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
|
||||
irq_free_desc(irq);
|
||||
xen_free_irq(irq);
|
||||
irq = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
@ -682,7 +699,7 @@ void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc)
|
||||
spin_lock(&irq_mapping_update_lock);
|
||||
|
||||
if (alloc & XEN_ALLOC_IRQ) {
|
||||
*irq = find_unbound_irq();
|
||||
*irq = xen_allocate_irq_dynamic();
|
||||
if (*irq == -1)
|
||||
goto out;
|
||||
}
|
||||
@ -732,7 +749,7 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type)
|
||||
|
||||
spin_lock(&irq_mapping_update_lock);
|
||||
|
||||
irq = find_unbound_irq();
|
||||
irq = xen_allocate_irq_dynamic();
|
||||
|
||||
if (irq == -1)
|
||||
goto out;
|
||||
@ -741,7 +758,7 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type)
|
||||
if (rc) {
|
||||
printk(KERN_WARNING "xen map irq failed %d\n", rc);
|
||||
|
||||
irq_free_desc(irq);
|
||||
xen_free_irq(irq);
|
||||
|
||||
irq = -1;
|
||||
goto out;
|
||||
@ -783,7 +800,7 @@ int xen_destroy_irq(int irq)
|
||||
}
|
||||
irq_info[irq] = mk_unbound_info();
|
||||
|
||||
irq_free_desc(irq);
|
||||
xen_free_irq(irq);
|
||||
|
||||
out:
|
||||
spin_unlock(&irq_mapping_update_lock);
|
||||
@ -814,7 +831,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
|
||||
irq = evtchn_to_irq[evtchn];
|
||||
|
||||
if (irq == -1) {
|
||||
irq = find_unbound_irq();
|
||||
irq = xen_allocate_irq_dynamic();
|
||||
|
||||
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
|
||||
handle_fasteoi_irq, "event");
|
||||
@ -839,7 +856,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
|
||||
irq = per_cpu(ipi_to_irq, cpu)[ipi];
|
||||
|
||||
if (irq == -1) {
|
||||
irq = find_unbound_irq();
|
||||
irq = xen_allocate_irq_dynamic();
|
||||
if (irq < 0)
|
||||
goto out;
|
||||
|
||||
@ -875,7 +892,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
|
||||
irq = per_cpu(virq_to_irq, cpu)[virq];
|
||||
|
||||
if (irq == -1) {
|
||||
irq = find_unbound_irq();
|
||||
irq = xen_allocate_irq_dynamic();
|
||||
|
||||
set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
|
||||
handle_percpu_irq, "virq");
|
||||
@ -934,7 +951,7 @@ static void unbind_from_irq(unsigned int irq)
|
||||
if (irq_info[irq].type != IRQT_UNBOUND) {
|
||||
irq_info[irq] = mk_unbound_info();
|
||||
|
||||
irq_free_desc(irq);
|
||||
xen_free_irq(irq);
|
||||
}
|
||||
|
||||
spin_unlock(&irq_mapping_update_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user