From patchwork Mon May 19 16:23:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 4203361 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6BD6F9F32B for ; Mon, 19 May 2014 16:24:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 322D2202FE for ; Mon, 19 May 2014 16:24:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1918420256 for ; Mon, 19 May 2014 16:24:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932514AbaESQXy (ORCPT ); Mon, 19 May 2014 12:23:54 -0400 Received: from mga01.intel.com ([192.55.52.88]:2939 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932301AbaESQXu (ORCPT ); Mon, 19 May 2014 12:23:50 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 19 May 2014 09:23:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.98,868,1392192000"; d="scan'208";a="534296216" Received: from gerry-dev.bj.intel.com ([10.238.158.74]) by fmsmga001.fm.intel.com with ESMTP; 19 May 2014 09:23:37 -0700 From: Jiang Liu To: Benjamin Herrenschmidt , Thomas Gleixner , Grant Likely , Ingo Molnar , "H. Peter Anvin" , "Rafael J. Wysocki" , Bjorn Helgaas , Randy Dunlap , Yinghai Lu , x86@kernel.org, Len Brown , Pavel Machek , Jiang Liu Cc: Konrad Rzeszutek Wilk , Andrew Morton , Tony Luck , Joerg Roedel , Paul Gortmaker , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, Ingo Molnar , linux-pm@vger.kernel.org Subject: [Patch Part1 V2 17/29] x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ number Date: Tue, 20 May 2014 00:23:01 +0800 Message-Id: <1400516594-11544-18-git-send-email-jiang.liu@linux.intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1400516594-11544-1-git-send-email-jiang.liu@linux.intel.com> References: <1400516594-11544-1-git-send-email-jiang.liu@linux.intel.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently ACPI and ioapic both implement algorithms to map (ioapic, pin) to IRQ number. So consolidate the common part into one place, which is also preparing for irqdomain support. It introduces mp_map_pin_to_irq(), which will be used to allocate IRQ number IOAPIC pins when irqdomain is enabled. Also rename gsi_to_irq() to map_gsi_to_irq(), later we will introduce unmap_gsi_to_irq() when enabling IOAPIC hotplug. Signed-off-by: Jiang Liu --- arch/x86/include/asm/io_apic.h | 2 ++ arch/x86/kernel/acpi/boot.c | 52 +++++++++++++++++++++------------------- arch/x86/kernel/apic/io_apic.c | 30 +++++++++++++---------- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index de3d8b04cf64..f4fd0be26cec 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -171,6 +171,7 @@ extern u32 gsi_top; extern int mp_find_ioapic(u32 gsi); extern int mp_find_ioapic_pin(int ioapic, u32 gsi); +extern int mp_map_pin_to_irq(int ioapic, int pin); extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); extern void __init pre_init_apic_IRQ0(void); @@ -212,6 +213,7 @@ extern void io_apic_eoi(unsigned int apic, unsigned int vector); static inline void ioapic_insert_resources(void) { } #define gsi_top (NR_IRQS_LEGACY) static inline int mp_find_ioapic(u32 gsi) { return 0; } +static inline int mp_map_pin_to_irq(int ioapic, int pin) { return -1; } struct io_apic_irq_attr; static inline int io_apic_set_pci_routing(struct device *dev, int irq, diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index dccf9e88db30..6eae9a7231c4 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -99,27 +99,22 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = { #define ACPI_INVALID_GSI INT_MIN -static unsigned int gsi_to_irq(unsigned int gsi) +static int map_gsi_to_irq(unsigned int gsi) { - unsigned int irq = gsi + NR_IRQS_LEGACY; - unsigned int i; + int i, ioapic, pin; - for (i = 0; i < NR_IRQS_LEGACY; i++) { - if (isa_irq_to_gsi[i] == gsi) { + for (i = 0; i < NR_IRQS_LEGACY; i++) + if (isa_irq_to_gsi[i] == gsi) return i; - } - } - /* Provide an identity mapping of gsi == irq - * except on truly weird platforms that have - * non isa irqs in the first 16 gsis. - */ - if (gsi >= NR_IRQS_LEGACY) - irq = gsi; - else - irq = gsi_top + gsi; + ioapic = mp_find_ioapic(gsi); + if (ioapic >= 0) { + pin = mp_find_ioapic_pin(ioapic, gsi); + return mp_map_pin_to_irq(ioapic, pin); + } - return irq; + pr_err("Failed to map GSI%d to IRQ number.\n", gsi); + return -1; } /* @@ -493,16 +488,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) outb(new >> 8, 0x4d1); } -int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) +int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { - *irq = gsi_to_irq(gsi); + int irq = map_gsi_to_irq(gsi); + if (irq >= 0) { #ifdef CONFIG_X86_IO_APIC - if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) - setup_IO_APIC_irq_extra(gsi); + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) + setup_IO_APIC_irq_extra(gsi); #endif + *irqp = irq; + return 0; + } - return 0; + return -1; } EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); @@ -556,11 +555,11 @@ int (*acpi_suspend_lowlevel)(void); */ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { - unsigned int plat_gsi = gsi; + unsigned int plat_gsi; plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity); if (plat_gsi != ACPI_INVALID_GSI) - return gsi_to_irq(plat_gsi); + return map_gsi_to_irq(plat_gsi); return -1; } @@ -1029,6 +1028,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger, static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { + int irq; int ioapic; int ioapic_pin; struct io_apic_irq_attr irq_attr; @@ -1041,6 +1041,10 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, if (acpi_gbl_FADT.sci_interrupt == gsi) return gsi; + irq = map_gsi_to_irq(gsi); + if (irq < 0) + return ACPI_INVALID_GSI; + ioapic = mp_find_ioapic(gsi); if (ioapic < 0) { printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); @@ -1062,7 +1066,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, polarity == ACPI_ACTIVE_HIGH ? 0 : 1); - ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); + ret = io_apic_set_pci_routing(dev, irq, &irq_attr); if (ret < 0) gsi = ACPI_INVALID_GSI; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 3b6e29d29903..2d776f69f4e8 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -963,11 +963,22 @@ static int irq_trigger(int idx) return trigger; } +int mp_map_pin_to_irq(int apic, int pin) +{ + struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic); + u32 gsi = gsi_cfg->gsi_base + pin; + + /* + * Provide an identity mapping of gsi == irq except on truly weird + * platforms that have non isa irqs in the first 16 gsis. + */ + return gsi >= NR_IRQS_LEGACY ? gsi : gsi_top + gsi; +} + static int pin_2_irq(int idx, int apic, int pin) { int irq; int bus = mp_irqs[idx].srcbus; - struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic); /* * Debugging check, we are in big trouble if this message pops up! @@ -975,17 +986,6 @@ static int pin_2_irq(int idx, int apic, int pin) if (mp_irqs[idx].dstirq != pin) pr_err("broken BIOS or MPTABLE parser, ayiee!!\n"); - if (test_bit(bus, mp_bus_not_pci)) { - irq = mp_irqs[idx].srcbusirq; - } else { - u32 gsi = gsi_cfg->gsi_base + pin; - - if (gsi >= NR_IRQS_LEGACY) - irq = gsi; - else - irq = gsi_top + gsi; - } - #ifdef CONFIG_X86_32 /* * PCI IRQ command line redirection. Yes, limits are hardcoded. @@ -1000,11 +1000,17 @@ static int pin_2_irq(int idx, int apic, int pin) apic_printk(APIC_VERBOSE, KERN_DEBUG "using PIRQ%d -> IRQ %d\n", pin-16, irq); + return irq; } } } #endif + if (test_bit(bus, mp_bus_not_pci)) + irq = mp_irqs[idx].srcbusirq; + else + irq = mp_map_pin_to_irq(apic, pin); + return irq; }