public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Grant Likely <grant.likely@linaro.org>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Randy Dunlap <rdunlap@infradead.org>,
	Yinghai Lu <yinghai@kernel.org>,
	x86@kernel.org, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Tony Luck <tony.luck@intel.com>, Joerg Roedel <joro@8bytes.org>,
	Paul Gortmaker <paul.gortmaker@windriver.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	linux-acpi@vger.kernel.org, Ingo Molnar <mingo@kernel.org>
Subject: Re: [Patch V4 29/42] x86, irq: introduce two helper functions to support irqdomain map operation
Date: Thu, 21 Aug 2014 19:57:28 +0300	[thread overview]
Message-ID: <20140821165728.GV1660@lahna.fi.intel.com> (raw)
In-Reply-To: <20140821141729.GT1660@lahna.fi.intel.com>

On Thu, Aug 21, 2014 at 05:17:29PM +0300, Mika Westerberg wrote:
> On Mon, Jun 09, 2014 at 04:19:58PM +0800, Jiang Liu wrote:
> > Currently there are multiple entries to program IOAPIC pins, such as
> > io_apic_setup_irq_pin_once(), io_apic_set_pci_routing() and
> > setup_IO_APIC_irq_extra() etc.
> > 
> > This patch introduces two functions to help consolidate the code to
> > program IOAPIC pins. Function mp_set_pin_attr() is used to optionally
> > set trigger, polarity and NUMA node property for an IOAPIC pin.
> > If mp_set_pin_attr() is not invoked for a pin, the default configuration
> > from BIOS will be used.
> > 
> > Function mp_irqdomain_map() is an common implementation of irqdomain map()
> > operation. It figures out attribures for pin and then actually programs
> > the IOAPIC pin. We hope this will be the only entrance for programming
> > IOAPIC pin.
> > 
> > And the flow will:
> > 1) caller such as xxx_pci_irq_enable figures out pin attributes.
> > 2) Invoke mp_set_pin_attr() to set attributes for a pin. If the pin has
> >    already bin programmed,  mp_set_pin_attr() will aslo detects attribute
> >    confictions.
> > 3) Invoke mp_map_pin_to_irq()
> > 3.1) If IRQ has already been assigned, return irq_find_mapping()
> > 3.2) Else irq_create_mapping()
> > 		->irq_domain_associate()
> > 			->mp_irqdomain_map()
> > 				->io_apic_setup_irq_pin()
> > 
> > So every pin will only programmed once by mp_irqdomain_map(), so we
> > could kill io_apic_setup_irq_pin_once(), io_apic_set_pci_routing() and
> > setup_IO_APIC_irq_extra() etc.
> > 
> > Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
> > ---
> >  arch/x86/include/asm/io_apic.h |    5 ++
> >  arch/x86/kernel/apic/io_apic.c |   99 +++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 103 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
> > index 3e4bea3a52b1..c53587868590 100644
> > --- a/arch/x86/include/asm/io_apic.h
> > +++ b/arch/x86/include/asm/io_apic.h
> > @@ -173,7 +173,9 @@ enum ioapic_domain_type {
> >  };
> >  
> >  struct device_node;
> > +struct irq_domain;
> >  struct irq_domain_ops;
> > +
> >  struct ioapic_domain_cfg {
> >  	enum ioapic_domain_type		type;
> >  	const struct irq_domain_ops	*ops;
> > @@ -192,6 +194,9 @@ extern u32 mp_pin_to_gsi(int ioapic, int pin);
> >  extern int mp_map_gsi_to_irq(u32 gsi, unsigned int flags);
> >  extern void __init mp_register_ioapic(int id, u32 address, u32 gsi_base,
> >  				      struct ioapic_domain_cfg *cfg);
> > +extern int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
> > +			    irq_hw_number_t hwirq);
> > +extern int mp_set_gsi_attr(u32 gsi, int trigger, int polarity, int node);
> >  extern void __init pre_init_apic_IRQ0(void);
> >  
> >  extern void mp_save_irq(struct mpc_intsrc *m);
> > diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> > index 9c5f70699a80..61aae90f7e23 100644
> > --- a/arch/x86/kernel/apic/io_apic.c
> > +++ b/arch/x86/kernel/apic/io_apic.c
> > @@ -87,6 +87,14 @@ static DEFINE_RAW_SPINLOCK(vector_lock);
> >  static DEFINE_MUTEX(ioapic_mutex);
> >  static unsigned int ioapic_dynirq_base;
> >  
> > +struct mp_pin_info {
> > +	int trigger;
> > +	int polarity;
> > +	int node;
> > +	int set;
> > +	u32 count;
> > +};
> > +
> >  static struct ioapic {
> >  	/*
> >  	 * # of IRQ routing registers
> > @@ -102,6 +110,7 @@ static struct ioapic {
> >  	struct mp_ioapic_gsi  gsi_config;
> >  	struct ioapic_domain_cfg irqdomain_cfg;
> >  	struct irq_domain *irqdomain;
> > +	struct mp_pin_info *pin_info;
> >  	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
> >  } ioapics[MAX_IO_APICS];
> >  
> > @@ -147,6 +156,11 @@ static inline int mp_init_irq_at_boot(int ioapic, int irq)
> >  	return ioapic == 0 || (irq >= 0 && irq < nr_legacy_irqs());
> >  }
> >  
> > +static inline struct mp_pin_info *mp_pin_info(int ioapic_idx, int pin)
> > +{
> > +	return ioapics[ioapic_idx].pin_info + pin;
> > +}
> > +
> >  static inline struct irq_domain *mp_ioapic_irqdomain(int ioapic)
> >  {
> >  	return ioapics[ioapic].irqdomain;
> > @@ -1006,6 +1020,7 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin,
> >  {
> >  	int irq;
> >  	struct irq_domain *domain = mp_ioapic_irqdomain(ioapic);
> > +	struct mp_pin_info *info = mp_pin_info(ioapic, pin);
> >  
> >  	/*
> >  	 * Don't use irqdomain to manage ISA IRQs because there may be
> > @@ -1034,6 +1049,13 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin,
> >  	irq = irq_find_mapping(domain, pin);
> >  	if (irq <= 0 && (flags & IOAPIC_MAP_ALLOC))
> >  		irq = alloc_irq_from_domain(domain, gsi, pin);
> > +
> > +	if (flags & IOAPIC_MAP_ALLOC) {
> > +		if (irq > 0)
> > +			info->count++;
> > +		else if (info->count == 0)
> > +			info->set = 0;
> > +	}
> >  	mutex_unlock(&ioapic_mutex);
> >  
> >  	return irq > 0 ? irq : -1;
> > @@ -2923,18 +2945,27 @@ out:
> >  
> >  static int mp_irqdomain_create(int ioapic)
> >  {
> > +	size_t size;
> >  	int hwirqs = mp_ioapic_pin_count(ioapic);
> >  	struct ioapic *ip = &ioapics[ioapic];
> >  	struct ioapic_domain_cfg *cfg = &ip->irqdomain_cfg;
> >  	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(ioapic);
> >  
> > +	size = sizeof(struct mp_pin_info) * mp_ioapic_pin_count(ioapic);
> > +	ip->pin_info = kzalloc(size, GFP_KERNEL);
> > +	if (!ip->pin_info)
> > +		return -ENOMEM;
> > +
> >  	if (cfg->type == IOAPIC_DOMAIN_INVALID)
> >  		return 0;
> >  
> >  	ip->irqdomain = irq_domain_add_linear(cfg->dev, hwirqs, cfg->ops,
> >  					      (void *)(long)ioapic);
> > -	if(!ip->irqdomain)
> > +	if(!ip->irqdomain) {
> > +		kfree(ip->pin_info);
> > +		ip->pin_info = NULL;
> >  		return -ENOMEM;
> > +	}
> >  
> >  	if (cfg->type == IOAPIC_DOMAIN_LEGACY ||
> >  	    cfg->type == IOAPIC_DOMAIN_STRICT)
> > @@ -3898,6 +3929,72 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base,
> >  	nr_ioapics++;
> >  }
> >  
> > +int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
> > +		     irq_hw_number_t hwirq)
> > +{
> > +	int ioapic = (int)(long)domain->host_data;
> > +	struct mp_pin_info *info = mp_pin_info(ioapic, hwirq);
> > +	struct io_apic_irq_attr attr;
> > +
> > +	/*
> > +	 * Skip the timer IRQ if there's a quirk handler installed and if it
> > +	 * returns 1:
> > +	 */
> > +	if (apic->multi_timer_check &&
> > +	    apic->multi_timer_check(ioapic, virq))
> > +		return 0;
> > +
> > +	/* Get default attribute if not set by caller yet */
> > +	if (!info->set) {
> > +		u32 gsi = mp_pin_to_gsi(ioapic, hwirq);
> > +
> > +		if (acpi_get_override_irq(gsi, &info->trigger,
> > +					  &info->polarity) < 0) {
> 
> Sadly this seems to break LPSS ACPI enumerated devices.
> 
> Before this change /proc/interrupts say:
> 
>    0:         14          0          0          0   IO-APIC-edge      timer
>    1:         10          0          0          0   IO-APIC-edge      i8042
>    4:         79          0          0          0   IO-APIC-edge      serial
>    5:         52          0          0          0   IO-APIC-fasteoi   mmc0
>    6:          0          0          0          0   IO-APIC-fasteoi   dw_dmac
>    7:          0          0          0          0   IO-APIC-fasteoi   INT3432:00, INT3433:00
>    8:          1          0          0          0   IO-APIC-edge      rtc0
>    9:        174          0          0          0   IO-APIC-fasteoi   acpi
>   57:        476          0          0          0   PCI-MSI-edge      xhci_hcd
>   58:         17          0          0          0   PCI-MSI-edge      snd_hda_intel
> 
> After the change it looks like this:
> 
>   0:         14          0          0          0   IO-APIC-edge      timer
>   1:         10          0          0          0   IO-APIC-edge      i8042
>   4:         64          0          0          0   IO-APIC-edge      serial
>   5:          0          0          0          0   IO-APIC-edge      mmc0
>   6:          0          0          0          0   IO-APIC-edge      dw_dmac
>   7:          0          0          0          0   IO-APIC-edge      INT3432:00, INT3433:00
>   8:          1          0          0          0   IO-APIC-edge      rtc0
>   9:        173          0          0          0   IO-APIC-fasteoi   acpi
>  41:        471          0          0          0   PCI-MSI-edge      xhci_hcd
>  42:         17          0          0          0   PCI-MSI-edge      snd_hda_intel
> 
> Notice the interrupt triggering of IRQs 5, 6, and 7 has changed from level to
> edge. I also see this printed on the console:
> 
> [    1.676685] Failed to set pin attr for GSI6
> [    1.691708] Failed to set pin attr for GSI7
> [    1.706750] Failed to set pin attr for GSI7
> [    1.721768] Failed to set pin attr for GSI13
> [    1.736765] Failed to set pin attr for GSI5
> [    1.838342] Failed to set pin attr for GSI6
> 
> Any ideas how to get that fixed?
> 
> We used to handle this in drivers/acpi/resource.c:acpi_dev_get_irqresource() so
> that only IRQ() and IRQNoFlags() ACPI resources resort calling
> acpi_get_override_irq(). Now that doesn't help anymore.

There's also a bugzilla bug filed about this here where touchpad stopped
working:

https://bugzilla.kernel.org/show_bug.cgi?id=82601

  reply	other threads:[~2014-08-21 16:57 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-09  8:19 [Patch V4 00/42] use irqdomain to dynamically allocate IRQ for IOAPIC Jiang Liu
2014-06-09  8:19 ` [Patch V4 01/42] x86, irq: update high address field when updating affinity for MSI IRQ Jiang Liu
2014-06-09 23:46   ` Yinghai Lu
2014-06-10  2:54     ` Jiang Liu
2014-06-10  0:22   ` David Rientjes
2014-06-09  8:19 ` [Patch V4 02/42] x86, mpparse: use pr_lvl() helper utilities to replace printk(KERN_LVL) Jiang Liu
2014-06-09  8:19 ` [Patch V4 03/42] x86, mpparse: simplify arch/x86/include/asm/mpspec.h Jiang Liu
2014-06-09  8:19 ` [Patch V4 04/42] x86, acpi: reorganize code to avoid forward declaration in boot.c Jiang Liu
2014-06-09  8:19 ` [Patch V4 05/42] x86, PCI, ACPI: use kmalloc_node() to optimize for performance Jiang Liu
2014-06-09  8:19 ` [Patch V4 06/42] x86, acpi, irq: kill static function irq_to_gsi() Jiang Liu
2014-06-09  8:19 ` [Patch V4 07/42] x86, ACPI, trivial: minor improvements to arch/x86/kernel/acpi/boot.c Jiang Liu
2014-06-09  8:19 ` [Patch V4 08/42] x86, ACPI, irq: enhance error handling in function acpi_register_gsi() Jiang Liu
2014-06-09 23:19   ` Thomas Gleixner
2014-06-10  5:49     ` Jiang Liu
2014-06-10  6:11     ` Jiang Liu
2014-06-09  8:19 ` [Patch V4 09/42] x86, ACPI, irq: fix possible eror in GSI to IRQ mapping for legacy IRQ Jiang Liu
2014-06-09  8:19 ` [Patch V4 10/42] x86, irq, trivial: minor improvements of IRQ related code Jiang Liu
2014-06-09  8:19 ` [Patch V4 11/42] x86, ioapic: kill unused global variable timer_through_8259 Jiang Liu
2014-06-09 14:41   ` Maciej W. Rozycki
2014-06-10  3:20     ` Jiang Liu
2014-06-10 21:57       ` Maciej W. Rozycki
2014-06-09  8:19 ` [Patch V4 12/42] x86, ioapic: kill static variable nr_irqs_gsi Jiang Liu
2014-06-09 23:22   ` Thomas Gleixner
2014-06-10  5:31     ` Jiang Liu
2014-06-12 10:58       ` Thomas Gleixner
2014-06-12 12:40         ` Jiang Liu
2014-06-09  8:19 ` [Patch V4 13/42] x86, ioapic: introduce helper utilities to walk ioapics and pins Jiang Liu
2014-06-09  8:19 ` [Patch V4 14/42] x86, ioapic: use irq_cfg() instead of irq_get_chip_data() for better readability Jiang Liu
2014-06-09  8:19 ` [Patch V4 15/42] x86, irq: reorganize IO_APIC_get_PCI_irq_vector() to prepare for irqdomain Jiang Liu
2014-06-09  8:19 ` [Patch V4 16/42] x86, irq: introduce some helper utilities to improve readability Jiang Liu
2014-06-09  8:19 ` [Patch V4 17/42] ce4100, irq: make CE4100 depend on CONFIG_X86_IO_APIC Jiang Liu
2014-06-09  8:19 ` [Patch V4 18/42] ce4100, irq: do not set legacy_pic to null_legacy_pic Jiang Liu
2014-06-09  8:19 ` [Patch V4 19/42] x86, irq: count legacy IRQs by legacy_pic->nr_legacy_irqs instead of NR_IRQS_LEGACY Jiang Liu
2014-06-10 14:18   ` [Xen-devel] " David Vrabel
2014-06-09  8:19 ` [Patch V4 20/42] x86, irq: simplify arch_early_irq_init() Jiang Liu
2014-06-09  8:19 ` [Patch V4 21/42] x86, ACPI, irq: consolidate algorithm of mapping (ioapic, pin) to IRQ number Jiang Liu
2014-06-10  6:13   ` Jiang Liu
2014-06-09  8:19 ` [Patch V4 22/42] x86, irq, ACPI: change __acpi_register_gsi to return IRQ number instead of GSI Jiang Liu
2014-06-10  6:14   ` Jiang Liu
2014-06-09  8:19 ` [Patch V4 23/42] x86, irq: introduce mechanisms to support dynamically allocate IRQ for IOAPIC Jiang Liu
2014-06-09  8:19 ` [Patch V4 24/42] x86, irq: enhance mp_register_ioapic() to support irqdomain Jiang Liu
2014-06-09  8:19 ` [Patch V4 25/42] x86, ACPI, irq: provide basic irqdomain support Jiang Liu
2014-06-09  8:19 ` [Patch V4 26/42] x86, mpparse, " Jiang Liu
2014-06-09  8:19 ` [Patch V4 27/42] x86, SFI, " Jiang Liu
2014-06-09  8:19 ` [Patch V4 28/42] x86, devicetree, irq: use common mechanism to support irqdomain Jiang Liu
2014-06-09  8:19 ` [Patch V4 29/42] x86, irq: introduce two helper functions to support irqdomain map operation Jiang Liu
2014-08-21 14:17   ` Mika Westerberg
2014-08-21 16:57     ` Mika Westerberg [this message]
2014-08-21 19:00       ` Jiang Liu
2014-08-22 12:41         ` Mika Westerberg
2014-08-26  8:45           ` [Bugfix] x86, irq: Fix bug in setting IOAPIC pin attributes Jiang Liu
2014-08-26  9:52             ` Mika Westerberg
2014-08-26 21:20               ` Thomas Gleixner
2014-08-27  5:53               ` Jiang Liu
2014-08-27  8:04                 ` Mika Westerberg
2014-08-26 18:55             ` Randy Dunlap
2014-06-09  8:19 ` [Patch V4 30/42] x86, irq, ACPI: use common irqdomain map interface to program IOAPIC pins Jiang Liu
2014-06-09  8:20 ` [Patch V4 31/42] x86, irq, mpparse: " Jiang Liu
2014-06-09  8:20 ` [Patch V4 32/42] x86, irq, SFI: " Jiang Liu
2014-06-09  8:20 ` [Patch V4 33/42] x86, irq, devicetree: " Jiang Liu
2014-06-09  8:20 ` [Patch V4 34/42] x86, irq: clean up unused IOAPIC interface Jiang Liu
2014-06-09  8:20 ` [Patch V4 35/42] x86, irq: simplify the way to handle ISA IRQ Jiang Liu
2014-06-09  8:20 ` [Patch V4 36/42] genirq: export irq_domain_disassociate() to architecture interrupt drivers Jiang Liu
2014-06-09  8:20 ` [Patch V4 37/42] x86, irq: introduce helper functions to release IOAPIC pin Jiang Liu
2014-06-09  8:20 ` [Patch V4 38/42] x86, irq, ACPI: release IOAPIC pin when PCI device is disabled Jiang Liu
2014-06-10  6:16   ` Jiang Liu
2014-06-09  8:20 ` [Patch V4 39/42] x86, irq, mpparse: " Jiang Liu
2014-06-09  8:20 ` [Patch V4 40/42] x86, irq, SFI: " Jiang Liu
2014-06-09  8:20 ` [Patch V4 41/42] x86, irq, devicetree: " Jiang Liu
2014-06-09  8:20 ` [Patch V4 42/42] x86, irq: clean up irqdomain transition code Jiang Liu
2014-06-21 21:08 ` [Patch V4 00/42] use irqdomain to dynamically allocate IRQ for IOAPIC Thomas Gleixner
2014-06-27  3:36   ` Yinghai Lu
2014-06-22  8:42 ` Ingo Molnar
2014-06-22 14:39   ` Feng Tang
2014-06-22 15:02     ` Feng Tang

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=20140821165728.GV1660@lahna.fi.intel.com \
    --to=mika.westerberg@linux.intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=benh@kernel.crashing.org \
    --cc=bhelgaas@google.com \
    --cc=grant.likely@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=jiang.liu@linux.intel.com \
    --cc=joro@8bytes.org \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=paul.gortmaker@windriver.com \
    --cc=rdunlap@infradead.org \
    --cc=rjw@rjwysocki.net \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.org \
    --cc=yinghai@kernel.org \
    /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