Skip to content

Commit

Permalink
x86/irq: Introduce helper functions to support hierarchical irqdomain…
Browse files Browse the repository at this point in the history
…s for IOAPIC

Introduce several helper functions, which will be used to enable
hierarchical irqdomain for IOAPIC.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Tested-by: Joerg Roedel <jroedel@suse.de>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: David Cohen <david.a.cohen@linux.intel.com>
Cc: Sander Eikelenboom <linux@eikelenboom.it>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dimitri Sivanich <sivanich@sgi.com>
Cc: Grant Likely <grant.likely@linaro.org>
Link: http://lkml.kernel.org/r/1428905519-23704-37-git-send-email-jiang.liu@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Jiang Liu authored and Thomas Gleixner committed Apr 24, 2015
1 parent a44174e commit 96ed44b
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct mp_chip_data {
struct IO_APIC_route_entry entry;
int trigger;
int polarity;
u32 count;
bool isa_irq;
};

Expand Down Expand Up @@ -945,6 +946,46 @@ void ioapic_set_alloc_attr(struct irq_alloc_info *info, int node,
info->ioapic_valid = 1;
}

#ifndef CONFIG_ACPI
int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
#endif

static void ioapic_copy_alloc_attr(struct irq_alloc_info *dst,
struct irq_alloc_info *src,
u32 gsi, int ioapic_idx, int pin)
{
int trigger, polarity;

copy_irq_alloc_info(dst, src);
dst->type = X86_IRQ_ALLOC_TYPE_IOAPIC;
dst->ioapic_id = mpc_ioapic_id(ioapic_idx);
dst->ioapic_pin = pin;
dst->ioapic_valid = 1;
if (src && src->ioapic_valid) {
dst->ioapic_node = src->ioapic_node;
dst->ioapic_trigger = src->ioapic_trigger;
dst->ioapic_polarity = src->ioapic_polarity;
} else {
dst->ioapic_node = NUMA_NO_NODE;
if (acpi_get_override_irq(gsi, &trigger, &polarity) >= 0) {
dst->ioapic_trigger = trigger;
dst->ioapic_polarity = polarity;
} else {
/*
* PCI interrupts are always polarity one level
* triggered.
*/
dst->ioapic_trigger = 1;
dst->ioapic_polarity = 1;
}
}
}

static int ioapic_alloc_attr_node(struct irq_alloc_info *info)
{
return (info && info->ioapic_valid) ? info->ioapic_node : NUMA_NO_NODE;
}

static void mp_register_handler(unsigned int irq, unsigned long trigger)
{
irq_flow_handler_t hdl;
Expand All @@ -962,6 +1003,26 @@ static void mp_register_handler(unsigned int irq, unsigned long trigger)
__irq_set_handler(irq, hdl, 0, fasteoi ? "fasteoi" : "edge");
}

static bool mp_check_pin_attr(int irq, struct irq_alloc_info *info)
{
struct mp_chip_data *data = irq_get_chip_data(irq);

/*
* setup_IO_APIC_irqs() programs all legacy IRQs with default trigger
* and polarity attirbutes. So allow the first user to reprogram the
* pin with real trigger and polarity attributes.
*/
if (irq < nr_legacy_irqs() && data->count == 1) {
if (info->ioapic_trigger != data->trigger)
mp_register_handler(irq, data->trigger);
data->entry.trigger = data->trigger = info->ioapic_trigger;
data->entry.polarity = data->polarity = info->ioapic_polarity;
}

return data->trigger == info->ioapic_trigger &&
data->polarity == info->ioapic_polarity;
}

static int alloc_irq_from_domain(struct irq_domain *domain, u32 gsi, int pin,
struct irq_alloc_info *info)
{
Expand Down

0 comments on commit 96ed44b

Please sign in to comment.