Re: [PATCH v2 2/8] powerpc/xive: Introduce an IPI interrupt domain

2021-03-08 Thread Greg Kurz
On Wed, 3 Mar 2021 18:48:51 +0100
Cédric Le Goater  wrote:

> The IPI interrupt is a special case of the XIVE IRQ domain. When
> mapping and unmapping the interrupts in the Linux interrupt number
> space, the HW interrupt number 0 (XIVE_IPI_HW_IRQ) is checked to
> distinguish the IPI interrupt from other interrupts of the system.
> 
> Simplify the XIVE interrupt domain by introducing a specific domain
> for the IPI.
> 
> Signed-off-by: Cédric Le Goater 
> ---

Nice !

Reviewed-by: Greg Kurz 

>  arch/powerpc/sysdev/xive/common.c | 51 +--
>  1 file changed, 22 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/xive/common.c 
> b/arch/powerpc/sysdev/xive/common.c
> index b8e456da28aa..e7783760d278 100644
> --- a/arch/powerpc/sysdev/xive/common.c
> +++ b/arch/powerpc/sysdev/xive/common.c
> @@ -63,6 +63,8 @@ static const struct xive_ops *xive_ops;
>  static struct irq_domain *xive_irq_domain;
>  
>  #ifdef CONFIG_SMP
> +static struct irq_domain *xive_ipi_irq_domain;
> +
>  /* The IPIs all use the same logical irq number */
>  static u32 xive_ipi_irq;
>  #endif
> @@ -1067,20 +1069,32 @@ static struct irq_chip xive_ipi_chip = {
>   .irq_unmask = xive_ipi_do_nothing,
>  };
>  
> +/*
> + * IPIs are marked per-cpu. We use separate HW interrupts under the
> + * hood but associated with the same "linux" interrupt
> + */
> +static int xive_ipi_irq_domain_map(struct irq_domain *h, unsigned int virq,
> +irq_hw_number_t hw)
> +{
> + irq_set_chip_and_handler(virq, _ipi_chip, handle_percpu_irq);
> + return 0;
> +}
> +
> +static const struct irq_domain_ops xive_ipi_irq_domain_ops = {
> + .map = xive_ipi_irq_domain_map,
> +};
> +
>  static void __init xive_request_ipi(void)
>  {
>   unsigned int virq;
>  
> - /*
> -  * Initialization failed, move on, we might manage to
> -  * reach the point where we display our errors before
> -  * the system falls appart
> -  */
> - if (!xive_irq_domain)
> + xive_ipi_irq_domain = irq_domain_add_linear(NULL, 1,
> + _ipi_irq_domain_ops, 
> NULL);
> + if (WARN_ON(xive_ipi_irq_domain == NULL))
>   return;
>  
>   /* Initialize it */
> - virq = irq_create_mapping(xive_irq_domain, XIVE_IPI_HW_IRQ);
> + virq = irq_create_mapping(xive_ipi_irq_domain, XIVE_IPI_HW_IRQ);
>   xive_ipi_irq = virq;
>  
>   WARN_ON(request_irq(virq, xive_muxed_ipi_action,
> @@ -1178,19 +1192,6 @@ static int xive_irq_domain_map(struct irq_domain *h, 
> unsigned int virq,
>*/
>   irq_clear_status_flags(virq, IRQ_LEVEL);
>  
> -#ifdef CONFIG_SMP
> - /* IPIs are special and come up with HW number 0 */
> - if (hw == XIVE_IPI_HW_IRQ) {
> - /*
> -  * IPIs are marked per-cpu. We use separate HW interrupts under
> -  * the hood but associated with the same "linux" interrupt
> -  */
> - irq_set_chip_and_handler(virq, _ipi_chip,
> -  handle_percpu_irq);
> - return 0;
> - }
> -#endif
> -
>   rc = xive_irq_alloc_data(virq, hw);
>   if (rc)
>   return rc;
> @@ -1202,15 +1203,7 @@ static int xive_irq_domain_map(struct irq_domain *h, 
> unsigned int virq,
>  
>  static void xive_irq_domain_unmap(struct irq_domain *d, unsigned int virq)
>  {
> - struct irq_data *data = irq_get_irq_data(virq);
> - unsigned int hw_irq;
> -
> - /* XXX Assign BAD number */
> - if (!data)
> - return;
> - hw_irq = (unsigned int)irqd_to_hwirq(data);
> - if (hw_irq != XIVE_IPI_HW_IRQ)
> - xive_irq_free_data(virq);
> + xive_irq_free_data(virq);
>  }
>  
>  static int xive_irq_domain_xlate(struct irq_domain *h, struct device_node 
> *ct,



[PATCH v2 2/8] powerpc/xive: Introduce an IPI interrupt domain

2021-03-03 Thread Cédric Le Goater
The IPI interrupt is a special case of the XIVE IRQ domain. When
mapping and unmapping the interrupts in the Linux interrupt number
space, the HW interrupt number 0 (XIVE_IPI_HW_IRQ) is checked to
distinguish the IPI interrupt from other interrupts of the system.

Simplify the XIVE interrupt domain by introducing a specific domain
for the IPI.

Signed-off-by: Cédric Le Goater 
---
 arch/powerpc/sysdev/xive/common.c | 51 +--
 1 file changed, 22 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/sysdev/xive/common.c 
b/arch/powerpc/sysdev/xive/common.c
index b8e456da28aa..e7783760d278 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -63,6 +63,8 @@ static const struct xive_ops *xive_ops;
 static struct irq_domain *xive_irq_domain;
 
 #ifdef CONFIG_SMP
+static struct irq_domain *xive_ipi_irq_domain;
+
 /* The IPIs all use the same logical irq number */
 static u32 xive_ipi_irq;
 #endif
@@ -1067,20 +1069,32 @@ static struct irq_chip xive_ipi_chip = {
.irq_unmask = xive_ipi_do_nothing,
 };
 
+/*
+ * IPIs are marked per-cpu. We use separate HW interrupts under the
+ * hood but associated with the same "linux" interrupt
+ */
+static int xive_ipi_irq_domain_map(struct irq_domain *h, unsigned int virq,
+  irq_hw_number_t hw)
+{
+   irq_set_chip_and_handler(virq, _ipi_chip, handle_percpu_irq);
+   return 0;
+}
+
+static const struct irq_domain_ops xive_ipi_irq_domain_ops = {
+   .map = xive_ipi_irq_domain_map,
+};
+
 static void __init xive_request_ipi(void)
 {
unsigned int virq;
 
-   /*
-* Initialization failed, move on, we might manage to
-* reach the point where we display our errors before
-* the system falls appart
-*/
-   if (!xive_irq_domain)
+   xive_ipi_irq_domain = irq_domain_add_linear(NULL, 1,
+   _ipi_irq_domain_ops, 
NULL);
+   if (WARN_ON(xive_ipi_irq_domain == NULL))
return;
 
/* Initialize it */
-   virq = irq_create_mapping(xive_irq_domain, XIVE_IPI_HW_IRQ);
+   virq = irq_create_mapping(xive_ipi_irq_domain, XIVE_IPI_HW_IRQ);
xive_ipi_irq = virq;
 
WARN_ON(request_irq(virq, xive_muxed_ipi_action,
@@ -1178,19 +1192,6 @@ static int xive_irq_domain_map(struct irq_domain *h, 
unsigned int virq,
 */
irq_clear_status_flags(virq, IRQ_LEVEL);
 
-#ifdef CONFIG_SMP
-   /* IPIs are special and come up with HW number 0 */
-   if (hw == XIVE_IPI_HW_IRQ) {
-   /*
-* IPIs are marked per-cpu. We use separate HW interrupts under
-* the hood but associated with the same "linux" interrupt
-*/
-   irq_set_chip_and_handler(virq, _ipi_chip,
-handle_percpu_irq);
-   return 0;
-   }
-#endif
-
rc = xive_irq_alloc_data(virq, hw);
if (rc)
return rc;
@@ -1202,15 +1203,7 @@ static int xive_irq_domain_map(struct irq_domain *h, 
unsigned int virq,
 
 static void xive_irq_domain_unmap(struct irq_domain *d, unsigned int virq)
 {
-   struct irq_data *data = irq_get_irq_data(virq);
-   unsigned int hw_irq;
-
-   /* XXX Assign BAD number */
-   if (!data)
-   return;
-   hw_irq = (unsigned int)irqd_to_hwirq(data);
-   if (hw_irq != XIVE_IPI_HW_IRQ)
-   xive_irq_free_data(virq);
+   xive_irq_free_data(virq);
 }
 
 static int xive_irq_domain_xlate(struct irq_domain *h, struct device_node *ct,
-- 
2.26.2