diff mbox

[V3,08/10] irqchip, gicv3, its: Probe ITS in the ACPI way.

Message ID 1453209083-3358-9-git-send-email-tn@semihalf.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomasz Nowicki Jan. 19, 2016, 1:11 p.m. UTC
Since we prepared ITS for being initialized different that via DT,
it is now possible to parse MADT and pass mandatory info to
firmware-agnostic ITS init call.

Note that we are using here IORT lib to keep track of allocated
domain handler which will be used to build PCI MSI domain on top
in the later patches.

Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its.c | 57 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

Comments

kernel test robot Jan. 19, 2016, 6:04 p.m. UTC | #1
Hi Tomasz,

[auto build test ERROR on v4.4-rc8]
[cannot apply to tip/irq/core next-20160119]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Tomasz-Nowicki/Introduce-ACPI-world-to-GICv3-ITS-irqchip/20160119-211652
config: arm64-allmodconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

   drivers/irqchip/irq-gic-v3-its.c: In function 'its_irq_gic_domain_alloc':
>> drivers/irqchip/irq-gic-v3-its.c:1278:2: error: implicit declaration of function 'is_fwnode_irqchip' [-Werror=implicit-function-declaration]
     } else if (is_fwnode_irqchip(domain->parent->fwnode)) {
     ^
   cc1: some warnings being treated as errors

vim +/is_fwnode_irqchip +1278 drivers/irqchip/irq-gic-v3-its.c

  1272		if (irq_domain_get_of_node(domain->parent)) {
  1273			fwspec.fwnode = domain->parent->fwnode;
  1274			fwspec.param_count = 3;
  1275			fwspec.param[0] = GIC_IRQ_TYPE_LPI;
  1276			fwspec.param[1] = hwirq;
  1277			fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
> 1278		} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
  1279			fwspec.fwnode = domain->parent->fwnode;
  1280			fwspec.param_count = 2;
  1281			fwspec.param[0] = hwirq;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Marc Zyngier Feb. 10, 2016, 11:46 a.m. UTC | #2
On 19/01/16 13:11, Tomasz Nowicki wrote:
> Since we prepared ITS for being initialized different that via DT,
> it is now possible to parse MADT and pass mandatory info to
> firmware-agnostic ITS init call.
> 
> Note that we are using here IORT lib to keep track of allocated
> domain handler which will be used to build PCI MSI domain on top
> in the later patches.
> 
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 57 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 56 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index fecb7a6..42f378a 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -15,10 +15,13 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/bitmap.h>
>  #include <linux/cpu.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> +#include <linux/irqdomain.h>
> +#include <linux/iort.h>
>  #include <linux/log2.h>
>  #include <linux/mm.h>
>  #include <linux/msi.h>
> @@ -1272,6 +1275,11 @@ static int its_irq_gic_domain_alloc(struct irq_domain *domain,
>  		fwspec.param[0] = GIC_IRQ_TYPE_LPI;
>  		fwspec.param[1] = hwirq;
>  		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
> +	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
> +		fwspec.fwnode = domain->parent->fwnode;
> +		fwspec.param_count = 2;
> +		fwspec.param[0] = hwirq;
> +		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
>  	} else {
>  		return -EINVAL;
>  	}
> @@ -1594,6 +1602,52 @@ int its_cpu_init(void)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_ACPI
> +
> +#define ACPI_GICV3_ITS_MEM_SIZE (2 * SZ_64K)
> +
> +static struct irq_domain *its_parent __initdata;
> +
> +static int __init
> +gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
> +			const unsigned long end)
> +{
> +	struct acpi_madt_generic_translator *its_entry;
> +	struct fwnode_handle *domain_handle;
> +	int err;
> +
> +	its_entry = (struct acpi_madt_generic_translator *)header;
> +	domain_handle = irq_domain_alloc_fwnode((void *)its_entry->base_address);
> +	if (!domain_handle) {
> +		pr_err("Unable to allocate GICv2m domain token\n");

-ECOPYPASTE.

> +		return -ENOMEM;
> +	}
> +
> +	/* ITS works as msi controller in ACPI case */
> +	err = its_probe_one(its_entry->base_address, ACPI_GICV3_ITS_MEM_SIZE,
> +			    its_parent, true, domain_handle);
> +	if (err) {
> +		irq_domain_free_fwnode(domain_handle);
> +		return err;
> +	}
> +	iort_register_domain_token(its_entry->translation_id, domain_handle);

And what if this fails?

> +	return 0;
> +}
> +
> +void __init its_acpi_probe(struct irq_domain *parent_domain)
> +{
> +	int count;
> +
> +	its_parent = parent_domain;
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
> +				      gic_acpi_parse_madt_its, 0);
> +	if (count <= 0)
> +		pr_info("No valid GIC ITS entries exist\n");
> +}
> +#else
> +static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
> +#endif
> +
>  static struct of_device_id its_device_id[] = {
>  	{	.compatible	= "arm,gic-v3-its",	},
>  	{},
> @@ -1610,7 +1664,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>  		     np = of_find_matching_node(np, its_device_id)) {
>  			its_of_probe(np, parent_domain);
>  		}
> -	}
> +	} else
> +		its_acpi_probe(parent_domain);

