diff mbox

[4/5] irqchip: gic-v3: Add gic_get_irq_domain() to get the irqdomain of the GIC.

Message ID 1436979285-8177-5-git-send-email-ddaney.cavm@gmail.com
State Changes Requested
Headers show

Commit Message

David Daney July 15, 2015, 4:54 p.m. UTC
From: David Daney <david.daney@cavium.com>

Needed to map SPI interrupt sources.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 drivers/irqchip/irq-gic-v3.c       | 5 +++++
 include/linux/irqchip/arm-gic-v3.h | 1 +
 2 files changed, 6 insertions(+)

Comments

Marc Zyngier July 15, 2015, 5:12 p.m. UTC | #1
On 15/07/15 17:54, David Daney wrote:
> From: David Daney <david.daney@cavium.com>
> 
> Needed to map SPI interrupt sources.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>
> ---
>  drivers/irqchip/irq-gic-v3.c       | 5 +++++
>  include/linux/irqchip/arm-gic-v3.h | 1 +
>  2 files changed, 6 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c52f7ba..0019fed 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -58,6 +58,11 @@ static struct gic_chip_data gic_data __read_mostly;
>  /* Our default, arbitrary priority value. Linux only uses one anyway. */
>  #define DEFAULT_PMR_VALUE	0xf0
>  
> +struct irq_domain *gic_get_irq_domain(void)
> +{
> +	return gic_data.domain;
> +}
> +
>  static inline unsigned int gic_irq(struct irq_data *d)
>  {
>  	return d->hwirq;
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index 18e3757..5992224 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -391,6 +391,7 @@ int its_init(struct device_node *node, struct rdists *rdists,
>  
>  typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
>  void set_its_pci_requester_id(its_pci_requester_id_t fn);
> +struct irq_domain *gic_get_irq_domain(void);
>  #endif
>  
>  #endif
> 

Hmmmffff... You need the domain for SPIs??

What is wrong with putting these interrupts in your device tree?

	M.
David Daney July 15, 2015, 6:57 p.m. UTC | #2
On 07/15/2015 10:12 AM, Marc Zyngier wrote:
> On 15/07/15 17:54, David Daney wrote:
>> From: David Daney <david.daney@cavium.com>
>>
>> Needed to map SPI interrupt sources.
>>
>> Signed-off-by: David Daney <david.daney@cavium.com>
>> ---
>>   drivers/irqchip/irq-gic-v3.c       | 5 +++++
>>   include/linux/irqchip/arm-gic-v3.h | 1 +
>>   2 files changed, 6 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index c52f7ba..0019fed 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -58,6 +58,11 @@ static struct gic_chip_data gic_data __read_mostly;
>>   /* Our default, arbitrary priority value. Linux only uses one anyway. */
>>   #define DEFAULT_PMR_VALUE	0xf0
>>
>> +struct irq_domain *gic_get_irq_domain(void)
>> +{
>> +	return gic_data.domain;
>> +}
>> +
>>   static inline unsigned int gic_irq(struct irq_data *d)
>>   {
>>   	return d->hwirq;
>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>> index 18e3757..5992224 100644
>> --- a/include/linux/irqchip/arm-gic-v3.h
>> +++ b/include/linux/irqchip/arm-gic-v3.h
>> @@ -391,6 +391,7 @@ int its_init(struct device_node *node, struct rdists *rdists,
>>
>>   typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
>>   void set_its_pci_requester_id(its_pci_requester_id_t fn);
>> +struct irq_domain *gic_get_irq_domain(void);
>>   #endif
>>
>>   #endif
>>
>
> Hmmmffff... You need the domain for SPIs??
>
> What is wrong with putting these interrupts in your device tree?
>

There is no device tree node for ECAM based "PCIe" devices, they are 
discovered in the PCI bus scan, yet they still need to use SPI interrupts.

We need a way to be able to map these.

David Daney



> 	M.
>

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Marc Zyngier July 16, 2015, 7:38 a.m. UTC | #3
On 15/07/15 19:57, David Daney wrote:
> On 07/15/2015 10:12 AM, Marc Zyngier wrote:
>> On 15/07/15 17:54, David Daney wrote:
>>> From: David Daney <david.daney@cavium.com>
>>>
>>> Needed to map SPI interrupt sources.
>>>
>>> Signed-off-by: David Daney <david.daney@cavium.com>
>>> ---
>>>   drivers/irqchip/irq-gic-v3.c       | 5 +++++
>>>   include/linux/irqchip/arm-gic-v3.h | 1 +
>>>   2 files changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>> index c52f7ba..0019fed 100644
>>> --- a/drivers/irqchip/irq-gic-v3.c
>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>> @@ -58,6 +58,11 @@ static struct gic_chip_data gic_data __read_mostly;
>>>   /* Our default, arbitrary priority value. Linux only uses one anyway. */
>>>   #define DEFAULT_PMR_VALUE	0xf0
>>>
>>> +struct irq_domain *gic_get_irq_domain(void)
>>> +{
>>> +	return gic_data.domain;
>>> +}
>>> +
>>>   static inline unsigned int gic_irq(struct irq_data *d)
>>>   {
>>>   	return d->hwirq;
>>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>>> index 18e3757..5992224 100644
>>> --- a/include/linux/irqchip/arm-gic-v3.h
>>> +++ b/include/linux/irqchip/arm-gic-v3.h
>>> @@ -391,6 +391,7 @@ int its_init(struct device_node *node, struct rdists *rdists,
>>>
>>>   typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
>>>   void set_its_pci_requester_id(its_pci_requester_id_t fn);
>>> +struct irq_domain *gic_get_irq_domain(void);
>>>   #endif
>>>
>>>   #endif
>>>
>>
>> Hmmmffff... You need the domain for SPIs??
>>
>> What is wrong with putting these interrupts in your device tree?
>>
> 
> There is no device tree node for ECAM based "PCIe" devices, they are 
> discovered in the PCI bus scan, yet they still need to use SPI interrupts.

What is different between these and the normal legacy interrupts that
are normally expressed in the RC node using an interrupt map? Sorry if
I'm only showing my ignorance here, but I'd like to understand the exact
nature of the problem.

> We need a way to be able to map these.

However you're going to map them, it will not be by just blindly
exporting random irqdomains from an unsuspecting interrupt controller.

Patch 5 has established that you're using "virtual wire" SPIs, so we
need to work on exposing that with the normal kernel abstraction, and
not by messing with the internals of the GIC.

Thanks,

	M.
David Daney July 16, 2015, 4:50 p.m. UTC | #4
On 07/16/2015 12:38 AM, Marc Zyngier wrote:
> On 15/07/15 19:57, David Daney wrote:
>> On 07/15/2015 10:12 AM, Marc Zyngier wrote:
>>> On 15/07/15 17:54, David Daney wrote:
>>>> From: David Daney <david.daney@cavium.com>
>>>>
>>>> Needed to map SPI interrupt sources.
>>>>
>>>> Signed-off-by: David Daney <david.daney@cavium.com>
>>>> ---
>>>>    drivers/irqchip/irq-gic-v3.c       | 5 +++++
>>>>    include/linux/irqchip/arm-gic-v3.h | 1 +
>>>>    2 files changed, 6 insertions(+)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>>> index c52f7ba..0019fed 100644
>>>> --- a/drivers/irqchip/irq-gic-v3.c
>>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>>> @@ -58,6 +58,11 @@ static struct gic_chip_data gic_data __read_mostly;
>>>>    /* Our default, arbitrary priority value. Linux only uses one anyway. */
>>>>    #define DEFAULT_PMR_VALUE	0xf0
>>>>
>>>> +struct irq_domain *gic_get_irq_domain(void)
>>>> +{
>>>> +	return gic_data.domain;
>>>> +}
>>>> +
>>>>    static inline unsigned int gic_irq(struct irq_data *d)
>>>>    {
>>>>    	return d->hwirq;
>>>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>>>> index 18e3757..5992224 100644
>>>> --- a/include/linux/irqchip/arm-gic-v3.h
>>>> +++ b/include/linux/irqchip/arm-gic-v3.h
>>>> @@ -391,6 +391,7 @@ int its_init(struct device_node *node, struct rdists *rdists,
>>>>
>>>>    typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
>>>>    void set_its_pci_requester_id(its_pci_requester_id_t fn);
>>>> +struct irq_domain *gic_get_irq_domain(void);
>>>>    #endif
[...]
>
>> We need a way to be able to map these.
>
> However you're going to map them, it will not be by just blindly
> exporting random irqdomains from an unsuspecting interrupt controller.

There is nothing random about it.  The ARM architects specified that 
there is exactly One True GIC in a system.  If we need to do something 
with the GIC, it is not a "random ... unsuspecting interrupt 
controller", it is *The* GIC.

>
> Patch 5 has established that you're using "virtual wire" SPIs, so we
> need to work on exposing that with the normal kernel abstraction, and
> not by messing with the internals of the GIC.
>

Agreed.

The MSI system has pci_enable_msix()/pci_disable_msix().

I would propose something like:

struct gic_spi_entry {
	int spi   /* SPI number */
	int irq;  /* kernel irq number mapped to the spi*/
	u32 msg;  /* message to be written */
	u64 assert_addr;
	u64 deassert_addr;
};

/* Fill in the SPI processing information */
int gic_map_spi(int spi, struct gic_spi_entry *data);

David Daney



> Thanks,
>
> 	M.
>

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Marc Zyngier July 16, 2015, 5:09 p.m. UTC | #5
On 16/07/15 17:50, David Daney wrote:
> On 07/16/2015 12:38 AM, Marc Zyngier wrote:
>> On 15/07/15 19:57, David Daney wrote:
>>> On 07/15/2015 10:12 AM, Marc Zyngier wrote:
>>>> On 15/07/15 17:54, David Daney wrote:
>>>>> From: David Daney <david.daney@cavium.com>
>>>>>
>>>>> Needed to map SPI interrupt sources.
>>>>>
>>>>> Signed-off-by: David Daney <david.daney@cavium.com>
>>>>> ---
>>>>>    drivers/irqchip/irq-gic-v3.c       | 5 +++++
>>>>>    include/linux/irqchip/arm-gic-v3.h | 1 +
>>>>>    2 files changed, 6 insertions(+)
>>>>>
>>>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>>>> index c52f7ba..0019fed 100644
>>>>> --- a/drivers/irqchip/irq-gic-v3.c
>>>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>>>> @@ -58,6 +58,11 @@ static struct gic_chip_data gic_data __read_mostly;
>>>>>    /* Our default, arbitrary priority value. Linux only uses one anyway. */
>>>>>    #define DEFAULT_PMR_VALUE	0xf0
>>>>>
>>>>> +struct irq_domain *gic_get_irq_domain(void)
>>>>> +{
>>>>> +	return gic_data.domain;
>>>>> +}
>>>>> +
>>>>>    static inline unsigned int gic_irq(struct irq_data *d)
>>>>>    {
>>>>>    	return d->hwirq;
>>>>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>>>>> index 18e3757..5992224 100644
>>>>> --- a/include/linux/irqchip/arm-gic-v3.h
>>>>> +++ b/include/linux/irqchip/arm-gic-v3.h
>>>>> @@ -391,6 +391,7 @@ int its_init(struct device_node *node, struct rdists *rdists,
>>>>>
>>>>>    typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
>>>>>    void set_its_pci_requester_id(its_pci_requester_id_t fn);
>>>>> +struct irq_domain *gic_get_irq_domain(void);
>>>>>    #endif
> [...]
>>
>>> We need a way to be able to map these.
>>
>> However you're going to map them, it will not be by just blindly
>> exporting random irqdomains from an unsuspecting interrupt controller.
> 
> There is nothing random about it.  The ARM architects specified that 
> there is exactly One True GIC in a system.  If we need to do something 
> with the GIC, it is not a "random ... unsuspecting interrupt 
> controller", it is *The* GIC.

Indeed. And The One True GIC Driver will not be butchered just because
you can, thank you very much.

>>
>> Patch 5 has established that you're using "virtual wire" SPIs, so we
>> need to work on exposing that with the normal kernel abstraction, and
>> not by messing with the internals of the GIC.
>>
> 
> Agreed.
> 
> The MSI system has pci_enable_msix()/pci_disable_msix().
> 
> I would propose something like:
> 
> struct gic_spi_entry {
> 	int spi   /* SPI number */
> 	int irq;  /* kernel irq number mapped to the spi*/
> 	u32 msg;  /* message to be written */
> 	u64 assert_addr;
> 	u64 deassert_addr;
> };
> 
> /* Fill in the SPI processing information */
> int gic_map_spi(int spi, struct gic_spi_entry *data);

Neither.

The way to do it is to make this a *separate* IRQ domain stacked onto
the SPI domain. No funky hook on the side. If it doesn't go through the
normal kernel API, it doesn't reach the GIC.

	M.
David Daney July 16, 2015, 5:14 p.m. UTC | #6
On 07/16/2015 10:09 AM, Marc Zyngier wrote:
> On 16/07/15 17:50, David Daney wrote:
[...]
>>> Patch 5 has established that you're using "virtual wire" SPIs, so we
>>> need to work on exposing that with the normal kernel abstraction, and
>>> not by messing with the internals of the GIC.
>>>
>>
>> Agreed.
>>
>> The MSI system has pci_enable_msix()/pci_disable_msix().
>>
>> I would propose something like:
>>
>> struct gic_spi_entry {
>> 	int spi   /* SPI number */
>> 	int irq;  /* kernel irq number mapped to the spi*/
>> 	u32 msg;  /* message to be written */
>> 	u64 assert_addr;
>> 	u64 deassert_addr;
>> };
>>
>> /* Fill in the SPI processing information */
>> int gic_map_spi(int spi, struct gic_spi_entry *data);
>
> Neither.
>
> The way to do it is to make this a *separate* IRQ domain stacked onto
> the SPI domain. No funky hook on the side. If it doesn't go through the
> normal kernel API, it doesn't reach the GIC.

Yes, the irqdomain does handle mapping SPI -> irq, and the message can 
be derived from the SPI.  However, the irqdomain infrastructure cannot 
supply values for either assert_addr or deassert_addr.

Those are needed in order to use SPI.  How would you suggest that they 
be obtained?


David Daney


>
> 	M.
>

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Marc Zyngier July 16, 2015, 5:32 p.m. UTC | #7
On 16/07/15 18:14, David Daney wrote:
> On 07/16/2015 10:09 AM, Marc Zyngier wrote:
>> On 16/07/15 17:50, David Daney wrote:
> [...]
>>>> Patch 5 has established that you're using "virtual wire" SPIs, so we
>>>> need to work on exposing that with the normal kernel abstraction, and
>>>> not by messing with the internals of the GIC.
>>>>
>>>
>>> Agreed.
>>>
>>> The MSI system has pci_enable_msix()/pci_disable_msix().
>>>
>>> I would propose something like:
>>>
>>> struct gic_spi_entry {
>>> 	int spi   /* SPI number */
>>> 	int irq;  /* kernel irq number mapped to the spi*/
>>> 	u32 msg;  /* message to be written */
>>> 	u64 assert_addr;
>>> 	u64 deassert_addr;
>>> };
>>>
>>> /* Fill in the SPI processing information */
>>> int gic_map_spi(int spi, struct gic_spi_entry *data);
>>
>> Neither.
>>
>> The way to do it is to make this a *separate* IRQ domain stacked onto
>> the SPI domain. No funky hook on the side. If it doesn't go through the
>> normal kernel API, it doesn't reach the GIC.
> 
> Yes, the irqdomain does handle mapping SPI -> irq, and the message can 
> be derived from the SPI.  However, the irqdomain infrastructure cannot 
> supply values for either assert_addr or deassert_addr.

This is why I suggested earlier (in my reply to patch 5) that you have a
look at the series I posted a couple of days ago to implement non-PCI
MSI support. This would allow you to compose the domains as such:

platform-MSI -> message-SPI -> GIC

You'd end up with a msi_msg containing the GICD_SETSPI_NSR doorbell, and
the SPI as a payload.

> Those are needed in order to use SPI.  How would you suggest that they 
> be obtained?

Two possibilities: either you derive GICD_CLRSPI_NSR by adding 8 to the
doorbell you got from the msi_msg structure (ugly, but limited to your
own code), or you extend msi_msg to cater for this case.

Thanks,

	M.
Marc Zyngier July 17, 2015, 6:45 a.m. UTC | #8
On Thu, 16 Jul 2015 18:32:28 +0100
Marc Zyngier <marc.zyngier@arm.com> wrote:

> On 16/07/15 18:14, David Daney wrote:
> > On 07/16/2015 10:09 AM, Marc Zyngier wrote:
> >> On 16/07/15 17:50, David Daney wrote:
> > [...]
> >>>> Patch 5 has established that you're using "virtual wire" SPIs, so we
> >>>> need to work on exposing that with the normal kernel abstraction, and
> >>>> not by messing with the internals of the GIC.
> >>>>
> >>>
> >>> Agreed.
> >>>
> >>> The MSI system has pci_enable_msix()/pci_disable_msix().
> >>>
> >>> I would propose something like:
> >>>
> >>> struct gic_spi_entry {
> >>> 	int spi   /* SPI number */
> >>> 	int irq;  /* kernel irq number mapped to the spi*/
> >>> 	u32 msg;  /* message to be written */
> >>> 	u64 assert_addr;
> >>> 	u64 deassert_addr;
> >>> };
> >>>
> >>> /* Fill in the SPI processing information */
> >>> int gic_map_spi(int spi, struct gic_spi_entry *data);
> >>
> >> Neither.
> >>
> >> The way to do it is to make this a *separate* IRQ domain stacked onto
> >> the SPI domain. No funky hook on the side. If it doesn't go through the
> >> normal kernel API, it doesn't reach the GIC.
> > 
> > Yes, the irqdomain does handle mapping SPI -> irq, and the message can 
> > be derived from the SPI.  However, the irqdomain infrastructure cannot 
> > supply values for either assert_addr or deassert_addr.
> 
> This is why I suggested earlier (in my reply to patch 5) that you have a
> look at the series I posted a couple of days ago to implement non-PCI
> MSI support. This would allow you to compose the domains as such:
> 
> platform-MSI -> message-SPI -> GIC
> 
> You'd end up with a msi_msg containing the GICD_SETSPI_NSR doorbell, and
> the SPI as a payload.
> 
> > Those are needed in order to use SPI.  How would you suggest that they 
> > be obtained?
> 
> Two possibilities: either you derive GICD_CLRSPI_NSR by adding 8 to the
> doorbell you got from the msi_msg structure (ugly, but limited to your
> own code), or you extend msi_msg to cater for this case.

A simpler alternative to the above would be to move all this to
firmware, and only expose a *wired* SPI to the kernel. This would have
the advantage to use the existing infrastructure for both DT and ACPI.

As a side note, that was the intended use of these registers - to
provide a "virtual wire" interface that remains mostly invisible to
software.

Thanks,

	M.
diff mbox

Patch

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba..0019fed 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -58,6 +58,11 @@  static struct gic_chip_data gic_data __read_mostly;
 /* Our default, arbitrary priority value. Linux only uses one anyway. */
 #define DEFAULT_PMR_VALUE	0xf0
 
+struct irq_domain *gic_get_irq_domain(void)
+{
+	return gic_data.domain;
+}
+
 static inline unsigned int gic_irq(struct irq_data *d)
 {
 	return d->hwirq;
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 18e3757..5992224 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -391,6 +391,7 @@  int its_init(struct device_node *node, struct rdists *rdists,
 
 typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
 void set_its_pci_requester_id(its_pci_requester_id_t fn);
+struct irq_domain *gic_get_irq_domain(void);
 #endif
 
 #endif