lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160104094828.2664b044@bbrezillon>
Date:	Mon, 4 Jan 2016 09:48:28 +0100
From:	Boris Brezillon <boris.brezillon@...e-electrons.com>
To:	Milo Kim <milo.kim@...com>
Cc:	<tglx@...utronix.de>, <jason@...edaemon.net>,
	<marc.zyngier@....com>, <alexandre.belloni@...e-electrons.com>,
	<ludovic.desroches@...el.com>, <nicolas.ferre@...el.com>,
	<linux-kernel@...r.kernel.org>
Subject: Re: [PATCH 08/19] irqchip: atmel-aic: add common mask and unmask
 functions

On Mon, 4 Jan 2016 13:28:32 +0900
Milo Kim <milo.kim@...com> wrote:

> AIC has one register access to enable/disable an interrupt.
> AIC5 requires two register accesses - SSR and IECR/IDCR.
> This patch unifies interrupt mask and unmask operations.
> 
> Mask and unmask operations are moved into aic_common_of_init().
> AIC5 can have multiple IRQ chips, mask/unmask should be assigned per chip.
> In case of AIC, it's also good because AIC has one IRQ chip.
> So looping count is just one time to configure mask/unmask functions.
> 
> struct irq_domain *__init aic_common_of_init(struct device_node *node,
> 					     const char *name, int nirqs)
> {
> 	...
> 
> 	for (i = 0; i < nchips; i++) {
> 		gc = irq_get_domain_generic_chip(domain, i * AIC_IRQS_PER_CHIP);
> 
> 		...
> 		gc->chip_types[0].chip.irq_mask = aic_mask;
> 		gc->chip_types[0].chip.irq_unmask = aic_unmask;
> 		gc->private = &aic[i];
> 	}
> }
> 
> In AIC, register configuration for enabling and disabling IRQ can be
> replaced with irq_mask and irq_unmask. This is for using unified mask and
> unmask functions (aic_mask and aic_unmask).
> 
> Cc: Thomas Gleixner <tglx@...utronix.de>
> Cc: Jason Cooper <jason@...edaemon.net>
> Cc: Marc Zyngier <marc.zyngier@....com>
> Cc: Alexandre Belloni <alexandre.belloni@...e-electrons.com>
> Cc: Boris BREZILLON <boris.brezillon@...e-electrons.com>
> Cc: Ludovic Desroches <ludovic.desroches@...el.com>
> Cc: Nicolas Ferre <nicolas.ferre@...el.com>
> Cc: linux-kernel@...r.kernel.org
> Signed-off-by: Milo Kim <milo.kim@...com>
> ---
>  drivers/irqchip/irq-atmel-aic-common.c | 52 ++++++++++++++++++++++++++++++++++
>  drivers/irqchip/irq-atmel-aic.c        |  4 ---
>  drivers/irqchip/irq-atmel-aic5.c       | 36 -----------------------
>  3 files changed, 52 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c
> index 94c9dad..533b3e9 100644
> --- a/drivers/irqchip/irq-atmel-aic-common.c
> +++ b/drivers/irqchip/irq-atmel-aic-common.c
> @@ -193,6 +193,56 @@ static void aic_common_shutdown(struct irq_data *d)
>  	ct->chip.irq_mask(d);
>  }
>  
> +static void aic_mask(struct irq_data *d)
> +{
> +	struct irq_domain *domain = d->domain;
> +	struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> +	u32 mask = d->mask;
> +
> +	/*
> +	 * Disable interrupt. We always take the lock of the
> +	 * first irq chip as all chips share the same registers.
> +	 */
> +	irq_gc_lock(bgc);
> +
> +	if (aic_is_ssr_used()) {
> +		irq_reg_writel(gc, d->hwirq, aic_reg_data->ssr);
> +		irq_reg_writel(gc, 1, aic_reg_data->idcr);
> +	} else {
> +		irq_reg_writel(gc, mask, aic_reg_data->idcr);
> +	}
> +
> +	gc->mask_cache &= ~mask;
> +
> +	irq_gc_unlock(bgc);
> +}
> +
> +static void aic_unmask(struct irq_data *d)
> +{
> +	struct irq_domain *domain = d->domain;
> +	struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> +	u32 mask = d->mask;
> +
> +	/*
> +	 * Enable interrupt. We always take the lock of the
> +	 * first irq chip as all chips share the same registers.
> +	 */
> +	irq_gc_lock(bgc);
> +
> +	if (aic_is_ssr_used()) {
> +		irq_reg_writel(gc, d->hwirq, aic_reg_data->ssr);
> +		irq_reg_writel(gc, 1, aic_reg_data->iecr);
> +	} else {
> +		irq_reg_writel(gc, mask, aic_reg_data->iecr);
> +	}

In other words, you prefer to add extra conditional statements in the
critical irq path rather than keeping two different drivers for two IPs
that are not so similar.

Here is my opinion: if you want to get rid of the aic-common* files,
fine, but please keep 2 different drivers for the AIC and AIC5 IPs and
duplicate the common code in each driver.
I understand that code factorization is important (and this is exactly
why I created aic-common), but it's pointless to try to factorize things
that are completely different, and AIC and AIC5 fall in this case (look
at the number of aic_is_ssr_used() you're adding in your series).

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