Missing braces.

>  
>  	if (list_empty(&its_nodes)) {
>  		pr_warn("ITS: No ITS available, not enabling LPIs\n");
> 

Thanks,

	M.
Tomasz Nowicki Feb. 12, 2016, 10:14 a.m. UTC | #3
On 10.02.2016 12:46, Marc Zyngier wrote:
> On 19/01/16 13:11, Tomasz Nowicki wrote:
>> Since we prepared ITS for being initialized different that via DT,
>> it is now possible to parse MADT and pass mandatory info to
>> firmware-agnostic ITS init call.
>>
>> Note that we are using here IORT lib to keep track of allocated
>> domain handler which will be used to build PCI MSI domain on top
>> in the later patches.
>>
>> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-v3-its.c | 57 +++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 56 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index fecb7a6..42f378a 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -15,10 +15,13 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> +#include <linux/acpi.h>
>>   #include <linux/bitmap.h>
>>   #include <linux/cpu.h>
>>   #include <linux/delay.h>
>>   #include <linux/interrupt.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/iort.h>
>>   #include <linux/log2.h>
>>   #include <linux/mm.h>
>>   #include <linux/msi.h>
>> @@ -1272,6 +1275,11 @@ static int its_irq_gic_domain_alloc(struct irq_domain *domain,
>>   		fwspec.param[0] = GIC_IRQ_TYPE_LPI;
>>   		fwspec.param[1] = hwirq;
>>   		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
>> +	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
>> +		fwspec.fwnode = domain->parent->fwnode;
>> +		fwspec.param_count = 2;
>> +		fwspec.param[0] = hwirq;
>> +		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
>>   	} else {
>>   		return -EINVAL;
>>   	}
>> @@ -1594,6 +1602,52 @@ int its_cpu_init(void)
>>   	return 0;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +
>> +#define ACPI_GICV3_ITS_MEM_SIZE (2 * SZ_64K)
>> +
>> +static struct irq_domain *its_parent __initdata;
>> +
>> +static int __init
>> +gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
>> +			const unsigned long end)
>> +{
>> +	struct acpi_madt_generic_translator *its_entry;
>> +	struct fwnode_handle *domain_handle;
>> +	int err;
>> +
>> +	its_entry = (struct acpi_madt_generic_translator *)header;
>> +	domain_handle = irq_domain_alloc_fwnode((void *)its_entry->base_address);
>> +	if (!domain_handle) {
>> +		pr_err("Unable to allocate GICv2m domain token\n");
>
> -ECOPYPASTE.
>
>> +		return -ENOMEM;
>> +	}
>> +
>> +	/* ITS works as msi controller in ACPI case */
>> +	err = its_probe_one(its_entry->base_address, ACPI_GICV3_ITS_MEM_SIZE,
>> +			    its_parent, true, domain_handle);
>> +	if (err) {
>> +		irq_domain_free_fwnode(domain_handle);
>> +		return err;
>> +	}
>> +	iort_register_domain_token(its_entry->translation_id, domain_handle);
>
> And what if this fails?
>
>> +	return 0;
>> +}
>> +
>> +void __init its_acpi_probe(struct irq_domain *parent_domain)
>> +{
>> +	int count;
>> +
>> +	its_parent = parent_domain;
>> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
>> +				      gic_acpi_parse_madt_its, 0);
>> +	if (count <= 0)
>> +		pr_info("No valid GIC ITS entries exist\n");
>> +}
>> +#else
>> +static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
>> +#endif
>> +
>>   static struct of_device_id its_device_id[] = {
>>   	{	.compatible	= "arm,gic-v3-its",	},
>>   	{},
>> @@ -1610,7 +1664,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>>   		     np = of_find_matching_node(np, its_device_id)) {
>>   			its_of_probe(np, parent_domain);
>>   		}
>> -	}
>> +	} else
>> +		its_acpi_probe(parent_domain);
>
> Missing braces.
>

