Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
On Tue, Oct 25, 2016 at 11:09:26PM +0800, Hanjun Guo wrote: > From: Hanjun Guo> > In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, > > Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, > ResourceSourceIndex, ResourceSource, DescriptorName) > { InterruptList } => Buffer > > For the arguement ResourceUsage and DescriptorName, which means: > > ResourceUsage describes whether the device consumes the specified > interrupt ( ResourceConsumer ) or produces it for use by a child > device ( ResourceProducer ). > If nothing is specified, then ResourceConsumer is assumed. > > DescriptorName evaluates to a name string which refers to the > entire resource descriptor. > > So it can be used for devices connecting to a specific interrupt > prodcucer instead of the main interrupt controller in MADT. In the > real world, we have irqchip such as mbi-gen which connecting to > a group of wired interrupts and then issue msi to the ITS, devices > connecting to such interrupt controller fit this scope. > > For now the irq for ACPI only pointer to the main interrupt > controller's irqdomain, for devices not connecting to those > irqdomains, which need to present its irq parent, we can use > following ASL code to represent it: > > Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} > > then we can parse the interrupt producer with the full > path name "\_SB.IRQP". > > In order to do that, we introduce a pointer interrupt_producer > in struct acpi_device, and fill it when scanning irq resources > for acpi device if it specifies the interrupt producer. > > But for now when parsing the resources for acpi devices, we don't > pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, > so introduce a adev in struct res_proc_context to pass it as a context > to scan the interrupt resources, then finally pass to acpi_register_gsi() > to find its interrupt producer to get the virq from diffrent domains. > > With steps above ready, rework acpi_register_gsi() to get other > interrupt producer if devices not connecting to main interrupt > controller. > > Since we often pass NULL to acpi_register_gsi() and there is no interrupt > producer for devices connect to gicd on ARM or io-apic on X86, so it will > use the default irqdomain for those deivces and no functional changes to > those devices. > > Signed-off-by: Hanjun Guo > Cc: Rafael J. Wysocki > Cc: Marc Zyngier > Cc: Agustin Vega-Frias > Cc: Lorenzo Pieralisi > --- > drivers/acpi/gsi.c | 10 -- > drivers/acpi/resource.c | 85 > ++--- > include/acpi/acpi_bus.h | 1 + > 3 files changed, 68 insertions(+), 28 deletions(-) > > diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c > index ee9e0f2..29ee547 100644 > --- a/drivers/acpi/gsi.c > +++ b/drivers/acpi/gsi.c > @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int > trigger, > int polarity) > { > struct irq_fwspec fwspec; > + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; > > - if (WARN_ON(!acpi_gsi_domain_id)) { > + if (adev && >fwnode && adev->interrupt_producer) > + /* devices in DSDT connecting to spefic interrupt producer */ > + fwspec.fwnode = adev->interrupt_producer; > + else if (acpi_gsi_domain_id) > + /* devices connecting to gicd in default */ > + fwspec.fwnode = acpi_gsi_domain_id; > + else { > pr_warn("GSI: No registered irqchip, giving up\n"); > return -EINVAL; > } > > - fwspec.fwnode = acpi_gsi_domain_id; > fwspec.param[0] = gsi; > fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); > fwspec.param_count = 2; > diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c > index 56241eb..f1371cf 100644 > --- a/drivers/acpi/resource.c > +++ b/drivers/acpi/resource.c > @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource > *res, u32 gsi) > res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; > } > > -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, > +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct > resource *res, u32 gsi, >u8 triggering, u8 polarity, u8 shareable, >bool legacy) > { > @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource > *res, u32 gsi, > } > > res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); > - irq = acpi_register_gsi(NULL, gsi, triggering, polarity); > + irq = acpi_register_gsi(>dev, gsi, triggering, polarity); > if (irq >= 0) { > res->start = irq; > res->end = irq; > @@ -424,27 +424,9 @@
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
On Tue, Oct 25, 2016 at 11:09:26PM +0800, Hanjun Guo wrote: > From: Hanjun Guo > > In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, > > Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, > ResourceSourceIndex, ResourceSource, DescriptorName) > { InterruptList } => Buffer > > For the arguement ResourceUsage and DescriptorName, which means: > > ResourceUsage describes whether the device consumes the specified > interrupt ( ResourceConsumer ) or produces it for use by a child > device ( ResourceProducer ). > If nothing is specified, then ResourceConsumer is assumed. > > DescriptorName evaluates to a name string which refers to the > entire resource descriptor. > > So it can be used for devices connecting to a specific interrupt > prodcucer instead of the main interrupt controller in MADT. In the > real world, we have irqchip such as mbi-gen which connecting to > a group of wired interrupts and then issue msi to the ITS, devices > connecting to such interrupt controller fit this scope. > > For now the irq for ACPI only pointer to the main interrupt > controller's irqdomain, for devices not connecting to those > irqdomains, which need to present its irq parent, we can use > following ASL code to represent it: > > Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} > > then we can parse the interrupt producer with the full > path name "\_SB.IRQP". > > In order to do that, we introduce a pointer interrupt_producer > in struct acpi_device, and fill it when scanning irq resources > for acpi device if it specifies the interrupt producer. > > But for now when parsing the resources for acpi devices, we don't > pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, > so introduce a adev in struct res_proc_context to pass it as a context > to scan the interrupt resources, then finally pass to acpi_register_gsi() > to find its interrupt producer to get the virq from diffrent domains. > > With steps above ready, rework acpi_register_gsi() to get other > interrupt producer if devices not connecting to main interrupt > controller. > > Since we often pass NULL to acpi_register_gsi() and there is no interrupt > producer for devices connect to gicd on ARM or io-apic on X86, so it will > use the default irqdomain for those deivces and no functional changes to > those devices. > > Signed-off-by: Hanjun Guo > Cc: Rafael J. Wysocki > Cc: Marc Zyngier > Cc: Agustin Vega-Frias > Cc: Lorenzo Pieralisi > --- > drivers/acpi/gsi.c | 10 -- > drivers/acpi/resource.c | 85 > ++--- > include/acpi/acpi_bus.h | 1 + > 3 files changed, 68 insertions(+), 28 deletions(-) > > diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c > index ee9e0f2..29ee547 100644 > --- a/drivers/acpi/gsi.c > +++ b/drivers/acpi/gsi.c > @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int > trigger, > int polarity) > { > struct irq_fwspec fwspec; > + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; > > - if (WARN_ON(!acpi_gsi_domain_id)) { > + if (adev && >fwnode && adev->interrupt_producer) > + /* devices in DSDT connecting to spefic interrupt producer */ > + fwspec.fwnode = adev->interrupt_producer; > + else if (acpi_gsi_domain_id) > + /* devices connecting to gicd in default */ > + fwspec.fwnode = acpi_gsi_domain_id; > + else { > pr_warn("GSI: No registered irqchip, giving up\n"); > return -EINVAL; > } > > - fwspec.fwnode = acpi_gsi_domain_id; > fwspec.param[0] = gsi; > fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); > fwspec.param_count = 2; > diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c > index 56241eb..f1371cf 100644 > --- a/drivers/acpi/resource.c > +++ b/drivers/acpi/resource.c > @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource > *res, u32 gsi) > res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; > } > > -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, > +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct > resource *res, u32 gsi, >u8 triggering, u8 polarity, u8 shareable, >bool legacy) > { > @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource > *res, u32 gsi, > } > > res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); > - irq = acpi_register_gsi(NULL, gsi, triggering, polarity); > + irq = acpi_register_gsi(>dev, gsi, triggering, polarity); > if (irq >= 0) { > res->start = irq; > res->end = irq; > @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource > *res, u32 gsi, > } > } > > -/** > - * acpi_dev_resource_interrupt - Extract
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hi Aleksey, On 2016/12/1 19:12, Aleksey Makarov wrote: Hi Hanjun, On 10/25/2016 09:09 PM, Hanjun Guo wrote: From: Hanjun GuoIn ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, [ ... ] --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; +struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; Why are you sure dev is always an acpi device? Look for example at drivers/acpi/pci_irq.c:377 where this function is called for a PCI device Good catch, but I will drop this patch and use Agustin's one [1]. [1]: https://mail-archive.com/linux-kernel@vger.kernel.org/msg1283116.html Thanks Hanjun
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hi Aleksey, On 2016/12/1 19:12, Aleksey Makarov wrote: Hi Hanjun, On 10/25/2016 09:09 PM, Hanjun Guo wrote: From: Hanjun Guo In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, [ ... ] --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; +struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; Why are you sure dev is always an acpi device? Look for example at drivers/acpi/pci_irq.c:377 where this function is called for a PCI device Good catch, but I will drop this patch and use Agustin's one [1]. [1]: https://mail-archive.com/linux-kernel@vger.kernel.org/msg1283116.html Thanks Hanjun
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hi Hanjun, On 10/25/2016 09:09 PM, Hanjun Guo wrote: From: Hanjun GuoIn ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, [ ... ] --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; Why are you sure dev is always an acpi device? Look for example at drivers/acpi/pci_irq.c:377 where this function is called for a PCI device - if (WARN_ON(!acpi_gsi_domain_id)) { + if (adev && >fwnode && adev->interrupt_producer) >fwnode is always true + /* devices in DSDT connecting to spefic interrupt producer */ + fwspec.fwnode = adev->interrupt_producer; + else if (acpi_gsi_domain_id) + /* devices connecting to gicd in default */ + fwspec.fwnode = acpi_gsi_domain_id; + else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } [ ... ] All the best Aleksey Makarov
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hi Hanjun, On 10/25/2016 09:09 PM, Hanjun Guo wrote: From: Hanjun Guo In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, [ ... ] --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; Why are you sure dev is always an acpi device? Look for example at drivers/acpi/pci_irq.c:377 where this function is called for a PCI device - if (WARN_ON(!acpi_gsi_domain_id)) { + if (adev && >fwnode && adev->interrupt_producer) >fwnode is always true + /* devices in DSDT connecting to spefic interrupt producer */ + fwspec.fwnode = adev->interrupt_producer; + else if (acpi_gsi_domain_id) + /* devices connecting to gicd in default */ + fwspec.fwnode = acpi_gsi_domain_id; + else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } [ ... ] All the best Aleksey Makarov
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hi Agustin, Sorry for the late reply, on travailing for now. On 10/29/2016 03:32 AM, agust...@codeaurora.org wrote: Hey Hanjun, On 2016-10-25 11:09, Hanjun Guo wrote: From: Hanjun GuoIn ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, ResourceSourceIndex, ResourceSource, DescriptorName) { InterruptList } => Buffer For the arguement ResourceUsage and DescriptorName, which means: ResourceUsage describes whether the device consumes the specified interrupt ( ResourceConsumer ) or produces it for use by a child device ( ResourceProducer ). If nothing is specified, then ResourceConsumer is assumed. DescriptorName evaluates to a name string which refers to the entire resource descriptor. So it can be used for devices connecting to a specific interrupt prodcucer instead of the main interrupt controller in MADT. In the real world, we have irqchip such as mbi-gen which connecting to a group of wired interrupts and then issue msi to the ITS, devices connecting to such interrupt controller fit this scope. For now the irq for ACPI only pointer to the main interrupt controller's irqdomain, for devices not connecting to those irqdomains, which need to present its irq parent, we can use following ASL code to represent it: Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} then we can parse the interrupt producer with the full path name "\_SB.IRQP". In order to do that, we introduce a pointer interrupt_producer in struct acpi_device, and fill it when scanning irq resources for acpi device if it specifies the interrupt producer. But for now when parsing the resources for acpi devices, we don't pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, so introduce a adev in struct res_proc_context to pass it as a context to scan the interrupt resources, then finally pass to acpi_register_gsi() to find its interrupt producer to get the virq from diffrent domains. With steps above ready, rework acpi_register_gsi() to get other interrupt producer if devices not connecting to main interrupt controller. Since we often pass NULL to acpi_register_gsi() and there is no interrupt producer for devices connect to gicd on ARM or io-apic on X86, so it will use the default irqdomain for those deivces and no functional changes to those devices. Signed-off-by: Hanjun Guo Cc: Rafael J. Wysocki Cc: Marc Zyngier Cc: Agustin Vega-Frias Cc: Lorenzo Pieralisi --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; +struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; -if (WARN_ON(!acpi_gsi_domain_id)) { +if (adev && >fwnode && adev->interrupt_producer) +/* devices in DSDT connecting to spefic interrupt producer */ +fwspec.fwnode = adev->interrupt_producer; +else if (acpi_gsi_domain_id) +/* devices connecting to gicd in default */ +fwspec.fwnode = acpi_gsi_domain_id; +else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } -fwspec.fwnode = acpi_gsi_domain_id; fwspec.param[0] = gsi; fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb..f1371cf 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, bool legacy) { @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); -irq = acpi_register_gsi(NULL, gsi, triggering, polarity); +irq = acpi_register_gsi(>dev, gsi, triggering, polarity); if (irq >= 0) { res->start = irq; res->end = irq; @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } } -/** - * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. - * @ares: Input ACPI resource object. - * @index: Index
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hi Agustin, Sorry for the late reply, on travailing for now. On 10/29/2016 03:32 AM, agust...@codeaurora.org wrote: Hey Hanjun, On 2016-10-25 11:09, Hanjun Guo wrote: From: Hanjun Guo In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, ResourceSourceIndex, ResourceSource, DescriptorName) { InterruptList } => Buffer For the arguement ResourceUsage and DescriptorName, which means: ResourceUsage describes whether the device consumes the specified interrupt ( ResourceConsumer ) or produces it for use by a child device ( ResourceProducer ). If nothing is specified, then ResourceConsumer is assumed. DescriptorName evaluates to a name string which refers to the entire resource descriptor. So it can be used for devices connecting to a specific interrupt prodcucer instead of the main interrupt controller in MADT. In the real world, we have irqchip such as mbi-gen which connecting to a group of wired interrupts and then issue msi to the ITS, devices connecting to such interrupt controller fit this scope. For now the irq for ACPI only pointer to the main interrupt controller's irqdomain, for devices not connecting to those irqdomains, which need to present its irq parent, we can use following ASL code to represent it: Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} then we can parse the interrupt producer with the full path name "\_SB.IRQP". In order to do that, we introduce a pointer interrupt_producer in struct acpi_device, and fill it when scanning irq resources for acpi device if it specifies the interrupt producer. But for now when parsing the resources for acpi devices, we don't pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, so introduce a adev in struct res_proc_context to pass it as a context to scan the interrupt resources, then finally pass to acpi_register_gsi() to find its interrupt producer to get the virq from diffrent domains. With steps above ready, rework acpi_register_gsi() to get other interrupt producer if devices not connecting to main interrupt controller. Since we often pass NULL to acpi_register_gsi() and there is no interrupt producer for devices connect to gicd on ARM or io-apic on X86, so it will use the default irqdomain for those deivces and no functional changes to those devices. Signed-off-by: Hanjun Guo Cc: Rafael J. Wysocki Cc: Marc Zyngier Cc: Agustin Vega-Frias Cc: Lorenzo Pieralisi --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; +struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; -if (WARN_ON(!acpi_gsi_domain_id)) { +if (adev && >fwnode && adev->interrupt_producer) +/* devices in DSDT connecting to spefic interrupt producer */ +fwspec.fwnode = adev->interrupt_producer; +else if (acpi_gsi_domain_id) +/* devices connecting to gicd in default */ +fwspec.fwnode = acpi_gsi_domain_id; +else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } -fwspec.fwnode = acpi_gsi_domain_id; fwspec.param[0] = gsi; fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb..f1371cf 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, bool legacy) { @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); -irq = acpi_register_gsi(NULL, gsi, triggering, polarity); +irq = acpi_register_gsi(>dev, gsi, triggering, polarity); if (irq >= 0) { res->start = irq; res->end = irq; @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } } -/** - * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. - * @ares: Input ACPI resource object. - * @index: Index into the array of GSIs represented by the resource. - * @res: Output generic resource object. - * - * Check if the given ACPI resource
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hey Hanjun, On 2016-10-25 11:09, Hanjun Guo wrote: From: Hanjun GuoIn ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, ResourceSourceIndex, ResourceSource, DescriptorName) { InterruptList } => Buffer For the arguement ResourceUsage and DescriptorName, which means: ResourceUsage describes whether the device consumes the specified interrupt ( ResourceConsumer ) or produces it for use by a child device ( ResourceProducer ). If nothing is specified, then ResourceConsumer is assumed. DescriptorName evaluates to a name string which refers to the entire resource descriptor. So it can be used for devices connecting to a specific interrupt prodcucer instead of the main interrupt controller in MADT. In the real world, we have irqchip such as mbi-gen which connecting to a group of wired interrupts and then issue msi to the ITS, devices connecting to such interrupt controller fit this scope. For now the irq for ACPI only pointer to the main interrupt controller's irqdomain, for devices not connecting to those irqdomains, which need to present its irq parent, we can use following ASL code to represent it: Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} then we can parse the interrupt producer with the full path name "\_SB.IRQP". In order to do that, we introduce a pointer interrupt_producer in struct acpi_device, and fill it when scanning irq resources for acpi device if it specifies the interrupt producer. But for now when parsing the resources for acpi devices, we don't pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, so introduce a adev in struct res_proc_context to pass it as a context to scan the interrupt resources, then finally pass to acpi_register_gsi() to find its interrupt producer to get the virq from diffrent domains. With steps above ready, rework acpi_register_gsi() to get other interrupt producer if devices not connecting to main interrupt controller. Since we often pass NULL to acpi_register_gsi() and there is no interrupt producer for devices connect to gicd on ARM or io-apic on X86, so it will use the default irqdomain for those deivces and no functional changes to those devices. Signed-off-by: Hanjun Guo Cc: Rafael J. Wysocki Cc: Marc Zyngier Cc: Agustin Vega-Frias Cc: Lorenzo Pieralisi --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; - if (WARN_ON(!acpi_gsi_domain_id)) { + if (adev && >fwnode && adev->interrupt_producer) + /* devices in DSDT connecting to spefic interrupt producer */ + fwspec.fwnode = adev->interrupt_producer; + else if (acpi_gsi_domain_id) + /* devices connecting to gicd in default */ + fwspec.fwnode = acpi_gsi_domain_id; + else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } - fwspec.fwnode = acpi_gsi_domain_id; fwspec.param[0] = gsi; fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb..f1371cf 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, bool legacy) { @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); - irq = acpi_register_gsi(NULL, gsi, triggering, polarity); + irq = acpi_register_gsi(>dev, gsi, triggering, polarity); if (irq >= 0) { res->start = irq; res->end = irq; @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } } -/** - * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. - * @ares: Input
Re: [PATCH v3 11/14] ACPI: irq: introduce interrupt producer
Hey Hanjun, On 2016-10-25 11:09, Hanjun Guo wrote: From: Hanjun Guo In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, ResourceSourceIndex, ResourceSource, DescriptorName) { InterruptList } => Buffer For the arguement ResourceUsage and DescriptorName, which means: ResourceUsage describes whether the device consumes the specified interrupt ( ResourceConsumer ) or produces it for use by a child device ( ResourceProducer ). If nothing is specified, then ResourceConsumer is assumed. DescriptorName evaluates to a name string which refers to the entire resource descriptor. So it can be used for devices connecting to a specific interrupt prodcucer instead of the main interrupt controller in MADT. In the real world, we have irqchip such as mbi-gen which connecting to a group of wired interrupts and then issue msi to the ITS, devices connecting to such interrupt controller fit this scope. For now the irq for ACPI only pointer to the main interrupt controller's irqdomain, for devices not connecting to those irqdomains, which need to present its irq parent, we can use following ASL code to represent it: Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} then we can parse the interrupt producer with the full path name "\_SB.IRQP". In order to do that, we introduce a pointer interrupt_producer in struct acpi_device, and fill it when scanning irq resources for acpi device if it specifies the interrupt producer. But for now when parsing the resources for acpi devices, we don't pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, so introduce a adev in struct res_proc_context to pass it as a context to scan the interrupt resources, then finally pass to acpi_register_gsi() to find its interrupt producer to get the virq from diffrent domains. With steps above ready, rework acpi_register_gsi() to get other interrupt producer if devices not connecting to main interrupt controller. Since we often pass NULL to acpi_register_gsi() and there is no interrupt producer for devices connect to gicd on ARM or io-apic on X86, so it will use the default irqdomain for those deivces and no functional changes to those devices. Signed-off-by: Hanjun Guo Cc: Rafael J. Wysocki Cc: Marc Zyngier Cc: Agustin Vega-Frias Cc: Lorenzo Pieralisi --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; - if (WARN_ON(!acpi_gsi_domain_id)) { + if (adev && >fwnode && adev->interrupt_producer) + /* devices in DSDT connecting to spefic interrupt producer */ + fwspec.fwnode = adev->interrupt_producer; + else if (acpi_gsi_domain_id) + /* devices connecting to gicd in default */ + fwspec.fwnode = acpi_gsi_domain_id; + else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } - fwspec.fwnode = acpi_gsi_domain_id; fwspec.param[0] = gsi; fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb..f1371cf 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, bool legacy) { @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); - irq = acpi_register_gsi(NULL, gsi, triggering, polarity); + irq = acpi_register_gsi(>dev, gsi, triggering, polarity); if (irq >= 0) { res->start = irq; res->end = irq; @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } } -/** - * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. - * @ares: Input ACPI resource object. - * @index: Index into the array of GSIs represented by the resource. - * @res: Output generic resource object. - * -
[PATCH v3 11/14] ACPI: irq: introduce interrupt producer
From: Hanjun GuoIn ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, ResourceSourceIndex, ResourceSource, DescriptorName) { InterruptList } => Buffer For the arguement ResourceUsage and DescriptorName, which means: ResourceUsage describes whether the device consumes the specified interrupt ( ResourceConsumer ) or produces it for use by a child device ( ResourceProducer ). If nothing is specified, then ResourceConsumer is assumed. DescriptorName evaluates to a name string which refers to the entire resource descriptor. So it can be used for devices connecting to a specific interrupt prodcucer instead of the main interrupt controller in MADT. In the real world, we have irqchip such as mbi-gen which connecting to a group of wired interrupts and then issue msi to the ITS, devices connecting to such interrupt controller fit this scope. For now the irq for ACPI only pointer to the main interrupt controller's irqdomain, for devices not connecting to those irqdomains, which need to present its irq parent, we can use following ASL code to represent it: Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} then we can parse the interrupt producer with the full path name "\_SB.IRQP". In order to do that, we introduce a pointer interrupt_producer in struct acpi_device, and fill it when scanning irq resources for acpi device if it specifies the interrupt producer. But for now when parsing the resources for acpi devices, we don't pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, so introduce a adev in struct res_proc_context to pass it as a context to scan the interrupt resources, then finally pass to acpi_register_gsi() to find its interrupt producer to get the virq from diffrent domains. With steps above ready, rework acpi_register_gsi() to get other interrupt producer if devices not connecting to main interrupt controller. Since we often pass NULL to acpi_register_gsi() and there is no interrupt producer for devices connect to gicd on ARM or io-apic on X86, so it will use the default irqdomain for those deivces and no functional changes to those devices. Signed-off-by: Hanjun Guo Cc: Rafael J. Wysocki Cc: Marc Zyngier Cc: Agustin Vega-Frias Cc: Lorenzo Pieralisi --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; - if (WARN_ON(!acpi_gsi_domain_id)) { + if (adev && >fwnode && adev->interrupt_producer) + /* devices in DSDT connecting to spefic interrupt producer */ + fwspec.fwnode = adev->interrupt_producer; + else if (acpi_gsi_domain_id) + /* devices connecting to gicd in default */ + fwspec.fwnode = acpi_gsi_domain_id; + else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } - fwspec.fwnode = acpi_gsi_domain_id; fwspec.param[0] = gsi; fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb..f1371cf 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, bool legacy) { @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); - irq = acpi_register_gsi(NULL, gsi, triggering, polarity); + irq = acpi_register_gsi(>dev, gsi, triggering, polarity); if (irq >= 0) { res->start = irq; res->end = irq; @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } } -/** - * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. - * @ares: Input ACPI resource object. - * @index: Index into the array
[PATCH v3 11/14] ACPI: irq: introduce interrupt producer
From: Hanjun Guo In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro, Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared, ResourceSourceIndex, ResourceSource, DescriptorName) { InterruptList } => Buffer For the arguement ResourceUsage and DescriptorName, which means: ResourceUsage describes whether the device consumes the specified interrupt ( ResourceConsumer ) or produces it for use by a child device ( ResourceProducer ). If nothing is specified, then ResourceConsumer is assumed. DescriptorName evaluates to a name string which refers to the entire resource descriptor. So it can be used for devices connecting to a specific interrupt prodcucer instead of the main interrupt controller in MADT. In the real world, we have irqchip such as mbi-gen which connecting to a group of wired interrupts and then issue msi to the ITS, devices connecting to such interrupt controller fit this scope. For now the irq for ACPI only pointer to the main interrupt controller's irqdomain, for devices not connecting to those irqdomains, which need to present its irq parent, we can use following ASL code to represent it: Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,} then we can parse the interrupt producer with the full path name "\_SB.IRQP". In order to do that, we introduce a pointer interrupt_producer in struct acpi_device, and fill it when scanning irq resources for acpi device if it specifies the interrupt producer. But for now when parsing the resources for acpi devices, we don't pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c, so introduce a adev in struct res_proc_context to pass it as a context to scan the interrupt resources, then finally pass to acpi_register_gsi() to find its interrupt producer to get the virq from diffrent domains. With steps above ready, rework acpi_register_gsi() to get other interrupt producer if devices not connecting to main interrupt controller. Since we often pass NULL to acpi_register_gsi() and there is no interrupt producer for devices connect to gicd on ARM or io-apic on X86, so it will use the default irqdomain for those deivces and no functional changes to those devices. Signed-off-by: Hanjun Guo Cc: Rafael J. Wysocki Cc: Marc Zyngier Cc: Agustin Vega-Frias Cc: Lorenzo Pieralisi --- drivers/acpi/gsi.c | 10 -- drivers/acpi/resource.c | 85 ++--- include/acpi/acpi_bus.h | 1 + 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c index ee9e0f2..29ee547 100644 --- a/drivers/acpi/gsi.c +++ b/drivers/acpi/gsi.c @@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { struct irq_fwspec fwspec; + struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL; - if (WARN_ON(!acpi_gsi_domain_id)) { + if (adev && >fwnode && adev->interrupt_producer) + /* devices in DSDT connecting to spefic interrupt producer */ + fwspec.fwnode = adev->interrupt_producer; + else if (acpi_gsi_domain_id) + /* devices connecting to gicd in default */ + fwspec.fwnode = acpi_gsi_domain_id; + else { pr_warn("GSI: No registered irqchip, giving up\n"); return -EINVAL; } - fwspec.fwnode = acpi_gsi_domain_id; fwspec.param[0] = gsi; fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb..f1371cf 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, +static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, bool legacy) { @@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); - irq = acpi_register_gsi(NULL, gsi, triggering, polarity); + irq = acpi_register_gsi(>dev, gsi, triggering, polarity); if (irq >= 0) { res->start = irq; res->end = irq; @@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } } -/** - * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. - * @ares: Input ACPI resource object. - * @index: Index into the array of GSIs represented by the resource. - * @res: Output generic resource object. - * - * Check if the given ACPI resource object represents an