From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kenji Kaneshige Subject: [PATCH] PCI IRQ resource deallocation support [2/3] Date: Tue, 21 Sep 2004 17:52:43 +0900 Sender: acpi-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Message-ID: <414FEBDB.2050201@soft.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Return-path: Errors-To: acpi-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , List-Archive: To: akpm-3NddpPZAyC0@public.gmane.org, greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org, len.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org, tony.luck-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org, linux-ia64-u79uwXL29TY76Z2rM5mHXA@public.gmane.org List-Id: linux-acpi@vger.kernel.org This patch is ACPI portion of IRQ deallocation. This patch defines the following new interface. The implementation of this interface depends on each platform. o void acpi_unregister_gsi(int irq) This is a opposite portion of acpi_register_gsi(). This has a responsibility for deallocating IRQ resources associated with the specified linux IRQ number. We need to consider the case of shared interrupt. In the case of shared interrupt, acpi_register_gsi() is called multiple times for one gsi. That is, registrations and unregistrations can be nested. This function undoes the effect of one call to acpi_register_gsi(). If this matches the last registration, IRQ resources associated with the specified linux IRQ number are freed. This patch also adds the following new function. o void acpi_pci_irq_disable (struct pci_dev *dev) This function is a opposite portion of acpi_pci_enable_irq(). It clears the device's linux IRQ number and calls acpi_unregister_gsi() to deallocate IRQ resources. Signed-off-by: Kenji Kaneshige --- linux-2.6.9-rc2-mm1-kanesige/arch/i386/kernel/acpi/boot.c | 11 +++++ linux-2.6.9-rc2-mm1-kanesige/arch/ia64/kernel/acpi.c | 11 +++++ linux-2.6.9-rc2-mm1-kanesige/drivers/acpi/pci_irq.c | 26 ++++++++++++++ linux-2.6.9-rc2-mm1-kanesige/include/linux/acpi.h | 2 + 4 files changed, 50 insertions(+) diff -puN arch/i386/kernel/acpi/boot.c~IRQ_deallocation_acpi arch/i386/kernel/acpi/boot.c --- linux-2.6.9-rc2-mm1/arch/i386/kernel/acpi/boot.c~IRQ_deallocation_acpi 2004-09-21 14:06:20.000000000 +0900 +++ linux-2.6.9-rc2-mm1-kanesige/arch/i386/kernel/acpi/boot.c 2004-09-21 15:23:48.012354914 +0900 @@ -480,6 +480,17 @@ unsigned int acpi_register_gsi(u32 gsi, } EXPORT_SYMBOL(acpi_register_gsi); +/* + * This function undoes the effect of one call to acpi_register_gsi(). + * If this matches the last regstration, any IRQ resources for gsi + * associated with the irq are freed. + */ +void +acpi_unregister_gsi (unsigned int irq) +{ +} +EXPORT_SYMBOL(acpi_unregister_gsi); + static unsigned long __init acpi_scan_rsdp ( unsigned long start, diff -puN arch/ia64/kernel/acpi.c~IRQ_deallocation_acpi arch/ia64/kernel/acpi.c --- linux-2.6.9-rc2-mm1/arch/ia64/kernel/acpi.c~IRQ_deallocation_acpi 2004-09-21 14:06:20.000000000 +0900 +++ linux-2.6.9-rc2-mm1-kanesige/arch/ia64/kernel/acpi.c 2004-09-21 15:23:11.218165006 +0900 @@ -516,6 +516,17 @@ acpi_register_gsi (u32 gsi, int edge_lev } EXPORT_SYMBOL(acpi_register_gsi); +/* + * This function undoes the effect of one call to acpi_register_gsi(). + * If this matches the last regstration, any IRQ resources for gsi + * associated with the irq are freed. + */ +void +acpi_unregister_gsi (unsigned int irq) +{ +} +EXPORT_SYMBOL(acpi_unregister_gsi); + static int __init acpi_parse_fadt (unsigned long phys_addr, unsigned long size) { diff -puN drivers/acpi/pci_irq.c~IRQ_deallocation_acpi drivers/acpi/pci_irq.c --- linux-2.6.9-rc2-mm1/drivers/acpi/pci_irq.c~IRQ_deallocation_acpi 2004-09-21 14:06:20.000000000 +0900 +++ linux-2.6.9-rc2-mm1-kanesige/drivers/acpi/pci_irq.c 2004-09-21 14:06:20.000000000 +0900 @@ -390,3 +390,29 @@ acpi_pci_irq_enable ( return_VALUE(dev->irq); } + +void +acpi_pci_irq_disable ( + struct pci_dev *dev) +{ + unsigned char irq_disabled, irq; + + ACPI_FUNCTION_TRACE("acpi_pci_irq_disable"); + + irq_disabled = dev->irq; + + /* + * dev->irq is cleared by BIOS-assigned IRQ set during boot. + */ + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); + if (irq) + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + dev->irq = irq; + + printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n", + pci_name(dev)); + + acpi_unregister_gsi(irq_disabled); + + return_VOID; +} diff -puN include/linux/acpi.h~IRQ_deallocation_acpi include/linux/acpi.h --- linux-2.6.9-rc2-mm1/include/linux/acpi.h~IRQ_deallocation_acpi 2004-09-21 14:06:20.000000000 +0900 +++ linux-2.6.9-rc2-mm1-kanesige/include/linux/acpi.h 2004-09-21 14:06:20.000000000 +0900 @@ -414,6 +414,7 @@ static inline int acpi_boot_init(void) #endif /*!CONFIG_ACPI_BOOT*/ unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low); +void acpi_unregister_gsi (unsigned int); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); #ifdef CONFIG_ACPI_PCI @@ -439,6 +440,7 @@ extern struct acpi_prt_list acpi_prt; struct pci_dev; int acpi_pci_irq_enable (struct pci_dev *dev); +void acpi_pci_irq_disable (struct pci_dev *dev); struct acpi_pci_driver { struct acpi_pci_driver *next; _ ------------------------------------------------------- This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170 Project Admins to receive an Apple iPod Mini FREE for your judgement on who ports your project to Linux PPC the best. Sponsored by IBM. Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php