Right, I will address all your comments in the next ITS-only series.

Tomasz
diff mbox

Patch

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index fecb7a6..42f378a 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -15,10 +15,13 @@ 
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/bitmap.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/iort.h>
 #include <linux/log2.h>
 #include <linux/mm.h>
 #include <linux/msi.h>
@@ -1272,6 +1275,11 @@  static int its_irq_gic_domain_alloc(struct irq_domain *domain,
 		fwspec.param[0] = GIC_IRQ_TYPE_LPI;
 		fwspec.param[1] = hwirq;
 		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
+	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
+		fwspec.fwnode = domain->parent->fwnode;
+		fwspec.param_count = 2;
+		fwspec.param[0] = hwirq;
+		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
 	} else {
 		return -EINVAL;
 	}
@@ -1594,6 +1602,52 @@  int its_cpu_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+
+#define ACPI_GICV3_ITS_MEM_SIZE (2 * SZ_64K)
+
+static struct irq_domain *its_parent __initdata;
+
+static int __init
+gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_translator *its_entry;
+	struct fwnode_handle *domain_handle;
+	int err;
+
+	its_entry = (struct acpi_madt_generic_translator *)header;
+	domain_handle = irq_domain_alloc_fwnode((void *)its_entry->base_address);
+	if (!domain_handle) {
+		pr_err("Unable to allocate GICv2m domain token\n");
+		return -ENOMEM;
+	}
+
+	/* ITS works as msi controller in ACPI case */
+	err = its_probe_one(its_entry->base_address, ACPI_GICV3_ITS_MEM_SIZE,
+			    its_parent, true, domain_handle);
+	if (err) {
+		irq_domain_free_fwnode(domain_handle);
+		return err;
+	}
+	iort_register_domain_token(its_entry->translation_id, domain_handle);
+	return 0;
+}
+
+void __init its_acpi_probe(struct irq_domain *parent_domain)
+{
+	int count;
+
+	its_parent = parent_domain;
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+				      gic_acpi_parse_madt_its, 0);
+	if (count <= 0)
+		pr_info("No valid GIC ITS entries exist\n");
+}
+#else
+static inline void __init its_acpi_probe(struct irq_domain *parent_domain) { }
+#endif
+
 static struct of_device_id its_device_id[] = {
 	{	.compatible	= "arm,gic-v3-its",	},
 	{},
@@ -1610,7 +1664,8 @@  int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 		     np = of_find_matching_node(np, its_device_id)) {
 			its_of_probe(np, parent_domain);
 		}
-	}
+	} else
+		its_acpi_probe(parent_domain);
 
 	if (list_empty(&its_nodes)) {
 		pr_warn("ITS: No ITS available, not enabling LPIs\n");