public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
To: Bjorn Helgaas <bjorn.helgaas@hp.com>,
	Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: "'Li, Shaohua'" <shaohua.li@intel.com>,
	acpi-devel@lists.sourceforge.net, "'Brown,
	Len'" <len.brown@intel.com>,
	'David Mosberger' <davidm@hpl.hp.com>, 'Andi Kleen' <ak@suse.de>,
	"'Nakajima, Jun'" <jun.nakajima@intel.com>,
	linux-ia64@vger.kernel.org
Subject: RE: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework
Date: Tue, 18 May 2004 09:30:38 +0000	[thread overview]
Message-ID: <MDEEKOKJPMPMKGHIFAMACEPJEAAA.kaneshige.kenji@jp.fujitsu.com> (raw)
In-Reply-To: <200405171241.24071.bjorn.helgaas@hp.com>

> Out of curiosity, do you have a machine that routes INIT or
> PMI through an IOSAPIC?  It's certainly allowed, and we should
> support it, but the HP and Intel boxes I've seen don't seem to
> do that.

No, I don't. My machine is Tiger4. As you said, it doesn't have
PMI and INIT through an IOSAPIC.

Thanks,
Kenji Kaneshige


> -----Original Message-----
> From: linux-ia64-owner@vger.kernel.org
> [mailto:linux-ia64-owner@vger.kernel.org]On Behalf Of Bjorn Helgaas
> Sent: Tuesday, May 18, 2004 3:41 AM
> To: Kenji Kaneshige
> Cc: 'Li, Shaohua'; acpi-devel@lists.sourceforge.net; 'Brown,
> Len'; 'David Mosberger'; 'Andi Kleen'; 'Nakajima, Jun';
> linux-ia64@vger.kernel.org
> Subject: Re: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework
>
>
> On Monday 17 May 2004 10:16 am, Kenji Kaneshige wrote:
> > I agree with you about CPEI, but how about PMI and INIT?
> > I think PMI and INIT need to be unmasked in somewhere.
>
> Yes, you're right.
>
> The following patch unmasks platform interrupt IOSAPIC entries
> (except for CPEI) when we process them from the MADT.
>
> Out of curiosity, do you have a machine that routes INIT or
> PMI through an IOSAPIC?  It's certainly allowed, and we should
> support it, but the HP and Intel boxes I've seen don't seem to
> do that.
>
> === arch/i386/kernel/mpparse.c 1.71 vs edited ==> --- 1.71/arch/i386/kernel/mpparse.c	Fri Apr 30 23:27:25 2004
> +++ edited/arch/i386/kernel/mpparse.c	Mon May 17 10:39:37 2004
> @@ -1027,94 +1027,58 @@
>
>  extern FADT_DESCRIPTOR acpi_fadt;
>
> -#ifdef CONFIG_ACPI_PCI
> +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
> +
> +#ifdef CONFIG_X86_IO_APIC
>
> -void __init mp_parse_prt (void)
> +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
>  {
> -	struct list_head	*node = NULL;
> -	struct acpi_prt_entry	*entry = NULL;
>  	int			ioapic = -1;
>  	int			ioapic_pin = 0;
> -	int			gsi = 0;
>  	int			idx, bit = 0;
> -	int			edge_level = 0;
> -	int			active_high_low = 0;
>
> -	/*
> -	 * Parsing through the PCI Interrupt Routing Table (PRT) and program
> -	 * routing for all entries.
> -	 */
> -	list_for_each(node, &acpi_prt.entries) {
> -		entry = list_entry(node, struct acpi_prt_entry, node);
> +	/* Don't set up the ACPI SCI because it's already set up */
> +	if (acpi_fadt.sci_int = gsi)
> +		return;
> +
> +	ioapic = mp_find_ioapic(gsi);
> +	if (ioapic < 0) {
> +		printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi);
> +		return;
> +	}
> +
> +	ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
>
> -		/* Need to get gsi for dynamic entry */
> -		if (entry->link.handle) {
> -			gsi > acpi_pci_link_get_irq(entry->link.handle, entry->link.index,
> &edge_level, &active_high_low);
> -			if (!gsi)
> -				continue;
> -		}
> -		else {
> -			/* Hardwired GSI. Assume PCI standard settings */
> -			gsi = entry->link.index;
> -			edge_level = 1;
> -			active_high_low = 1;
> -		}
> -
> -		/* Don't set up the ACPI SCI because it's already set up */
> -                if (acpi_fadt.sci_int = gsi) {
> -			/* we still need to set entry's irq */
> -			acpi_gsi_to_irq(gsi, &entry->irq);
> -			continue;
> -                }
> -
> -		ioapic = mp_find_ioapic(gsi);
> -		if (ioapic < 0)
> -			continue;
> -		ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
> -
> -		if (es7000_plat) {
> -			if (!ioapic && (gsi < 16))
> -				gsi += 16;
> -		}
> -
> -		/*
> -		 * Avoid pin reprogramming.  PRTs typically include
> entries
> -		 * with redundant pin->gsi mappings (but unique PCI
> devices);
> -		 * we only only program the IOAPIC on the first.
> -		 */
> -		bit = ioapic_pin % 32;
> -		idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
> -		if (idx > 3) {
> -			printk(KERN_ERR "Invalid reference to IOAPIC pin "
> -				"%d-%d\n",
> mp_ioapic_routing[ioapic].apic_id,
> -				ioapic_pin);
> -			continue;
> -		}
> -		if ((1<<bit) &
> mp_ioapic_routing[ioapic].pin_programmed[idx]) {
> -			Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
> -				mp_ioapic_routing[ioapic].apic_id,
> ioapic_pin);
> -			acpi_gsi_to_irq(gsi, &entry->irq);
> -			continue;
> -		}
> -
> -		mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
> -
> -		if (!io_apic_set_pci_routing(ioapic, ioapic_pin,
> gsi, edge_level, active_high_low)) {
> -			acpi_gsi_to_irq(gsi, &entry->irq);
> -		}
> -		printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d ->
> IRQ %d %s %s\n",
> -			entry->id.segment, entry->id.bus,
> -			entry->id.device, ('A' + entry->pin),
> -			mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
> -			entry->irq, edge_level ? "level" : "edge",
> -			active_high_low ? "low" : "high");
> +	if (es7000_plat) {
> +		if (!ioapic && (gsi < 16))
> +			gsi += 16;
>  	}
>
> -	print_IO_APIC();
> +	/*
> +	 * Avoid pin reprogramming.  PRTs typically include entries
> +	 * with redundant pin->gsi mappings (but unique PCI devices);
> +	 * we only program the IOAPIC on the first.
> +	 */
> +	bit = ioapic_pin % 32;
> +	idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
> +	if (idx > 3) {
> +		printk(KERN_ERR "Invalid reference to IOAPIC pin "
> +			"%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
> +			ioapic_pin);
> +		return;
> +	}
> +	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
> +		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
> +			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
> +		return;
> +	}
>
> -	return;
> +	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
> +
> +	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
> +		    edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1,
> +		    active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1);
>  }
>
> -#endif /*CONFIG_ACPI_PCI*/
> -#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
> +#endif /*CONFIG_X86_IO_APIC*/
>  #endif /*CONFIG_ACPI_BOOT*/
> === arch/i386/kernel/acpi/boot.c 1.61 vs edited ==> --- 1.61/arch/i386/kernel/acpi/boot.c	Sat May 15 00:11:59 2004
> +++ edited/arch/i386/kernel/acpi/boot.c	Mon May 17 10:39:37 2004
> @@ -428,6 +428,28 @@
>  	return 0;
>  }
>
> +unsigned int acpi_register_gsi(u32 gsi, int edge_level, int
> active_high_low)
> +{
> +	static u16 irq_mask;
> +	unsigned int irq;
> +	extern void eisa_set_level_irq(unsigned int irq);
> +
> +	/*
> +	 * Make sure all (legacy) PCI IRQs are set as level-triggered.
> +	 */
> +	if ((gsi < 16) && !((1 << gsi) & irq_mask)) {
> +		printk(KERN_DEBUG PREFIX "Setting GSI 0x%x as
> level-triggered\n", gsi);
> +		irq_mask |= (1 << gsi);
> +		eisa_set_level_irq(gsi);
> +	}
> +
> +#ifdef CONFIG_X86_IO_APIC
> +	mp_register_gsi(gsi, edge_level, active_high_low);
> +#endif
> +	acpi_gsi_to_irq(gsi, &irq);
> +	return irq;
> +}
> +
>  static unsigned long __init
>  acpi_scan_rsdp (
>  	unsigned long		start,
> === arch/i386/pci/acpi.c 1.13 vs edited ==> --- 1.13/arch/i386/pci/acpi.c	Fri Apr 30 23:27:25 2004
> +++ edited/arch/i386/pci/acpi.c	Mon May 17 10:39:37 2004
> @@ -1,6 +1,8 @@
>  #include <linux/pci.h>
>  #include <linux/acpi.h>
>  #include <linux/init.h>
> +#include <linux/irq.h>
> +#include <asm/hw_irq.h>
>  #include "pci.h"
>
>  struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device
> *device, int domain, int busnum)
> @@ -15,18 +17,28 @@
>
>  static int __init pci_acpi_init(void)
>  {
> +	struct pci_dev *dev = NULL;
> +
>  	if (pcibios_scanned)
>  		return 0;
>
> -	if (!acpi_noirq) {
> -		if (!acpi_pci_irq_init()) {
> -			printk(KERN_INFO "PCI: Using ACPI for IRQ
> routing\n");
> -			pcibios_scanned++;
> -			pcibios_enable_irq = acpi_pci_irq_enable;
> -		} else
> -			printk(KERN_WARNING "PCI: Invalid ACPI-PCI
> IRQ routing table\n");
> +	if (acpi_noirq)
> +		return 0;
>
> -	}
> +	printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
> +	acpi_irq_penalty_init();
> +	pcibios_scanned++;
> +	pcibios_enable_irq = acpi_pci_irq_enable;
> +
> +	/*
> +	 * PCI IRQ routing is set up by pci_enable_device(), but we
> +	 * also do it here in case there are still broken drivers that
> +	 * don't use pci_enable_device().
> +	 */
> +	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
> +		acpi_pci_irq_enable(dev);
> +
> +	print_IO_APIC();
>
>  	return 0;
>  }
> === arch/ia64/kernel/acpi.c 1.69 vs edited ==> --- 1.69/arch/ia64/kernel/acpi.c	Sat May 15 00:11:59 2004
> +++ edited/arch/ia64/kernel/acpi.c	Mon May 17 10:39:37 2004
> @@ -508,9 +508,14 @@
>  #endif /* CONFIG_ACPI_NUMA */
>
>  unsigned int
> -acpi_register_gsi (u32 gsi, int polarity, int trigger)
> +acpi_register_gsi (u32 gsi, int edge_level, int active_high_low)
>  {
> -	return acpi_register_irq(gsi, polarity, trigger);
> +	if (has_8259 && gsi < 16)
> +		return isa_irq_to_vector(gsi);
> +
> +	return iosapic_register_intr(gsi,
> +			(active_high_low = ACPI_ACTIVE_HIGH) ?
> IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
> +			(edge_level = ACPI_EDGE_SENSITIVE) ?
> IOSAPIC_EDGE : IOSAPIC_LEVEL);
>  }
>  EXPORT_SYMBOL(acpi_register_gsi);
>
> @@ -535,7 +540,7 @@
>  	if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
>  		acpi_legacy_devices = 1;
>
> -	acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW,
> ACPI_LEVEL_SENSITIVE);
> +	acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE,
> ACPI_ACTIVE_LOW);
>  	return 0;
>  }
>
> @@ -648,17 +653,5 @@
>  	}
>  	return 0;
>  }
> -
> -int
> -acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
> -{
> -	if (has_8259 && gsi < 16)
> -		return isa_irq_to_vector(gsi);
> -
> -	return iosapic_register_intr(gsi,
> -			(polarity = ACPI_ACTIVE_HIGH) ?
> IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
> -			(trigger = ACPI_EDGE_SENSITIVE) ?
> IOSAPIC_EDGE : IOSAPIC_LEVEL);
> -}
> -EXPORT_SYMBOL(acpi_register_irq);
>
>  #endif /* CONFIG_ACPI_BOOT */
> === arch/ia64/kernel/iosapic.c 1.42 vs edited ==> --- 1.42/arch/ia64/kernel/iosapic.c	Fri May 14 20:00:12 2004
> +++ edited/arch/ia64/kernel/iosapic.c	Mon May 17 11:51:35 2004
> @@ -512,6 +512,42 @@
>  	}
>  }
>
> +static unsigned int
> +dest_cpu_lid (void)
> +{
> +#ifdef CONFIG_SMP
> +	static int cpu = -1;
> +
> +	/*
> +	 * If the platform supports redirection via XTP, let it
> +	 * distribute interrupts.
> +	 */
> +	if (smp_int_redirect & SMP_IRQ_REDIRECTION)
> +		return hard_smp_processor_id();
> +
> +	/*
> +	 * Some interrupts (ACPI SCI, for instance) are registered
> +	 * before the BSP is marked as online.
> +	 */
> +	if (!cpu_online(smp_processor_id()))
> +		return hard_smp_processor_id();
> +
> +	/*
> +	 * Otherwise, round-robin interrupt vectors across all the
> +	 * processors.  (It'd be nice if we could be smarter in the
> +	 * case of NUMA.)
> +	 */
> +	do {
> +		if (++cpu >= NR_CPUS)
> +			cpu = 0;
> +	} while (!cpu_online(cpu));
> +
> +	return cpu_physical_id(cpu);
> +#else
> +	return hard_smp_processor_id();
> +#endif
> +}
> +
>  /*
>   * ACPI can describe IOSAPIC interrupts via static tables and namespace
>   * methods.  This provides an interface to register those interrupts and
> @@ -522,21 +558,35 @@
>  		       unsigned long polarity, unsigned long trigger)
>  {
>  	int vector;
> -	unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
> +	unsigned int dest;
> +	unsigned long flags;
>
> -	vector = gsi_to_vector(gsi);
> -	if (vector < 0)
> -		vector = assign_irq_vector(AUTO_ASSIGN);
> +	/*
> +	 * If this GSI has already been registered (i.e., it's a
> +	 * shared interrupt, or we lost a race to register it),
> +	 * don't touch the RTE.
> +	 */
> +	spin_lock_irqsave(&iosapic_lock, flags);
> +	{
> +		vector = gsi_to_vector(gsi);
> +		if (vector > 0) {
> +			spin_unlock_irqrestore(&iosapic_lock, flags);
> +			return vector;
> +		}
>
> -	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
> -		      polarity, trigger);
> +		vector = assign_irq_vector(AUTO_ASSIGN);
> +		dest = dest_cpu_lid();
> +		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
> +			polarity, trigger);
> +	}
> +	spin_unlock_irqrestore(&iosapic_lock, flags);
>
> -	printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
> -	       gsi, (polarity = IOSAPIC_POL_HIGH ? "high" : "low"),
> -	       (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
> +	printk(KERN_INFO "GSI 0x%x (%s, %s) -> CPU %d (0x%04x) vector %d\n",
> +	       gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"),
> +	       (polarity = IOSAPIC_POL_HIGH ? "high" : "low"),
> +	       cpu_logical_id(dest), dest, vector);
>
> -	/* program the IOSAPIC routing table */
> -	set_rte(vector, dest, 0);
> +	set_rte(vector, dest, 1);
>  	return vector;
>  }
>
> @@ -549,8 +599,9 @@
>  				int iosapic_vector, u16 eid, u16 id,
>  				unsigned long polarity, unsigned
> long trigger)
>  {
> +	static const char * const name[] = {"unknown", "PMI",
> "INIT", "CPEI"};
>  	unsigned char delivery;
> -	int vector;
> +	int vector, mask = 0;
>  	unsigned int dest = ((id << 8) | eid) & 0xffff;
>
>  	switch (int_type) {
> @@ -570,21 +621,22 @@
>  	      case ACPI_INTERRUPT_CPEI:
>  		vector = IA64_CPE_VECTOR;
>  		delivery = IOSAPIC_LOWEST_PRIORITY;
> +		mask = 1;
>  		break;
>  	      default:
> -		printk(KERN_ERR "iosapic_register_platform_irq():
> invalid int type\n");
> +		printk(KERN_ERR "iosapic_register_platform_irq():
> invalid int type 0x%x\n", int_type);
>  		return -1;
>  	}
>
> -	register_intr(gsi, vector, delivery, polarity,
> -		      trigger);
> +	register_intr(gsi, vector, delivery, polarity, trigger);
>
> -	printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU
> 0x%04x vector %d\n",
> -	       int_type, gsi, (polarity = IOSAPIC_POL_HIGH ?
> "high" : "low"),
> -	       (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
> +	printk(KERN_INFO "PLATFORM int %s (0x%x): GSI 0x%x (%s, %s)
> -> CPU %d (0x%04x) vector %d\n",
> +	       int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
> +	       int_type, gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"),
> +	       (polarity = IOSAPIC_POL_HIGH ? "high" : "low"),
> +	       cpu_logical_id(dest), dest, vector);
>
> -	/* program the IOSAPIC routing table */
> -	set_rte(vector, dest, 0);
> +	set_rte(vector, dest, mask);
>  	return vector;
>  }
>
> @@ -599,18 +651,18 @@
>  			  unsigned long trigger)
>  {
>  	int vector;
> -	unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
> +	unsigned int dest = hard_smp_processor_id();
>
>  	vector = isa_irq_to_vector(isa_irq);
>
>  	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
> polarity, trigger);
>
> -	DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
> -	    isa_irq, gsi, polarity = IOSAPIC_POL_HIGH ? "high" : "low",
> -	    trigger = IOSAPIC_EDGE ? "edge" : "level", dest, vector);
> +	DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU %d (0x%04x)
> vector %d\n",
> +	    isa_irq, gsi, trigger = IOSAPIC_EDGE ? "edge" : "level",
> +	    polarity = IOSAPIC_POL_HIGH ? "high" : "low",
> +	    cpu_logical_id(dest), dest, vector);
>
> -	/* program the IOSAPIC routing table */
> -	set_rte(vector, dest, 0);
> +	set_rte(vector, dest, 1);
>  }
>
>  void __init
> @@ -665,104 +717,3 @@
>  			iosapic_override_isa_irq(isa_irq, isa_irq,
> IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
>  	}
>  }
> -
> -void
> -iosapic_enable_intr (unsigned int vector)
> -{
> -	unsigned int dest;
> -	irq_desc_t *desc;
> -
> -	/*
> -	 * In the case of a shared interrupt, do not re-route the
> vector, and
> -	 * especially do not mask a running interrupt (startup will not get
> -	 * called for a shared interrupt).
> -	 */
> -	desc = irq_descp(vector);
> -	if (desc->action)
> -		return;
> -
> -#ifdef CONFIG_SMP
> -	/*
> -	 * For platforms that do not support interrupt redirect via
> the XTP interface, we
> -	 * can round-robin the PCI device interrupts to the processors
> -	 */
> -	if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
> -		static int cpu_index = -1;
> -
> -		do
> -			if (++cpu_index >= NR_CPUS)
> -				cpu_index = 0;
> -		while (!cpu_online(cpu_index));
> -
> -		dest = cpu_physical_id(cpu_index) & 0xffff;
> -	} else {
> -		/*
> -		 * Direct the interrupt vector to the current cpu,
> platform redirection
> -		 * will distribute them.
> -		 */
> -		dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
> -	}
> -#else
> -	/* direct the interrupt vector to the running cpu id */
> -	dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
> -#endif
> -	set_rte(vector, dest, 1);
> -
> -	printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n",
> -	       vector, dest);
> -}
> -
> -#ifdef CONFIG_ACPI_PCI
> -
> -void __init
> -iosapic_parse_prt (void)
> -{
> -	struct acpi_prt_entry *entry;
> -	struct list_head *node;
> -	unsigned int gsi;
> -	int vector;
> -	char pci_id[16];
> -	struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
> -	irq_desc_t *idesc;
> -
> -	list_for_each(node, &acpi_prt.entries) {
> -		entry = list_entry(node, struct acpi_prt_entry, node);
> -
> -		/* We're only interested in static (non-link) entries.  */
> -		if (entry->link.handle)
> -			continue;
> -
> -		gsi = entry->link.index;
> -
> -		vector = gsi_to_vector(gsi);
> -		if (vector < 0) {
> -			if (find_iosapic(gsi) < 0)
> -				continue;
> -
> -			/* allocate a vector for this interrupt line */
> -			if (pcat_compat && (gsi < 16))
> -				vector = isa_irq_to_vector(gsi);
> -			else
> -				/* new GSI; allocate a vector for it */
> -				vector = assign_irq_vector(AUTO_ASSIGN);
> -
> -			register_intr(gsi, vector,
> IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
> -				      IOSAPIC_LEVEL);
> -		}
> -		entry->irq = vector;
> -		snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
> -			 entry->id.segment, entry->id.bus,
> entry->id.device, 'A' + entry->pin);
> -
> -		/*
> -		 * If vector was previously initialized to a different
> -		 * handler, re-initialize.
> -		 */
> -		idesc = irq_descp(vector);
> -		if (idesc->handler != irq_type)
> -			register_intr(gsi, vector,
> IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
> -				      IOSAPIC_LEVEL);
> -
> -	}
> -}
> -
> -#endif /* CONFIG_ACPI */
> === arch/ia64/pci/pci.c 1.48 vs edited ==> --- 1.48/arch/ia64/pci/pci.c	Wed Apr 21 15:26:09 2004
> +++ edited/arch/ia64/pci/pci.c	Mon May 17 10:39:38 2004
> @@ -134,10 +134,18 @@
>  static int __init
>  pci_acpi_init (void)
>  {
> -	if (!acpi_pci_irq_init())
> -		printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
> -	else
> -		printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ
> routing table\n");
> +	struct pci_dev *dev = NULL;
> +
> +	printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
> +
> +	/*
> +	 * PCI IRQ routing is set up by pci_enable_device(), but we
> +	 * also do it here in case there are still broken drivers that
> +	 * don't use pci_enable_device().
> +	 */
> +	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
> +		acpi_pci_irq_enable(dev);
> +
>  	return 0;
>  }
>
> === arch/x86_64/kernel/mpparse.c 1.27 vs edited ==> --- 1.27/arch/x86_64/kernel/mpparse.c	Sat May 15 07:32:27 2004
> +++ edited/arch/x86_64/kernel/mpparse.c	Mon May 17 10:39:38 2004
> @@ -887,88 +887,49 @@
>
>  extern FADT_DESCRIPTOR acpi_fadt;
>
> -#ifdef CONFIG_ACPI_PCI
> -
> -void __init mp_parse_prt (void)
> +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
>  {
> -	struct list_head	*node = NULL;
> -	struct acpi_prt_entry	*entry = NULL;
>  	int			ioapic = -1;
>  	int			ioapic_pin = 0;
> -	int			gsi = 0;
>  	int			idx, bit = 0;
> -	int			edge_level = 0;
> -	int			active_high_low = 0;
>
> -	/*
> -	 * Parsing through the PCI Interrupt Routing Table (PRT) and program
> -	 * routing for all static (IOAPIC-direct) entries.
> -	 */
> -	list_for_each(node, &acpi_prt.entries) {
> -		entry = list_entry(node, struct acpi_prt_entry, node);
> +	/* Don't set up the ACPI SCI because it's already set up */
> +	if (acpi_fadt.sci_int = gsi)
> +		return;
> +
> +	ioapic = mp_find_ioapic(gsi);
> +	if (ioapic < 0) {
> +		printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi);
> +		return;
> +	}
>
> -		/* Need to get gsi for dynamic entry */
> -		if (entry->link.handle) {
> -			gsi > acpi_pci_link_get_irq(entry->link.handle, entry->link.index,
> &edge_level, &active_high_low);
> -			if (!gsi)
> -				continue;
> -		} else {
> -			/* Hardwired GSI. Assume PCI standard settings */
> -			gsi = entry->link.index;
> -			edge_level = 1;
> -			active_high_low = 1;
> -		}
> -
> -		/* Don't set up the ACPI SCI because it's already set up */
> -		if (acpi_fadt.sci_int = gsi) {
> -			/* we still need to set up the entry's irq */
> -			acpi_gsi_to_irq(gsi, &entry->irq);
> -			continue;
> -		}
> -
> -		ioapic = mp_find_ioapic(gsi);
> -		if (ioapic < 0)
> -			continue;
> -		ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
> -
> -		/*
> -		 * Avoid pin reprogramming.  PRTs typically include
> entries
> -		 * with redundant pin->gsi mappings (but unique PCI
> devices);
> -		 * we only only program the IOAPIC on the first.
> -		 */
> -		bit = ioapic_pin % 32;
> -		idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
> -		if (idx > 3) {
> -			printk(KERN_ERR "Invalid reference to IOAPIC pin "
> -				"%d-%d\n",
> mp_ioapic_routing[ioapic].apic_id,
> -				ioapic_pin);
> -			continue;
> -		}
> -		if ((1<<bit) &
> mp_ioapic_routing[ioapic].pin_programmed[idx]) {
> -			Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
> -				mp_ioapic_routing[ioapic].apic_id,
> ioapic_pin);
> -			acpi_gsi_to_irq(gsi, &entry->irq);
> -			continue;
> -		}
> -
> -		mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
> -		if (!io_apic_set_pci_routing(ioapic, ioapic_pin,
> gsi, edge_level, active_high_low)) {
> -			acpi_gsi_to_irq(gsi, &entry->irq);
> - 		}
> -		printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
> -			entry->id.segment, entry->id.bus,
> -			entry->id.device, ('A' + entry->pin),
> -			mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
> -			entry->irq);
> +	ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
> +
> +	/*
> +	 * Avoid pin reprogramming.  PRTs typically include entries
> +	 * with redundant pin->gsi mappings (but unique PCI devices);
> +	 * we only program the IOAPIC on the first.
> +	 */
> +	bit = ioapic_pin % 32;
> +	idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
> +	if (idx > 3) {
> +		printk(KERN_ERR "Invalid reference to IOAPIC pin "
> +			"%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
> +			ioapic_pin);
> +		return;
> +	}
> +	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
> +		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
> +			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
> +		return;
>  	}
> -
> -	print_IO_APIC();
>
> -	return;
> -}
> +	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
>
> -#endif /*CONFIG_ACPI_PCI*/
> +	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
> +		edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1,
> +		active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1);
> +}
>
>  #endif /*CONFIG_X86_IO_APIC*/
> -
>  #endif /*CONFIG_ACPI_BOOT*/
> === drivers/acpi/pci_irq.c 1.27 vs edited ==> --- 1.27/drivers/acpi/pci_irq.c	Sat Apr 24 00:17:22 2004
> +++ edited/drivers/acpi/pci_irq.c	Mon May 17 10:39:38 2004
> @@ -35,12 +35,6 @@
>  #include <linux/pm.h>
>  #include <linux/pci.h>
>  #include <linux/acpi.h>
> -#ifdef CONFIG_X86_IO_APIC
> -#include <asm/mpspec.h>
> -#endif
> -#ifdef CONFIG_IOSAPIC
> -# include <asm/iosapic.h>
> -#endif
>  #include <acpi/acpi_bus.h>
>  #include <acpi/acpi_drivers.h>
>
> @@ -50,10 +44,6 @@
>
>  struct acpi_prt_list		acpi_prt;
>
> -#ifdef CONFIG_X86
> -extern void eisa_set_level_irq(unsigned int irq);
> -#endif
> -
>
>  /*
> --------------------------------------------------------------------------
>                           PCI IRQ Routing Table (PRT) Support
> @@ -237,12 +227,18 @@
>                            PCI Interrupt Routing Support
>
> ------------------------------------------------------------------
> -------- */
>
> -int
> -acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
> +static int
> +acpi_pci_irq_lookup (
> +	struct pci_bus		*bus,
> +	int			device,
> +	int			pin,
> +	int			*edge_level,
> +	int			*active_high_low)
>  {
>  	struct acpi_prt_entry	*entry = NULL;
>  	int segment = pci_domain_nr(bus);
>  	int bus_nr = bus->number;
> +	int irq;
>
>  	ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
>
> @@ -255,28 +251,30 @@
>  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
>  		return_VALUE(0);
>  	}
> -
> -	if (!entry->irq && entry->link.handle) {
> -		entry->irq > acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL);
> -		if (!entry->irq) {
> +
> +	if (entry->link.handle) {
> +		irq = acpi_pci_link_get_irq(entry->link.handle,
> entry->link.index, edge_level, active_high_low);
> +		if (!irq) {
>  			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid
> IRQ link routing entry\n"));
>  			return_VALUE(0);
>  		}
> -	}
> -	else if (!entry->irq) {
> -		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static
> routing entry (IRQ 0)\n"));
> -		return_VALUE(0);
> +	} else {
> +		irq = entry->link.index;
> +		*edge_level = ACPI_LEVEL_SENSITIVE;
> +		*active_high_low = ACPI_ACTIVE_LOW;
>  	}
>
> -	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq));
> +	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
>
> -	return_VALUE(entry->irq);
> +	return_VALUE(irq);
>  }
>
>  static int
>  acpi_pci_irq_derive (
>  	struct pci_dev		*dev,
> -	int			pin)
> +	int			pin,
> +	int			*edge_level,
> +	int			*active_high_low)
>  {
>  	struct pci_dev		*bridge = dev;
>  	int			irq = 0;
> @@ -308,8 +306,8 @@
>  			pin = bridge_pin;
>  		}
>
> -		irq = acpi_pci_irq_lookup(bridge->bus,
> -				PCI_SLOT(bridge->devfn), pin);
> +		irq = acpi_pci_irq_lookup(bridge->bus,
> PCI_SLOT(bridge->devfn),
> +			pin, edge_level, active_high_low);
>  	}
>
>  	if (!irq) {
> @@ -330,6 +328,8 @@
>  {
>  	int			irq = 0;
>  	u8			pin = 0;
> +	int			edge_level = ACPI_LEVEL_SENSITIVE;
> +	int			active_high_low = ACPI_ACTIVE_LOW;
>
>  	ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
>
> @@ -352,21 +352,22 @@
>  	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
>  	 * values override any BIOS-assigned IRQs set during boot.
>  	 */
> - 	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin);
> + 	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn),
> pin, &edge_level, &active_high_low);
>
>  	/*
>  	 * If no PRT entry was found, we'll try to derive an IRQ from the
>  	 * device's parent bridge.
>  	 */
>  	if (!irq)
> - 		irq = acpi_pci_irq_derive(dev, pin);
> + 		irq = acpi_pci_irq_derive(dev, pin, &edge_level,
> &active_high_low);
>
>  	/*
>  	 * No IRQ known to the ACPI subsystem - maybe the BIOS /
>  	 * driver reported one, then use it. Exit in any case.
>  	 */
>  	if (!irq) {
> -		printk(KERN_WARNING PREFIX "No IRQ known for
> interrupt pin %c of device %s", ('A' + pin), pci_name(dev));
> +		printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI",
> +			pci_name(dev), ('A' + pin));
>  		/* Interrupt Line values above 0xF are forbidden */
>  		if (dev->irq && (dev->irq <= 0xF)) {
>  			printk(" - using IRQ %d\n", dev->irq);
> @@ -378,62 +379,14 @@
>  		}
>   	}
>
> -	dev->irq = irq;
> +	dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
>
> -	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n",
> pci_name(dev), dev->irq));
> -
> -	/*
> -	 * Make sure all (legacy) PCI IRQs are set as level-triggered.
> -	 */
> -#ifdef CONFIG_X86
> -	{
> -		static u16 irq_mask;
> -		if ((dev->irq < 16) &&  !((1 << dev->irq) & irq_mask)) {
> -			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting
> IRQ %d as level-triggered\n", dev->irq));
> -			irq_mask |= (1 << dev->irq);
> -			eisa_set_level_irq(dev->irq);
> -		}
> -	}
> -#endif
> -#ifdef CONFIG_IOSAPIC
> -	if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC)
> -		iosapic_enable_intr(dev->irq);
> -#endif
> +	printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI 0x%x "
> +		"(%s, %s) -> IRQ %d\n",
> +		pci_name(dev), 'A' + pin, irq,
> +		(edge_level = ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
> +		(active_high_low = ACPI_ACTIVE_LOW) ? "low" : "high",
> +		dev->irq);
>
>  	return_VALUE(dev->irq);
> -}
> -
> -
> -int __init
> -acpi_pci_irq_init (void)
> -{
> -	struct pci_dev          *dev = NULL;
> -
> -	ACPI_FUNCTION_TRACE("acpi_pci_irq_init");
> -
> -	if (!acpi_prt.count) {
> -		printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ "
> -			"routing entries\n");
> -		return_VALUE(-ENODEV);
> -	}
> -
> -	/* Make sure all link devices have a valid IRQ. */
> -	if (acpi_pci_link_check()) {
> -		return_VALUE(-ENODEV);
> -	}
> -
> -#ifdef CONFIG_X86_IO_APIC
> -	/* Program IOAPICs using data from PRT entries. */
> -	if (acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC)
> -		mp_parse_prt();
> -#endif
> -#ifdef CONFIG_IOSAPIC
> -	if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC)
> -		iosapic_parse_prt();
> -#endif
> -
> -	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
> -		acpi_pci_irq_enable(dev);
> -
> -	return_VALUE(0);
>  }
> === drivers/acpi/pci_link.c 1.28 vs edited ==> --- 1.28/drivers/acpi/pci_link.c	Mon May 10 14:42:35 2004
> +++ edited/drivers/acpi/pci_link.c	Mon May 17 10:39:39 2004
> @@ -487,13 +487,13 @@
>  };
>
>  int
> -acpi_pci_link_check (void)
> +acpi_irq_penalty_init(void)
>  {
>  	struct list_head	*node = NULL;
>  	struct acpi_pci_link    *link = NULL;
>  	int			i = 0;
>
> -	ACPI_FUNCTION_TRACE("acpi_pci_link_check");
> +	ACPI_FUNCTION_TRACE("acpi_irq_penalty_init");
>
>  	/*
>  	 * Update penalties to facilitate IRQ balancing.
> === drivers/serial/8250_acpi.c 1.8 vs edited ==> --- 1.8/drivers/serial/8250_acpi.c	Mon Mar 15 15:53:32 2004
> +++ edited/drivers/serial/8250_acpi.c	Mon May 17 10:39:39 2004
> @@ -58,28 +58,18 @@
>  static acpi_status acpi_serial_ext_irq(struct serial_struct *req,
>  				       struct acpi_resource_ext_irq
> *ext_irq)
>  {
> -	if (ext_irq->number_of_interrupts > 0) {
> -#ifdef CONFIG_IA64
> -		req->irq = acpi_register_irq(ext_irq->interrupts[0],
> -	                  ext_irq->active_high_low, ext_irq->edge_level);
> -#else
> -		req->irq = ext_irq->interrupts[0];
> -#endif
> -	}
> +	if (ext_irq->number_of_interrupts > 0)
> +		req->irq = acpi_register_gsi(ext_irq->interrupts[0],
> +	                  ext_irq->edge_level, ext_irq->active_high_low);
>  	return AE_OK;
>  }
>
>  static acpi_status acpi_serial_irq(struct serial_struct *req,
>  				   struct acpi_resource_irq *irq)
>  {
> -	if (irq->number_of_interrupts > 0) {
> -#ifdef CONFIG_IA64
> -		req->irq = acpi_register_irq(irq->interrupts[0],
> -	                  irq->active_high_low, irq->edge_level);
> -#else
> -		req->irq = irq->interrupts[0];
> -#endif
> -	}
> +	if (irq->number_of_interrupts > 0)
> +		req->irq = acpi_register_gsi(irq->interrupts[0],
> +	                  irq->edge_level, irq->active_high_low);
>  	return AE_OK;
>  }
>
> === drivers/serial/8250_hcdp.c 1.6 vs edited ==> --- 1.6/drivers/serial/8250_hcdp.c	Tue May  4 10:54:32 2004
> +++ edited/drivers/serial/8250_hcdp.c	Mon May 17 10:39:39 2004
> @@ -183,16 +183,12 @@
>  		}
>
>  		if (HCDP_IRQ_SUPPORTED(hcdp_dev)) {
> -#ifdef CONFIG_IA64
>  			if (HCDP_PCI_UART(hcdp_dev))
> -				port.irq = acpi_register_irq(gsi,
> -					ACPI_ACTIVE_LOW,
> ACPI_LEVEL_SENSITIVE);
> +				port.irq = acpi_register_gsi(gsi,
> +					ACPI_LEVEL_SENSITIVE,
> ACPI_ACTIVE_LOW);
>  			else
> -				port.irq = acpi_register_irq(gsi,
> -					ACPI_ACTIVE_HIGH,
> ACPI_EDGE_SENSITIVE);
> -#else
> -			port.irq = gsi;
> -#endif
> +				port.irq = acpi_register_gsi(gsi,
> +					ACPI_EDGE_SENSITIVE,
> ACPI_ACTIVE_HIGH);
>  			port.flags |= UPF_AUTO_IRQ;
>
>  			if (HCDP_PCI_UART(hcdp_dev))
> === include/acpi/acpi_drivers.h 1.17 vs edited ==> --- 1.17/include/acpi/acpi_drivers.h	Mon Dec 15 17:46:29 2003
> +++ edited/include/acpi/acpi_drivers.h	Mon May 17 10:39:40 2004
> @@ -55,7 +55,7 @@
>
>  /* ACPI PCI Interrupt Link (pci_link.c) */
>
> -int acpi_pci_link_check (void);
> +int acpi_irq_penalty_init (void);
>  int acpi_pci_link_get_irq (acpi_handle handle, int index, int*
> edge_level, int* active_high_low);
>
>  /* ACPI PCI Interrupt Routing (pci_irq.c) */
> === include/asm-i386/mpspec.h 1.20 vs edited ==> --- 1.20/include/asm-i386/mpspec.h	Mon Apr 12 11:55:30 2004
> +++ edited/include/asm-i386/mpspec.h	Mon May 17 10:39:40 2004
> @@ -33,7 +33,7 @@
>  extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
>  extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8
> trigger, u32 gsi);
>  extern void mp_config_acpi_legacy_irqs (void);
> -extern void mp_parse_prt (void);
> +extern void mp_register_gsi (u32 gsi, int edge_level, int
> active_high_low);
>  #endif /*CONFIG_ACPI_BOOT*/
>
>  #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
> === include/asm-ia64/iosapic.h 1.13 vs edited ==> --- 1.13/include/asm-ia64/iosapic.h	Fri Feb 27 04:39:17 2004
> +++ edited/include/asm-ia64/iosapic.h	Mon May 17 10:39:40 2004
> @@ -60,7 +60,6 @@
>  				    unsigned int gsi_base);
>  extern int gsi_to_vector (unsigned int gsi);
>  extern int gsi_to_irq (unsigned int gsi);
> -extern void __init iosapic_parse_prt (void);
>  extern void iosapic_enable_intr (unsigned int vector);
>  extern int iosapic_register_intr (unsigned int gsi, unsigned
> long polarity,
>  				  unsigned long trigger);
> === include/asm-x86_64/mpspec.h 1.11 vs edited ==> --- 1.11/include/asm-x86_64/mpspec.h	Mon Apr 12 11:55:30 2004
> +++ edited/include/asm-x86_64/mpspec.h	Mon May 17 10:39:40 2004
> @@ -189,7 +189,7 @@
>  extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
>  extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8
> trigger, u32 gsi);
>  extern void mp_config_acpi_legacy_irqs (void);
> -extern void mp_parse_prt (void);
> +extern void mp_register_gsi (u32 gsi, int edge_level, int
> active_high_low);
>  #endif /*CONFIG_X86_IO_APIC*/
>  #endif
>
> === include/linux/acpi.h 1.33 vs edited ==> --- 1.33/include/linux/acpi.h	Fri Apr  2 06:48:53 2004
> +++ edited/include/linux/acpi.h	Mon May 17 10:39:41 2004
> @@ -437,7 +437,7 @@
>  struct pci_dev;
>
>  int acpi_pci_irq_enable (struct pci_dev *dev);
> -int acpi_pci_irq_init (void);
> +unsigned int acpi_register_gsi (u32 gsi, int edge_level, int
> active_high_low);
>  int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
>
>  struct acpi_pci_driver {
> -
> To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


      reply	other threads:[~2004-05-18  9:30 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-17  9:58 [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework Li, Shaohua
2004-05-17 15:41 ` Bjorn Helgaas
2004-05-17 16:16   ` Kenji Kaneshige
2004-05-17 18:41     ` Bjorn Helgaas
2004-05-18  9:30       ` Kenji Kaneshige [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=MDEEKOKJPMPMKGHIFAMACEPJEAAA.kaneshige.kenji@jp.fujitsu.com \
    --to=kaneshige.kenji@jp.fujitsu.com \
    --cc=acpi-devel@lists.sourceforge.net \
    --cc=ak@suse.de \
    --cc=bjorn.helgaas@hp.com \
    --cc=davidm@hpl.hp.com \
    --cc=jun.nakajima@intel.com \
    --cc=len.brown@intel.com \
    --cc=linux-ia64@vger.kernel.org \
    --cc=shaohua.li@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox