Message ID | 20210120132717.395873-5-mohamed.mediouni@caramail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Linux on Apple Silicon | expand |
On 20.01.21 14:27, Mohamed Mediouni wrote: > From: Stan Skowronek <stan@corellium.com> > > Apple SoCs use the Apple AIC interrupt controller. > The Arm architectural timers is wired over FIQ on that hardware. > > Signed-off-by: Stan Skowronek <stan@corellium.com> > Signed-off-by: Mohamed Mediouni <mohamed.mediouni@caramail.com> > --- > .../interrupt-controller/apple,aic.yaml | 49 ++++ > MAINTAINERS | 6 + > drivers/irqchip/Kconfig | 6 + > drivers/irqchip/Makefile | 1 + > drivers/irqchip/irq-apple-aic.c | 211 ++++++++++++++++++ > 5 files changed, 273 insertions(+) > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml > create mode 100644 drivers/irqchip/irq-apple-aic.c > > diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml > new file mode 100644 > index 000000000000..e615eaaca869 > --- /dev/null > +++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml > @@ -0,0 +1,49 @@ > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/interrupt-controller/apple,aic.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Apple Advanced Interrupt Controller (AIC) > + > +description: > + Interrupt controller present on Apple processors. AIC > + is used by Apple on their AArch64 SoCs since the Apple A7. > + > +maintainers: > + - Stan Skowronek <stan@corellium.com> > + > +properties: > + compatible: > + items: > + - const: apple,aic > + > + reg: > + maxItems: 1 > + > + '#interrupt-cells': > + const: 3 > + > + interrupt-controller: true > + > + fast-ipi: > + description: > + Fast IPI support. > + > +required: > + - compatible > + - '#interrupt-cells' > + - interrupt-controller > + - reg > + > +additionalProperties: false > + > +examples: > + - | > + aic: interrupt-controller@23b100000 { > + compatible = "apple,aic"; > + #interrupt-cells = <3>; > + interrupt-controller; > + reg = <0x2 0x3b100000 0x0 0x8000>; > + fast-ipi; > + }; > diff --git a/MAINTAINERS b/MAINTAINERS > index 00836f6452f0..e609ede99dd4 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1218,6 +1218,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor > F: Documentation/admin-guide/LSM/apparmor.rst > F: security/apparmor/ > > +APPLE ADVANCED INTERRUPT CONTROLLER DRIVER > +M: Stan Skowronek <stan@corellium.com> Signing someone else up for maintainership is ... unusual :). Do you have buy in from Stan that he'll be responsive and handle patch reviews? > +L: linux-arm-kernel@lists.infradead.org > +S: Maintained > +F: drivers/irqchip/irq-apple-aic.c > + Alex Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879
> On 20 Jan 2021, at 18:11, Alexander Graf <graf@amazon.com> wrote: > > On 20.01.21 14:27, Mohamed Mediouni wrote: >> From: Stan Skowronek <stan@corellium.com> >> Apple SoCs use the Apple AIC interrupt controller. >> The Arm architectural timers is wired over FIQ on that hardware. >> Signed-off-by: Stan Skowronek <stan@corellium.com> >> Signed-off-by: Mohamed Mediouni <mohamed.mediouni@caramail.com> >> --- >> .../interrupt-controller/apple,aic.yaml | 49 ++++ >> MAINTAINERS | 6 + >> drivers/irqchip/Kconfig | 6 + >> drivers/irqchip/Makefile | 1 + >> drivers/irqchip/irq-apple-aic.c | 211 ++++++++++++++++++ >> 5 files changed, 273 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml >> create mode 100644 drivers/irqchip/irq-apple-aic.c >> diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml >> new file mode 100644 >> index 000000000000..e615eaaca869 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml >> @@ -0,0 +1,49 @@ >> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause >> +%YAML 1.2 >> +--- >> +$id: http://devicetree.org/schemas/interrupt-controller/apple,aic.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: Apple Advanced Interrupt Controller (AIC) >> + >> +description: >> + Interrupt controller present on Apple processors. AIC >> + is used by Apple on their AArch64 SoCs since the Apple A7. >> + >> +maintainers: >> + - Stan Skowronek <stan@corellium.com> >> + >> +properties: >> + compatible: >> + items: >> + - const: apple,aic >> + >> + reg: >> + maxItems: 1 >> + >> + '#interrupt-cells': >> + const: 3 >> + >> + interrupt-controller: true >> + >> + fast-ipi: >> + description: >> + Fast IPI support. >> + >> +required: >> + - compatible >> + - '#interrupt-cells' >> + - interrupt-controller >> + - reg >> + >> +additionalProperties: false >> + >> +examples: >> + - | >> + aic: interrupt-controller@23b100000 { >> + compatible = "apple,aic"; >> + #interrupt-cells = <3>; >> + interrupt-controller; >> + reg = <0x2 0x3b100000 0x0 0x8000>; >> + fast-ipi; >> + }; >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 00836f6452f0..e609ede99dd4 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -1218,6 +1218,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor >> F: Documentation/admin-guide/LSM/apparmor.rst >> F: security/apparmor/ >> +APPLE ADVANCED INTERRUPT CONTROLLER DRIVER >> +M: Stan Skowronek <stan@corellium.com> > > Signing someone else up for maintainership is ... unusual :). Do you have buy in from Stan that he'll be responsive and handle patch reviews? Yeah, I asked Corellium about it explicitly. :) >> +L: linux-arm-kernel@lists.infradead.org >> +S: Maintained >> +F: drivers/irqchip/irq-apple-aic.c >> + > > > Alex > > > > Amazon Development Center Germany GmbH > Krausenstr. 38 > 10117 Berlin > Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss > Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B > Sitz: Berlin > Ust-ID: DE 289 237 879
> >> @@ -1218,6 +1218,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor > >> F: Documentation/admin-guide/LSM/apparmor.rst > >> F: security/apparmor/ > >> +APPLE ADVANCED INTERRUPT CONTROLLER DRIVER > >> +M: Stan Skowronek <stan@corellium.com> > > > > Signing someone else up for maintainership is ... unusual :). Do you have buy in from Stan that he'll be responsive and handle patch reviews? > > Yeah, I asked Corellium about it explicitly. :) Having an Ack-by: from Stan Skowronek would remove all doubt. Andrew
Acked-by: Stan Skowronek <stan@corellium.com> On 1/20/21 8:27 AM, Mohamed Mediouni wrote: > From: Stan Skowronek <stan@corellium.com> > > Apple SoCs use the Apple AIC interrupt controller. > The Arm architectural timers is wired over FIQ on that hardware. > > Signed-off-by: Stan Skowronek <stan@corellium.com> > Signed-off-by: Mohamed Mediouni <mohamed.mediouni@caramail.com> > --- > .../interrupt-controller/apple,aic.yaml | 49 ++++ > MAINTAINERS | 6 + > drivers/irqchip/Kconfig | 6 + > drivers/irqchip/Makefile | 1 + > drivers/irqchip/irq-apple-aic.c | 211 ++++++++++++++++++ > 5 files changed, 273 insertions(+) > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml > create mode 100644 drivers/irqchip/irq-apple-aic.c
Hi Mohamed, thanks for your patch! On Wed, Jan 20, 2021 at 2:31 PM Mohamed Mediouni <mohamed.mediouni@caramail.com> wrote: > +properties: > + compatible: > + items: > + - const: apple,aic However weird it may seem, Apple is not in the file Documentation/devicetree/bindings/vendor-prefixes.yaml (I think it's weird because I remember clearly that they have been using device tree for PPC since ages.) Could you add this 2-liner to that file and send it directly to DT binding maintainers as a single patch as a preparation? Yours, Linus Walleij
On Thu, Jan 21, 2021 at 10:48 AM Linus Walleij <linus.walleij@linaro.org> wrote: > > Hi Mohamed, > > thanks for your patch! > > On Wed, Jan 20, 2021 at 2:31 PM Mohamed Mediouni > <mohamed.mediouni@caramail.com> wrote: > > > +properties: > > + compatible: > > + items: > > + - const: apple,aic > > However weird it may seem, Apple is not in the file > Documentation/devicetree/bindings/vendor-prefixes.yaml > > (I think it's weird because I remember clearly that they have been > using device tree for PPC since ages.) > > Could you add this 2-liner to that file and send it directly to > DT binding maintainers as a single patch as a preparation? Choosing the vendor prefix here is going to be a little tricky and non-obvious. Background: Traditionally, it should have been the stock ticker symbol of the company (clearly only publicly traded companies would be able to produce a Unix capable computer, right?), but there were already inconsistent: IBM used "ibm" (in small letters), Sun used "SUNW" (in capitals) but in 2007 changed the stock ticker symbol to "JAVA", obviously without changing the firmware bindings. Apple traditionally used "AAPL" (also in caps) in the device tree, and there is one remnant of that in the M1 device tree, in the form of the "AAPL,phandle" property in each node, which corresponds to our "linux,phandle". (phandles were introduced as properties in both of the flattened DT formats, .dtb and apple's own format). There are also "AAPL,unit-string properties and some device_type strings (AAPL,display-crossbar, AAPL,atc-dpxbar, ...) in the M1 DT, and the CPU nodes (and only those) use "apple" in small letters as in "apple,icestorm","ARM,v8". The other nodes tend to not have a vendor prefix, but a lot use a subsystem name as the prefix, such as compatible="gpio,t8101" or compatible="tempsensor,t8020". Since Apple are already using both the "AAPL" and the "apple" prefix themselves, I have a bad feeling about reusing either of them for defining the devicetree.org bindings that we add to linux/Documentation/devicetree/bindings. The question is: if not "apple", what else should we use here? Arnd
On 21/01/2021 19.37, Arnd Bergmann wrote: > On Thu, Jan 21, 2021 at 10:48 AM Linus Walleij <linus.walleij@linaro.org> wrote: >> >> However weird it may seem, Apple is not in the file >> Documentation/devicetree/bindings/vendor-prefixes.yaml > > Since Apple are already using both the "AAPL" and the "apple" > prefix themselves, I have a bad feeling about reusing either of > them for defining the devicetree.org bindings that we add to > linux/Documentation/devicetree/bindings. The question is: if > not "apple", what else should we use here? This ties into the larger question of how we should handle devicetrees in general on these platforms. The two extremes are: 1) Have the bootloader outright convert ADT to FDT and make Linux support the entirety of Apple's devicetree structure, or 2) Maintain our own devicetrees and ignore Apple's entirely My feeling is that 1) is a non-starter, because Linux ARM device trees and Apple ARM device trees have seen independent evolution from the PowerPC era, and many details are completely different. Plus conversion is non-trivial, because the endianness is different and the format is too ambiguous to do programmatically without complex logic. On the other hand, cranking out devicetrees by hand for every device variant that Apple puts out is a waste of time. Obviously at the bare minimum the bootloader will need to move some dynamic information from the ADT to the FDT, but that can be a very specific set of properties (memory layout, MAC addresses, etc). My current thinking is that we should write offline, automated tooling to parse, diff, and automatically convert portions of Apple devicetrees into Linux ones. Then we can more easily maintain our own, but still ultimately have humans decide what goes into the Linux device trees. It's worth noting that AIUI Apple does not consider their devicetree layout to be stable, and it may change any time. On M1 devices, the devicetree is provided as part of the iBoot2 firmware bundle, which means it changes from one macOS version to the next (this is paired with the Darwin kernel itself, and they are upgraded as a unit). It includes placeholder values that iBoot2 then replaces with data from NOR before handing control over to the kernel. My goal for our long-term project [1] is to keep up with iBoot2 updates so that we do not have to instruct users to dig up old macOS versions. Quick TL;DR on how these things boot: - Boot ROM boots - iBoot1 (system firmware) in NOR flash which looks for a bootable OS in internal storage (only!) in the form of an APFS container+volume and then boots - iBoot2 (OS loader) which loads a bunch of firmware blobs and the devicetree off of storage, customizes it with system data from NOR, and then loads a wrapped mach-o file containing - A Darwin kernel, or in our case a Linux bootloader which then boots - A standard arm64 Linux blob The boot ROM is ROM. iBoot1 only ever rolls forward (downgrades impossible). iBoot2 downgrades are possible but Apple already proved they can break this willingly or not, at least in betas (macOS 11.2 Beta2 iBoot1 cannot boot Beta1 iBoot2). The secureboot chain goes all the way up to the mach-o kernel load, that is the first point where we can change boot policy to load anything we want (with user consent). [1] https://asahilinux.org/
On Thu, Jan 21, 2021 at 3:49 AM Linus Walleij <linus.walleij@linaro.org> wrote: > > Hi Mohamed, > > thanks for your patch! > > On Wed, Jan 20, 2021 at 2:31 PM Mohamed Mediouni > <mohamed.mediouni@caramail.com> wrote: > > > +properties: > > + compatible: > > + items: > > + - const: apple,aic As mentioned in patch 7, this needs to be SoC specific. Also, bindings should be separate patch. checkpatch.pl will tell you this. > However weird it may seem, Apple is not in the file > Documentation/devicetree/bindings/vendor-prefixes.yaml > > (I think it's weird because I remember clearly that they have been > using device tree for PPC since ages.) That's because the vendor prefix is 'AAPL' which is the stock ticker and it predates documenting anything. > Could you add this 2-liner to that file and send it directly to > DT binding maintainers as a single patch as a preparation? So this is still needed. Happy to take that given already in use. Rob
On 20/01/2021 22.27, Mohamed Mediouni wrote: > + irq_domain_set_info(d, virq, hw, &apple_aic_irq_chip, > + d->host_data, handle_level_irq, NULL, NULL); The AIC automatically masks IRQs on reason fetch, which means the handle_level_irq flow is redundant. Using the fasteoi flow, as in [1], should be more efficient. [1] https://github.com/AsahiLinux/linux/commit/d4cb18c93
On Thu, Jan 21, 2021 at 9:31 AM Hector Martin 'marcan' <marcan@marcan.st> wrote: > > On 21/01/2021 19.37, Arnd Bergmann wrote: > > On Thu, Jan 21, 2021 at 10:48 AM Linus Walleij <linus.walleij@linaro.org> wrote: > >> > >> However weird it may seem, Apple is not in the file > >> Documentation/devicetree/bindings/vendor-prefixes.yaml > > > > Since Apple are already using both the "AAPL" and the "apple" > > prefix themselves, I have a bad feeling about reusing either of > > them for defining the devicetree.org bindings that we add to > > linux/Documentation/devicetree/bindings. The question is: if > > not "apple", what else should we use here? > > This ties into the larger question of how we should handle devicetrees > in general on these platforms. > > The two extremes are: > > 1) Have the bootloader outright convert ADT to FDT and make Linux > support the entirety of Apple's devicetree structure, or > > 2) Maintain our own devicetrees and ignore Apple's entirely > > My feeling is that 1) is a non-starter, because Linux ARM device trees > and Apple ARM device trees have seen independent evolution from the > PowerPC era, and many details are completely different. Plus conversion > is non-trivial, because the endianness is different and the format is > too ambiguous to do programmatically without complex logic. You are right it's a non-starter. Apple's DT even from PowerPC days were weird and the hardware was much simpler then. Given we're still maintaining that code I don't care to add what they've evolved on their own over the last 15 years and support it for the next 20+ years (given folks notice when we break 1998 era Macs). > On the other hand, cranking out devicetrees by hand for every device > variant that Apple puts out is a waste of time. > > Obviously at the bare minimum the bootloader will need to move some > dynamic information from the ADT to the FDT, but that can be a very > specific set of properties (memory layout, MAC addresses, etc). > > My current thinking is that we should write offline, automated tooling > to parse, diff, and automatically convert portions of Apple devicetrees > into Linux ones. Then we can more easily maintain our own, but still > ultimately have humans decide what goes into the Linux device trees. Seems reasonable. > It's worth noting that AIUI Apple does not consider their devicetree > layout to be stable, and it may change any time. Yeah, also not something we want to support. > On M1 devices, the > devicetree is provided as part of the iBoot2 firmware bundle, which > means it changes from one macOS version to the next (this is paired with > the Darwin kernel itself, and they are upgraded as a unit). It includes > placeholder values that iBoot2 then replaces with data from NOR before > handing control over to the kernel. My goal for our long-term project > [1] is to keep up with iBoot2 updates so that we do not have to instruct > users to dig up old macOS versions. > > Quick TL;DR on how these things boot: > - Boot ROM boots > - iBoot1 (system firmware) in NOR flash which looks for a bootable OS in > internal storage (only!) in the form of an APFS container+volume and > then boots > - iBoot2 (OS loader) which loads a bunch of firmware blobs and the > devicetree off of storage, customizes it with system data from NOR, and > then loads a wrapped mach-o file containing > - A Darwin kernel, or in our case a Linux bootloader which then boots > - A standard arm64 Linux blob > > The boot ROM is ROM. iBoot1 only ever rolls forward (downgrades > impossible). iBoot2 downgrades are possible but Apple already proved > they can break this willingly or not, at least in betas (macOS 11.2 > Beta2 iBoot1 cannot boot Beta1 iBoot2). The secureboot chain goes all > the way up to the mach-o kernel load, that is the first point where we > can change boot policy to load anything we want (with user consent). > > [1] https://asahilinux.org/ > > -- > Hector Martin "marcan" (marcan@marcan.st) > Public Key: https://mrcn.st/pub > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Thu, Jan 21, 2021 at 4:38 AM Arnd Bergmann <arnd@kernel.org> wrote: > > On Thu, Jan 21, 2021 at 10:48 AM Linus Walleij <linus.walleij@linaro.org> wrote: > > > > Hi Mohamed, > > > > thanks for your patch! > > > > On Wed, Jan 20, 2021 at 2:31 PM Mohamed Mediouni > > <mohamed.mediouni@caramail.com> wrote: > > > > > +properties: > > > + compatible: > > > + items: > > > + - const: apple,aic > > > > However weird it may seem, Apple is not in the file > > Documentation/devicetree/bindings/vendor-prefixes.yaml > > > > (I think it's weird because I remember clearly that they have been > > using device tree for PPC since ages.) > > > > Could you add this 2-liner to that file and send it directly to > > DT binding maintainers as a single patch as a preparation? > > Choosing the vendor prefix here is going to be a little tricky > and non-obvious. > > Background: > > Traditionally, it should have been the stock ticker symbol of the > company (clearly only publicly traded companies would be able > to produce a Unix capable computer, right?), but there were > already inconsistent: IBM used "ibm" (in small letters), Sun > used "SUNW" (in capitals) but in 2007 changed the stock ticker > symbol to "JAVA", obviously without changing the firmware bindings. > > Apple traditionally used "AAPL" (also in caps) in the device tree, > and there is one remnant of that in the M1 device tree, in the form > of the "AAPL,phandle" property in each node, which corresponds > to our "linux,phandle". (phandles were introduced as properties in > both of the flattened DT formats, .dtb and apple's own format). > There are also "AAPL,unit-string properties and some device_type > strings (AAPL,display-crossbar, AAPL,atc-dpxbar, ...) in the M1 DT, > and the CPU nodes (and only those) use "apple" in small letters > as in "apple,icestorm","ARM,v8". The other nodes tend to not have > a vendor prefix, but a lot use a subsystem name as the prefix, such > as compatible="gpio,t8101" or compatible="tempsensor,t8020". > > Since Apple are already using both the "AAPL" and the "apple" > prefix themselves, I have a bad feeling about reusing either of > them for defining the devicetree.org bindings that we add to > linux/Documentation/devicetree/bindings. The question is: if > not "apple", what else should we use here? IMO, 'AAPL' as that is what is already in use in the kernel. I don't see why it matters at all what Apple is using. It might if we used any of the ADT as-is, but I don't see that happening from what I've seen. Rob
diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml new file mode 100644 index 000000000000..e615eaaca869 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/apple,aic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Advanced Interrupt Controller (AIC) + +description: + Interrupt controller present on Apple processors. AIC + is used by Apple on their AArch64 SoCs since the Apple A7. + +maintainers: + - Stan Skowronek <stan@corellium.com> + +properties: + compatible: + items: + - const: apple,aic + + reg: + maxItems: 1 + + '#interrupt-cells': + const: 3 + + interrupt-controller: true + + fast-ipi: + description: + Fast IPI support. + +required: + - compatible + - '#interrupt-cells' + - interrupt-controller + - reg + +additionalProperties: false + +examples: + - | + aic: interrupt-controller@23b100000 { + compatible = "apple,aic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x2 0x3b100000 0x0 0x8000>; + fast-ipi; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 00836f6452f0..e609ede99dd4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1218,6 +1218,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor F: Documentation/admin-guide/LSM/apparmor.rst F: security/apparmor/ +APPLE ADVANCED INTERRUPT CONTROLLER DRIVER +M: Stan Skowronek <stan@corellium.com> +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: drivers/irqchip/irq-apple-aic.c + APPLE BCM5974 MULTITOUCH DRIVER M: Henrik Rydberg <rydberg@bitmath.org> L: linux-input@vger.kernel.org diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 94920a51c628..3aa9e711324b 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -56,6 +56,12 @@ config ARM_GIC_V3_ITS_FSL_MC depends on FSL_MC_BUS default ARM_GIC_V3_ITS +config APPLE_AIC + bool + select IRQ_DOMAIN_HIERARCHY + select GENERIC_IRQ_MULTI_HANDLER + select GENERIC_IRQ_EFFECTIVE_AFF_MASK + config ARM_NVIC bool select IRQ_DOMAIN_HIERARCHY diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 0ac93bfaec61..2f5a9a0cf40f 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-v3-mbi.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o obj-$(CONFIG_ARM_GIC_V3_ITS_PCI) += irq-gic-v3-its-pci-msi.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) += irq-gic-v3-its-fsl-mc-msi.o +obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c new file mode 100644 index 000000000000..c601bc4b501a --- /dev/null +++ b/drivers/irqchip/irq-apple-aic.c @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Apple chip interrupt controller + * + * Copyright (C) 2020 Corellium LLC + * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar + * + */ + +#include <linux/interrupt.h> +#include <linux/err.h> +#include <linux/irqdomain.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/exception.h> +#include <asm/irq.h> + +#define REG_ID_REVISION 0x0000 +#define REG_ID_CONFIG 0x0004 +#define REG_GLOBAL_CFG 0x0010 +#define REG_TIME_LO 0x0020 +#define REG_TIME_HI 0x0028 +#define REG_ID_CPUID 0x2000 +#define REG_IRQ_ACK 0x2004 +#define REG_IRQ_ACK_TYPE_MASK (15 << 16) +#define REG_IRQ_ACK_TYPE_NONE (0 << 16) +#define REG_IRQ_ACK_TYPE_IRQ (1 << 16) +#define REG_IRQ_ACK_TYPE_IPI (4 << 16) +#define REG_IRQ_ACK_IPI_OTHER 0x40001 +#define REG_IRQ_ACK_IPI_SELF 0x40002 +#define REG_IRQ_ACK_NUM_MASK (4095) +#define REG_IPI_SET 0x2008 +#define REG_IPI_FLAG_SELF (1 << 31) +#define REG_IPI_FLAG_OTHER (1 << 0) +#define REG_IPI_CLEAR 0x200C +#define REG_IPI_DISABLE 0x2024 +#define REG_IPI_ENABLE 0x2028 +#define REG_IPI_DEFER_SET 0x202C +#define REG_IPI_DEFER_CLEAR 0x2030 +#define REG_TSTAMP_CTRL 0x2040 +#define REG_TSTAMP_LO 0x2048 +#define REG_TSTAMP_HI 0x204C +#define REG_IRQ_AFFINITY(i) (0x3000 + ((i) << 2)) +#define REG_IRQ_DISABLE(i) (0x4100 + (((i) >> 5) << 2)) +#define REG_IRQ_xABLE_MASK(i) (1 << ((i)&31)) +#define REG_IRQ_ENABLE(i) (0x4180 + (((i) >> 5) << 2)) +#define REG_CPU_REGION 0x5000 +#define REG_CPU_LOCAL 0x2000 +#define REG_CPU_SHIFT 7 +#define REG_PERCPU(r, c) \ + ((r) + REG_CPU_REGION - REG_CPU_LOCAL + ((c) << REG_CPU_SHIFT)) + +static struct aic_chip_data { + void __iomem *base; + struct irq_domain *domain; + unsigned int num_irqs; +} aic; + +static void apple_aic_irq_mask(struct irq_data *d) +{ + writel(REG_IRQ_xABLE_MASK(d->hwirq), + aic.base + REG_IRQ_DISABLE(d->hwirq)); +} + +static void apple_aic_irq_unmask(struct irq_data *d) +{ + writel(REG_IRQ_xABLE_MASK(d->hwirq), + aic.base + REG_IRQ_ENABLE(d->hwirq)); +} + +static struct irq_chip apple_aic_irq_chip = { + .name = "apple_aic", + .irq_mask = apple_aic_irq_mask, + .irq_mask_ack = apple_aic_irq_mask, + .irq_unmask = apple_aic_irq_unmask, +}; + +static void apple_aic_fiq_mask(struct irq_data *d) +{ +} + +static void apple_aic_fiq_unmask(struct irq_data *d) +{ +} + +static struct irq_chip apple_aic_irq_chip_fiq = { + .name = "apple_aic_fiq", + .irq_mask = apple_aic_fiq_mask, + .irq_unmask = apple_aic_fiq_unmask, +}; + +static int apple_aic_irq_domain_xlate(struct irq_domain *d, + struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (intspec[0]) { /* FIQ */ + if (intspec[1] >= 2) + return -EINVAL; + if (out_hwirq) + *out_hwirq = aic.num_irqs + intspec[1]; + } else { + if (intspec[1] >= aic.num_irqs) + return -EINVAL; + if (out_hwirq) + *out_hwirq = intspec[1]; + } + + if (out_type) + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + return 0; +} + +static int apple_aic_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + if (hw >= aic.num_irqs) { + irq_set_percpu_devid(virq); + irq_domain_set_info(d, virq, hw, &apple_aic_irq_chip_fiq, + d->host_data, handle_percpu_devid_irq, NULL, + NULL); + irq_set_status_flags(virq, IRQ_NOAUTOEN); + } else { + irq_domain_set_info(d, virq, hw, &apple_aic_irq_chip, + d->host_data, handle_level_irq, NULL, NULL); + irq_set_probe(virq); + irqd_set_single_target( + irq_desc_get_irq_data(irq_to_desc(virq))); + } + return 0; +} + +static const struct irq_domain_ops apple_aic_irq_domain_ops = { + .xlate = apple_aic_irq_domain_xlate, + .map = apple_aic_irq_domain_map, +}; + +static void __exception_irq_entry apple_aic_handle_irq(struct pt_regs *regs) +{ + uint32_t ack; + unsigned done = 0; + + while (1) { + ack = readl(aic.base + REG_IRQ_ACK); + switch (ack & REG_IRQ_ACK_TYPE_MASK) { + case REG_IRQ_ACK_TYPE_NONE: + done = 1; + break; + case REG_IRQ_ACK_TYPE_IRQ: + handle_domain_irq(aic.domain, + ack & REG_IRQ_ACK_NUM_MASK, regs); + break; + } + if (done) + break; + } +} + +static void __exception_irq_entry apple_aic_handle_fiq(struct pt_regs *regs) +{ + handle_domain_irq(aic.domain, aic.num_irqs, regs); +} + +void apple_aic_cpu_prepare(unsigned int cpu) +{ + unsigned i; + + for (i = 0; i < aic.num_irqs; i++) + writel(readl(aic.base + REG_IRQ_AFFINITY(i)) | (1u << cpu), + aic.base + REG_IRQ_AFFINITY(i)); +} + +static int __init apple_aic_init(struct device_node *node, + struct device_node *interrupt_parent) +{ + unsigned i; + + if (!node) + return -ENODEV; + + aic.base = of_iomap(node, 0); + if (WARN(!aic.base, "unable to map aic registers\n")) + return -EINVAL; + + aic.num_irqs = readl(aic.base + REG_ID_CONFIG) & 0xFFFF; + pr_info("Apple AIC: %d IRQs + 1 FIQ + 1 dummy\n", aic.num_irqs); + + for (i = 0; i < aic.num_irqs; i++) + writel(1, aic.base + REG_IRQ_AFFINITY(i)); + for (i = 0; i < aic.num_irqs; i += 32) + writel(-1u, aic.base + REG_IRQ_DISABLE(i)); + writel((readl(aic.base + REG_GLOBAL_CFG) & ~0xF00000) | 0x700000, + aic.base + REG_GLOBAL_CFG); + + set_handle_irq(apple_aic_handle_irq); + set_handle_fiq(apple_aic_handle_fiq); + + apple_aic_cpu_prepare(0); + + aic.domain = irq_domain_add_linear(node, aic.num_irqs + 2, + &apple_aic_irq_domain_ops, + &apple_aic_irq_chip); + irq_set_default_host(aic.domain); + return 0; +} + +IRQCHIP_DECLARE(apple_aic_irq_chip, "apple,aic", apple_aic_init);