From patchwork Tue May 27 08:24:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 4247691 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 88FF2BF90B for ; Tue, 27 May 2014 08:22:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A2A0420272 for ; Tue, 27 May 2014 08:22:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AE66D2026F for ; Tue, 27 May 2014 08:22:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752911AbaE0IWq (ORCPT ); Tue, 27 May 2014 04:22:46 -0400 Received: from mga11.intel.com ([192.55.52.93]:45445 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752898AbaE0IWn (ORCPT ); Tue, 27 May 2014 04:22:43 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 27 May 2014 01:22:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.98,917,1392192000"; d="scan'208";a="545380807" Received: from gerry-dev.bj.intel.com ([10.238.158.74]) by fmsmga002.fm.intel.com with ESMTP; 27 May 2014 01:22:32 -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: [RFC Patch V1 4/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-removal Date: Tue, 27 May 2014 16:24:37 +0800 Message-Id: <1401179077-2020-5-git-send-email-jiang.liu@linux.intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1401179077-2020-1-git-send-email-jiang.liu@linux.intel.com> References: <1401179077-2020-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 Implement acpi_unregister_ioapic() to support ACPI based IOAPIC hot-removal. An IOAPIC could only be removed when all its pins are unused. Signed-off-by: Jiang Liu --- arch/x86/include/asm/io_apic.h | 1 + arch/x86/kernel/acpi/boot.c | 13 ++++++++---- arch/x86/kernel/apic/io_apic.c | 46 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 64379c285435..256ec8d9050c 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -183,6 +183,7 @@ extern int mp_map_gsi_to_irq(u32 gsi, unsigned int flags); extern void mp_unmap_irq(int irq); extern int mp_register_ioapic(int id, u32 address, u32 gsi_base, ioapic_create_domain_fn cb, void *arg); +extern int mp_unregister_ioapic(u32 gsi_base); extern struct irq_domain *mp_irqdomain_create(int ioapic, struct device_node *np, const struct irq_domain_ops *ops); extern int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq, diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d807e16f8fec..c17cc0510040 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -672,15 +672,20 @@ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) return ret; } - EXPORT_SYMBOL(acpi_register_ioapic); int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) { - /* TBD */ - return -EINVAL; -} + int ret = -ENOSYS; + +#ifdef CONFIG_X86_IO_APIC + down_write(&acpi_ioapic_rwsem); + ret = mp_unregister_ioapic(gsi_base); + up_write(&acpi_ioapic_rwsem); +#endif + return ret; +} EXPORT_SYMBOL(acpi_unregister_ioapic); static int __init acpi_parse_sbf(struct acpi_table_header *table) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 4bddff760ff4..4343247d15b1 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2949,6 +2949,18 @@ static int ioapic_create_irqdomain(int idx) return 0; } +static void ioapic_destroy_irqdomain(int idx) +{ + if (ioapics[idx].irqdomain) { + irq_domain_remove(ioapics[idx].irqdomain); + ioapics[idx].irqdomain = NULL; + } + if (ioapics[idx].pin_info) { + kfree(ioapics[idx].pin_info); + ioapics[idx].pin_info = NULL; + } +} + static void ioapic_create_irqdomains(void) { int idx; @@ -3904,6 +3916,40 @@ int mp_register_ioapic(int id, u32 address, u32 gsi_base, return 0; } +int mp_unregister_ioapic(u32 gsi_base) +{ + int ioapic, pin; + int found = 0; + struct mp_pin_info *pin_info; + + for_each_ioapic(ioapic) + if (ioapics[ioapic].gsi_config.gsi_base == gsi_base) { + found = 1; + break; + } + if (!found) { + pr_warn("can't find IOAPIC for GSI %d\n", gsi_base); + return -ENODEV; + } + + for_each_pin(ioapic, pin) { + pin_info = mp_pin_info(ioapic, pin); + if (pin_info->count) { + pr_warn("pin%d on IOAPIC%d is still in use.\n", + pin, ioapic); + return -EBUSY; + } + } + + /* Mark entry not present */ + ioapics[ioapic].nr_registers = 0; + ioapic_destroy_irqdomain(ioapic); + clear_fixmap(FIX_IO_APIC_BASE_0 + ioapic); + memset(&ioapics[ioapic], 0, sizeof(ioapics[ioapic])); + + return 0; +} + struct irq_domain *mp_irqdomain_create(int ioapic, struct device_node *np, const struct irq_domain_ops *ops) {