From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752218AbbGVVcZ (ORCPT ); Wed, 22 Jul 2015 17:32:25 -0400 Received: from gabe.freedesktop.org ([131.252.210.177]:53991 "EHLO gabe.freedesktop.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751154AbbGVVcY (ORCPT ); Wed, 22 Jul 2015 17:32:24 -0400 From: Eric Anholt To: Noralf =?utf-8?Q?Tr=C3=B8nnes?= , tglx@linutronix.de, jason@lakedaemon.net Cc: linux-rpi-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Noralf =?utf-8?Q?Tr=C3=B8nnes?= Subject: Re: [PATCH] irqchip: bcm2835: Add FIQ support In-Reply-To: <1434130016-26574-1-git-send-email-noralf@tronnes.org> References: <1434130016-26574-1-git-send-email-noralf@tronnes.org> User-Agent: Notmuch/0.20.2 (http://notmuchmail.org) Emacs/24.5.1 (x86_64-pc-linux-gnu) Date: Wed, 22 Jul 2015 14:32:21 -0700 Message-ID: <87d1zj6fq2.fsf@eliezer.anholt.net> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Noralf Tr=C3=B8nnes writes: > Add a duplicate irq range with an offset on the hwirq's so the > driver can detect that enable_fiq() is used. > Tested with downstream dwc_otg USB controller driver. > > Signed-off-by: Noralf Tr=C3=B8nnes > --- > arch/arm/mach-bcm/Kconfig | 1 + > drivers/irqchip/irq-bcm2835.c | 53 +++++++++++++++++++++++++++++++++++++= +----- > 2 files changed, 48 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig > index 8b11f44..7cfef7b 100644 > --- a/arch/arm/mach-bcm/Kconfig > +++ b/arch/arm/mach-bcm/Kconfig > @@ -114,6 +114,7 @@ config ARCH_BCM2835 > select ARM_ERRATA_411920 > select ARM_TIMER_SP804 > select CLKSRC_OF > + select FIQ > select PINCTRL > select PINCTRL_BCM2835 > help > diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c > index 5916d6c..db66246 100644 > --- a/drivers/irqchip/irq-bcm2835.c > +++ b/drivers/irqchip/irq-bcm2835.c > @@ -56,7 +56,7 @@ > #include "irqchip.h" >=20=20 > /* Put the bank and irq (32 bits) into the hwirq */ > -#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) > +#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) > #define HWIRQ_BANK(i) (i >> 5) > #define HWIRQ_BIT(i) BIT(i & 0x1f) >=20=20 > @@ -72,9 +72,13 @@ > | SHORTCUT1_MASK | SHORTCUT2_MASK) >=20=20 > #define REG_FIQ_CONTROL 0x0c > +#define REG_FIQ_ENABLE 0x80 > +#define REG_FIQ_DISABLE 0 >=20=20 > #define NR_BANKS 3 > #define IRQS_PER_BANK 32 > +#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) > +#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) >=20=20 > static int reg_pending[] __initconst =3D { 0x00, 0x04, 0x08 }; > static int reg_enable[] __initconst =3D { 0x18, 0x10, 0x14 }; > @@ -98,14 +102,38 @@ static struct armctrl_ic intc __read_mostly; > static void __exception_irq_entry bcm2835_handle_irq( > struct pt_regs *regs); >=20=20 > +static inline unsigned int hwirq_to_fiq(unsigned long hwirq) > +{ > + hwirq -=3D NUMBER_IRQS; > + /* > + * The hwirq numbering used in this driver is: > + * BASE (0-7) GPU1 (32-63) GPU2 (64-95). > + * This differ from the one used in the FIQ register: > + * GPU1 (0-31) GPU2 (32-63) BASE (64-71) > + */ > + if (hwirq >=3D 32) > + return hwirq - 32; > + > + return hwirq + 64; > +} > + > static void armctrl_mask_irq(struct irq_data *d) > { > - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); > + if (d->hwirq >=3D NUMBER_IRQS) > + writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); > + else > + writel_relaxed(HWIRQ_BIT(d->hwirq), > + intc.disable[HWIRQ_BANK(d->hwirq)]); > } >=20=20 > static void armctrl_unmask_irq(struct irq_data *d) > { > - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); > + if (d->hwirq >=3D NUMBER_IRQS) > + writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), > + intc.base + REG_FIQ_CONTROL); > + else > + writel_relaxed(HWIRQ_BIT(d->hwirq), > + intc.enable[HWIRQ_BANK(d->hwirq)]); > } I found it nice for the 2836 controller to declare a new irqchip when both the mask/unmask hooks needed to be changed for that class of interrupt. However, it looks like these functions aren't going to be called regularly, so it doesn't matter much. As far as interaction with my 2836 series, it looks like the only thing downstream does is make the FIQ get handled on CPU1 instead of CPU0. I think we'll be fine fixing this up later. Reviewed-by: Eric Anholt --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBCgAGBQJVsAvlAAoJELXWKTbR/J7oTEMP/1uoSxQhm8d6+ei2Oqlqd3I5 V5AdgASgmoPNPGM1Ers/GdM3gc4YKxBLkVUzIm+PAmNu1cZrhfdZbQp27M7hWbAA /91yHhq7aVdseg4MW5YxLHebGHDQSnW9lM1+YrMHiR38FVYZtbviMlR5ThrKBcWo DfRK+RZzjTK/1Y7ul0HXGRqF/CIvK6Bmp1LesIQPDd1tP4HY+jggGDQqugcfSuga EbV6r4guyA814imSwJZNCX1FxQzokuTyo6z6WIlws9JGWRBBRwi9/OjyhjHu6sUD 3dL/fobGYkjGgFHdCjkntR0FoxKfMJVKxregX2CTHBv40qoIp/0YsseUz3McQi1T 63YbuWWGsdKd9XyS4dhPHAxp+jh638DkNQnuyWZk5gc6901C+tWA/rvDaDrbpFyK 51nfgwcgzspRTNl6+olHieZKY+0IAp26GVDU/0syCm2zz8cALENhWyuFdAOBCyHI yR05rX4ucZIQc4ibDXmnJfWWVH8b8Xd6Dm+A/z/bbKfULFNq/LsH9mt0rVitRIft YwrlPb1DZ6lZ0Se1oev31Q6U+Fv7SXaTvL5JjfF0SMvV7rxR++aGQPpN7QVN1S26 8LvEXcwV6UkMO2Q6yUiEp68O4a7ReyubMQSHjasrjfx5HNEGSpjLsgmsl7cQaawH RiBDVpmuevkWgDb7wDxW =uibg -----END PGP SIGNATURE----- --=-=-=-- From mboxrd@z Thu Jan 1 00:00:00 1970 From: eric@anholt.net (Eric Anholt) Date: Wed, 22 Jul 2015 14:32:21 -0700 Subject: [PATCH] irqchip: bcm2835: Add FIQ support In-Reply-To: <1434130016-26574-1-git-send-email-noralf@tronnes.org> References: <1434130016-26574-1-git-send-email-noralf@tronnes.org> Message-ID: <87d1zj6fq2.fsf@eliezer.anholt.net> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Noralf Tr?nnes writes: > Add a duplicate irq range with an offset on the hwirq's so the > driver can detect that enable_fiq() is used. > Tested with downstream dwc_otg USB controller driver. > > Signed-off-by: Noralf Tr?nnes > --- > arch/arm/mach-bcm/Kconfig | 1 + > drivers/irqchip/irq-bcm2835.c | 53 ++++++++++++++++++++++++++++++++++++++----- > 2 files changed, 48 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig > index 8b11f44..7cfef7b 100644 > --- a/arch/arm/mach-bcm/Kconfig > +++ b/arch/arm/mach-bcm/Kconfig > @@ -114,6 +114,7 @@ config ARCH_BCM2835 > select ARM_ERRATA_411920 > select ARM_TIMER_SP804 > select CLKSRC_OF > + select FIQ > select PINCTRL > select PINCTRL_BCM2835 > help > diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c > index 5916d6c..db66246 100644 > --- a/drivers/irqchip/irq-bcm2835.c > +++ b/drivers/irqchip/irq-bcm2835.c > @@ -56,7 +56,7 @@ > #include "irqchip.h" > > /* Put the bank and irq (32 bits) into the hwirq */ > -#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) > +#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) > #define HWIRQ_BANK(i) (i >> 5) > #define HWIRQ_BIT(i) BIT(i & 0x1f) > > @@ -72,9 +72,13 @@ > | SHORTCUT1_MASK | SHORTCUT2_MASK) > > #define REG_FIQ_CONTROL 0x0c > +#define REG_FIQ_ENABLE 0x80 > +#define REG_FIQ_DISABLE 0 > > #define NR_BANKS 3 > #define IRQS_PER_BANK 32 > +#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) > +#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) > > static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; > static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; > @@ -98,14 +102,38 @@ static struct armctrl_ic intc __read_mostly; > static void __exception_irq_entry bcm2835_handle_irq( > struct pt_regs *regs); > > +static inline unsigned int hwirq_to_fiq(unsigned long hwirq) > +{ > + hwirq -= NUMBER_IRQS; > + /* > + * The hwirq numbering used in this driver is: > + * BASE (0-7) GPU1 (32-63) GPU2 (64-95). > + * This differ from the one used in the FIQ register: > + * GPU1 (0-31) GPU2 (32-63) BASE (64-71) > + */ > + if (hwirq >= 32) > + return hwirq - 32; > + > + return hwirq + 64; > +} > + > static void armctrl_mask_irq(struct irq_data *d) > { > - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); > + if (d->hwirq >= NUMBER_IRQS) > + writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); > + else > + writel_relaxed(HWIRQ_BIT(d->hwirq), > + intc.disable[HWIRQ_BANK(d->hwirq)]); > } > > static void armctrl_unmask_irq(struct irq_data *d) > { > - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); > + if (d->hwirq >= NUMBER_IRQS) > + writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), > + intc.base + REG_FIQ_CONTROL); > + else > + writel_relaxed(HWIRQ_BIT(d->hwirq), > + intc.enable[HWIRQ_BANK(d->hwirq)]); > } I found it nice for the 2836 controller to declare a new irqchip when both the mask/unmask hooks needed to be changed for that class of interrupt. However, it looks like these functions aren't going to be called regularly, so it doesn't matter much. As far as interaction with my 2836 series, it looks like the only thing downstream does is make the FIQ get handled on CPU1 instead of CPU0. I think we'll be fine fixing this up later. Reviewed-by: Eric Anholt -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 818 bytes Desc: not available URL: