linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] More GIC updates for Linux 4.4
@ 2015-10-14 11:27 Marc Zyngier
  2015-10-14 11:27 ` [PATCH v2 1/2] irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec Marc Zyngier
  2015-10-14 11:27 ` [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames Marc Zyngier
  0 siblings, 2 replies; 6+ messages in thread
From: Marc Zyngier @ 2015-10-14 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

Here's a couple of GIC patches that I'd like to see in 4.4:

- A fix for a (copy-paste) bug introduced by the fwnode/fwspec
  conversion, breaking LPI translation

- An extension to the GICv2m driver, enabling support for multiple MSI
  frames (already posted)

This is on top of tip/irq/core as of yesterday. Hopefully, this is the
last set of GIC patches for the next merge window (and I really mean
it this time).

Thanks,

	M.

* From v1:
  - Fixed the add_tree/create_tree resolution issue in the GICv2m patch

Marc Zyngier (2):
  irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec
  irqchip/gic-v2m: Add support for multiple MSI frames

 drivers/irqchip/irq-gic-v2m.c | 124 ++++++++++++++++++++++++++----------------
 drivers/irqchip/irq-gic-v3.c  |  22 +++++---
 2 files changed, 91 insertions(+), 55 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec
  2015-10-14 11:27 [PATCH v2 0/2] More GIC updates for Linux 4.4 Marc Zyngier
@ 2015-10-14 11:27 ` Marc Zyngier
  2015-10-14 11:27 ` [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames Marc Zyngier
  1 sibling, 0 replies; 6+ messages in thread
From: Marc Zyngier @ 2015-10-14 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Commit f833f57ff254 ("irqchip: Convert all alloc/xlate users from
of_node to fwnode") converted the GICv3 driver to using irq_fwspec
as part of its 'translate' method.

Too bad it ended up with a copy of the GICv2 'translate' method,
which screws up LPI translation (by not translating them at all).

Restore the code in its original shape, and just change what is
really required...

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 05d010b..d7be6dd 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -746,15 +746,19 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 		if (fwspec->param_count < 3)
 			return -EINVAL;
 
-		/* Get the interrupt number and add 16 to skip over SGIs */
-		*hwirq = fwspec->param[1] + 16;
-
-		/*
-		 * For SPIs, we need to add 16 more to get the GIC irq
-		 * ID number
-		 */
-		if (!fwspec->param[0])
-			*hwirq += 16;
+		switch (fwspec->param[0]) {
+		case 0:			/* SPI */
+			*hwirq = fwspec->param[1] + 32;
+			break;
+		case 1:			/* PPI */
+			*hwirq = fwspec->param[1] + 16;
+			break;
+		case GIC_IRQ_TYPE_LPI:	/* LPI */
+			*hwirq = fwspec->param[1];
+			break;
+		default:
+			return -EINVAL;
+		}
 
 		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
 		return 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames
  2015-10-14 11:27 [PATCH v2 0/2] More GIC updates for Linux 4.4 Marc Zyngier
  2015-10-14 11:27 ` [PATCH v2 1/2] irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec Marc Zyngier
@ 2015-10-14 11:27 ` Marc Zyngier
  2015-10-14 14:13   ` Suravee Suthikulanit
  1 sibling, 1 reply; 6+ messages in thread
From: Marc Zyngier @ 2015-10-14 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

The GICv2m driver is so far limited to a single MSI frame, but
nothing prevents an implementation from having several of them.

This patch expands the driver to enumerate all frames, keeping
the first one as the canonical identifier for the MSI domains.

Tested-by: Duc Dang <dhdang@apm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v2m.c | 124 ++++++++++++++++++++++++++----------------
 1 file changed, 78 insertions(+), 46 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index bf9b3c0..87f8d10 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -50,8 +50,12 @@
 /* List of flags for specific v2m implementation */
 #define GICV2M_NEEDS_SPI_OFFSET		0x00000001
 
+static LIST_HEAD(v2m_nodes);
+static DEFINE_SPINLOCK(v2m_lock);
+
 struct v2m_data {
-	spinlock_t msi_cnt_lock;
+	struct list_head entry;
+	struct device_node *node;
 	struct resource res;	/* GICv2m resource */
 	void __iomem *base;	/* GICv2m virt address */
 	u32 spi_start;		/* The SPI number that MSIs start */
@@ -158,27 +162,30 @@ static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq)
 		return;
 	}
 
-	spin_lock(&v2m->msi_cnt_lock);
+	spin_lock(&v2m_lock);
 	__clear_bit(pos, v2m->bm);
-	spin_unlock(&v2m->msi_cnt_lock);
+	spin_unlock(&v2m_lock);
 }
 
 static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				   unsigned int nr_irqs, void *args)
 {
-	struct v2m_data *v2m = domain->host_data;
+	struct v2m_data *v2m = NULL, *tmp;
 	int hwirq, offset, err = 0;
 
-	spin_lock(&v2m->msi_cnt_lock);
-	offset = find_first_zero_bit(v2m->bm, v2m->nr_spis);
-	if (offset < v2m->nr_spis)
-		__set_bit(offset, v2m->bm);
-	else
-		err = -ENOSPC;
-	spin_unlock(&v2m->msi_cnt_lock);
+	spin_lock(&v2m_lock);
+	list_for_each_entry(tmp, &v2m_nodes, entry) {
+		offset = find_first_zero_bit(tmp->bm, tmp->nr_spis);
+		if (offset < tmp->nr_spis) {
+			__set_bit(offset, tmp->bm);
+			v2m = tmp;
+			break;
+		}
+	}
+	spin_unlock(&v2m_lock);
 
-	if (err)
-		return err;
+	if (!v2m)
+		return -ENOSPC;
 
 	hwirq = v2m->spi_start + offset;
 
@@ -239,12 +246,61 @@ static struct msi_domain_info gicv2m_pmsi_domain_info = {
 	.chip	= &gicv2m_pmsi_irq_chip,
 };
 
+static void gicv2m_teardown(void)
+{
+	struct v2m_data *v2m, *tmp;
+
+	list_for_each_entry_safe(v2m, tmp, &v2m_nodes, entry) {
+		list_del(&v2m->entry);
+		kfree(v2m->bm);
+		iounmap(v2m->base);
+		of_node_put(v2m->node);
+		kfree(v2m);
+	}
+}
+
+static int gicv2m_allocate_domains(struct irq_domain *parent)
+{
+	struct irq_domain *inner_domain, *pci_domain, *plat_domain;
+	struct v2m_data *v2m;
+
+	v2m = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
+	if (!v2m)
+		return 0;
+
+	inner_domain = irq_domain_create_tree(of_node_to_fwnode(v2m->node),
+					      &gicv2m_domain_ops, v2m);
+	if (!inner_domain) {
+		pr_err("Failed to create GICv2m domain\n");
+		return -ENOMEM;
+	}
+
+	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
+	inner_domain->parent = parent;
+	pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+					       &gicv2m_msi_domain_info,
+					       inner_domain);
+	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+						     &gicv2m_pmsi_domain_info,
+						     inner_domain);
+	if (!pci_domain || !plat_domain) {
+		pr_err("Failed to create MSI domains\n");
+		if (plat_domain)
+			irq_domain_remove(plat_domain);
+		if (pci_domain)
+			irq_domain_remove(pci_domain);
+		irq_domain_remove(inner_domain);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 static int __init gicv2m_init_one(struct device_node *node,
 				  struct irq_domain *parent)
 {
 	int ret;
 	struct v2m_data *v2m;
-	struct irq_domain *inner_domain, *pci_domain, *plat_domain;
 
 	v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL);
 	if (!v2m) {
@@ -252,6 +308,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 		return -ENOMEM;
 	}
 
+	INIT_LIST_HEAD(&v2m->entry);
+	v2m->node = node;
+
 	ret = of_address_to_resource(node, 0, &v2m->res);
 	if (ret) {
 		pr_err("Failed to allocate v2m resource.\n");
@@ -299,44 +358,13 @@ static int __init gicv2m_init_one(struct device_node *node,
 		goto err_iounmap;
 	}
 
-	inner_domain = irq_domain_add_tree(node, &gicv2m_domain_ops, v2m);
-	if (!inner_domain) {
-		pr_err("Failed to create GICv2m domain\n");
-		ret = -ENOMEM;
-		goto err_free_bm;
-	}
-
-	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
-	inner_domain->parent = parent;
-	pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node),
-					       &gicv2m_msi_domain_info,
-					       inner_domain);
-	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node),
-						     &gicv2m_pmsi_domain_info,
-						     inner_domain);
-	if (!pci_domain || !plat_domain) {
-		pr_err("Failed to create MSI domains\n");
-		ret = -ENOMEM;
-		goto err_free_domains;
-	}
-
-	spin_lock_init(&v2m->msi_cnt_lock);
-
+	list_add_tail(&v2m->entry, &v2m_nodes);
 	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
 		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
 		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 
 	return 0;
 
-err_free_domains:
-	if (plat_domain)
-		irq_domain_remove(plat_domain);
-	if (pci_domain)
-		irq_domain_remove(pci_domain);
-	if (inner_domain)
-		irq_domain_remove(inner_domain);
-err_free_bm:
-	kfree(v2m->bm);
 err_iounmap:
 	iounmap(v2m->base);
 err_free_v2m:
@@ -366,5 +394,9 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 		}
 	}
 
+	if (!ret)
+		ret = gicv2m_allocate_domains(parent);
+	if (ret)
+		gicv2m_teardown();
 	return ret;
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames
  2015-10-14 11:27 ` [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames Marc Zyngier
@ 2015-10-14 14:13   ` Suravee Suthikulanit
  2015-10-14 15:28     ` Marc Zyngier
  0 siblings, 1 reply; 6+ messages in thread
From: Suravee Suthikulanit @ 2015-10-14 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On 10/14/2015 6:27 AM, Marc Zyngier wrote:
> The GICv2m driver is so far limited to a single MSI frame, but
> nothing prevents an implementation from having several of them.
>
> This patch expands the driver to enumerate all frames, keeping
> the first one as the canonical identifier for the MSI domains.
>
> Tested-by: Duc Dang <dhdang@apm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v2m.c | 124 ++++++++++++++++++++++++++----------------
>   1 file changed, 78 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
> index bf9b3c0..87f8d10 100644
> --- a/drivers/irqchip/irq-gic-v2m.c
> +++ b/drivers/irqchip/irq-gic-v2m.c
> @@ -50,8 +50,12 @@
>   /* List of flags for specific v2m implementation */
>   #define GICV2M_NEEDS_SPI_OFFSET		0x00000001
>
> +static LIST_HEAD(v2m_nodes);
> +static DEFINE_SPINLOCK(v2m_lock);
> +
>   struct v2m_data {
> -	spinlock_t msi_cnt_lock;
> +	struct list_head entry;
> +	struct device_node *node;

Would it be better if we use struct fwnode_handle * here instead. I 
noticed that later on, this is also used as of_node_to_fwnode(v2m->node) 
in several places. Also, this would need to change anyways when we 
introducing ACPI support (see here https://lkml.org/lkml/2015/10/13/846).

Thanks,
Suravee

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames
  2015-10-14 14:13   ` Suravee Suthikulanit
@ 2015-10-14 15:28     ` Marc Zyngier
  2015-10-14 15:30       ` Suravee Suthikulanit
  0 siblings, 1 reply; 6+ messages in thread
From: Marc Zyngier @ 2015-10-14 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 15:13, Suravee Suthikulanit wrote:
> Hi Marc,
> 
> On 10/14/2015 6:27 AM, Marc Zyngier wrote:
>> The GICv2m driver is so far limited to a single MSI frame, but
>> nothing prevents an implementation from having several of them.
>>
>> This patch expands the driver to enumerate all frames, keeping
>> the first one as the canonical identifier for the MSI domains.
>>
>> Tested-by: Duc Dang <dhdang@apm.com>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>   drivers/irqchip/irq-gic-v2m.c | 124 ++++++++++++++++++++++++++----------------
>>   1 file changed, 78 insertions(+), 46 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
>> index bf9b3c0..87f8d10 100644
>> --- a/drivers/irqchip/irq-gic-v2m.c
>> +++ b/drivers/irqchip/irq-gic-v2m.c
>> @@ -50,8 +50,12 @@
>>   /* List of flags for specific v2m implementation */
>>   #define GICV2M_NEEDS_SPI_OFFSET		0x00000001
>>
>> +static LIST_HEAD(v2m_nodes);
>> +static DEFINE_SPINLOCK(v2m_lock);
>> +
>>   struct v2m_data {
>> -	spinlock_t msi_cnt_lock;
>> +	struct list_head entry;
>> +	struct device_node *node;
> 
> Would it be better if we use struct fwnode_handle * here instead. I 
> noticed that later on, this is also used as of_node_to_fwnode(v2m->node) 
> in several places. Also, this would need to change anyways when we 
> introducing ACPI support (see here https://lkml.org/lkml/2015/10/13/846).

I was thinking that it would be part of your series adapting it to ACPI.
I don't mind either way...

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames
  2015-10-14 15:28     ` Marc Zyngier
@ 2015-10-14 15:30       ` Suravee Suthikulanit
  0 siblings, 0 replies; 6+ messages in thread
From: Suravee Suthikulanit @ 2015-10-14 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/14/2015 10:28 AM, Marc Zyngier wrote:
> On 14/10/15 15:13, Suravee Suthikulanit wrote:
>> Hi Marc,
>>
>> On 10/14/2015 6:27 AM, Marc Zyngier wrote:
>>> The GICv2m driver is so far limited to a single MSI frame, but
>>> nothing prevents an implementation from having several of them.
>>>
>>> This patch expands the driver to enumerate all frames, keeping
>>> the first one as the canonical identifier for the MSI domains.
>>>
>>> Tested-by: Duc Dang <dhdang@apm.com>
>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>> ---
>>>    drivers/irqchip/irq-gic-v2m.c | 124 ++++++++++++++++++++++++++----------------
>>>    1 file changed, 78 insertions(+), 46 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
>>> index bf9b3c0..87f8d10 100644
>>> --- a/drivers/irqchip/irq-gic-v2m.c
>>> +++ b/drivers/irqchip/irq-gic-v2m.c
>>> @@ -50,8 +50,12 @@
>>>    /* List of flags for specific v2m implementation */
>>>    #define GICV2M_NEEDS_SPI_OFFSET		0x00000001
>>>
>>> +static LIST_HEAD(v2m_nodes);
>>> +static DEFINE_SPINLOCK(v2m_lock);
>>> +
>>>    struct v2m_data {
>>> -	spinlock_t msi_cnt_lock;
>>> +	struct list_head entry;
>>> +	struct device_node *node;
>>
>> Would it be better if we use struct fwnode_handle * here instead. I
>> noticed that later on, this is also used as of_node_to_fwnode(v2m->node)
>> in several places. Also, this would need to change anyways when we
>> introducing ACPI support (see here https://lkml.org/lkml/2015/10/13/846).
>
> I was thinking that it would be part of your series adapting it to ACPI.
> I don't mind either way...
>
> Thanks,
>
> 	M.
>

Ok, I'll rebase the GICv2m ACPI support on top of this multi-frame 
change and send out V2 If this won't be changing again any time soon.

Thanks,
Suravee

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-10-14 15:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-14 11:27 [PATCH v2 0/2] More GIC updates for Linux 4.4 Marc Zyngier
2015-10-14 11:27 ` [PATCH v2 1/2] irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec Marc Zyngier
2015-10-14 11:27 ` [PATCH v2 2/2] irqchip/gic-v2m: Add support for multiple MSI frames Marc Zyngier
2015-10-14 14:13   ` Suravee Suthikulanit
2015-10-14 15:28     ` Marc Zyngier
2015-10-14 15:30       ` Suravee Suthikulanit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).