summaryrefslogtreecommitdiff
path: root/drivers/irqchip/irq-sifive-plic.c
AgeCommit message (Collapse)Author
2024-10-08irqchip/sifive-plic: Unmask interrupt in plic_irq_enable()Nam Cao
It is possible that an interrupt is disabled and masked at the same time. When the interrupt is enabled again by enable_irq(), only plic_irq_enable() is called, not plic_irq_unmask(). The interrupt remains masked and never raises. An example where interrupt is both disabled and masked is when handle_fasteoi_irq() is the handler, and IRQS_ONESHOT is set. The interrupt handler: 1. Mask the interrupt 2. Handle the interrupt 3. Check if interrupt is still enabled, and unmask it (see cond_unmask_eoi_irq()) If another task disables the interrupt in the middle of the above steps, the interrupt will not get unmasked, and will remain masked when it is enabled in the future. The problem is occasionally observed when PREEMPT_RT is enabled, because PREEMPT_RT adds the IRQS_ONESHOT flag. But PREEMPT_RT only makes the problem more likely to appear, the bug has been around since commit a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask operations"). Fix it by unmasking interrupt in plic_irq_enable(). Fixes: a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask operations") Signed-off-by: Nam Cao <namcao@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20241003084152.2422969-1-namcao@linutronix.de
2024-10-02irqchip/sifive-plic: Return error code on failureCharlie Jenkins
Set error to -ENOMEM if kcalloc() fails or if irq_domain_add_linear() fails inside of plic_probe() instead of returning 0. Fixes: 4d936f10ff80 ("irqchip/sifive-plic: Probe plic driver early for Allwinner D1 platform") Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20240903-correct_error_codes_sifive_plic-v1-1-d929b79663a2@rivosinc.com Closes: https://lore.kernel.org/r/202409031122.yBh8HrxA-lkp@intel.com/
2024-09-02irqchip/sifive-plic: Add ACPI supportSunil V L
Add ACPI support in PLIC driver. Use the mapping created early during boot to get details about the PLIC. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> Co-developed-by: Haibo Xu <haibo1.xu@intel.com> Signed-off-by: Haibo Xu <haibo1.xu@intel.com> Reviewed-by: Anup Patel <anup@brainfault.org> Tested-by: Björn Töpel <bjorn@rivosinc.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Link: https://patch.msgid.link/20240812005929.113499-18-sunilvl@ventanamicro.com [ rjw: Rebase on top of recent irqchip changes ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2024-08-20irqchip/sifive-plic: Probe plic driver early for Allwinner D1 platformAnup Patel
The latest Linux RISC-V no longer boots on the Allwinner D1 platform because the sun4i_timer driver fails to get an interrupt from PLIC due to the recent conversion of the PLIC to a platform driver. Converting the sun4i timer to a platform driver does not work either because the D1 does not have a SBI timer available so early boot hangs. See the 'Closes:' link for deeper analysis. The real fix requires enabling the SBI time extension in the platform firmware (OpenSBI) and convert sun4i_timer into platform driver. Unfortunately, the real fix involves changing multiple places and can't be achieved in a short duration and aside of that requires users to update firmware. As a work-around, retrofit PLIC probing such that the PLIC is probed early only for the Allwinner D1 platform and probed as a regular platform driver for rest of the RISC-V platforms. In the process, partially revert some of the previous changes because the PLIC device pointer is not available in all probing paths. Fixes: e306a894bd51 ("irqchip/sifive-plic: Chain to parent IRQ after handlers are ready") Fixes: 8ec99b033147 ("irqchip/sifive-plic: Convert PLIC driver into a platform driver") Suggested-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Samuel Holland <samuel.holland@sifive.com> Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com> Tested-by: Charlie Jenkins <charlie@rivosinc.com> Reviewed-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20240820034850.3189912-1-apatel@ventanamicro.com Closes: https://lore.kernel.org/lkml/20240814145642.344485-1-emil.renner.berthing@canonical.com/
2024-06-03irqchip/sifive-plic: Chain to parent IRQ after handlers are readySamuel Holland
Now that the PLIC uses a platform driver, the driver is probed later in the boot process, where interrupts from peripherals might already be pending. As a result, plic_handle_irq() may be called as early as the call to irq_set_chained_handler() completes. But this call happens before the per-context handler is completely set up, so there is a window where plic_handle_irq() can see incomplete per-context state and crash. Avoid this by delaying the call to irq_set_chained_handler() until all handlers from all PLICs are initialized. Fixes: 8ec99b033147 ("irqchip/sifive-plic: Convert PLIC driver into a platform driver") Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Anup Patel <anup@brainfault.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240529215458.937817-1-samuel.holland@sifive.com Closes: https://lore.kernel.org/r/CAMuHMdVYFFR7K5SbHBLY-JHhb7YpgGMS_hnRWm8H0KD-wBo+4A@mail.gmail.com/
2024-04-24irqchip/sifive-plic: Avoid explicit cpumask allocation on stackDawei Li
In general it's preferable to avoid placing cpumasks on the stack, as for large values of NR_CPUS these can consume significant amounts of stack space and make stack overflows more likely. Use cpumask_first_and_and() to avoid the need for a temporary cpumask on the stack. Signed-off-by: Dawei Li <dawei.li@shingroup.cn> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20240416085454.3547175-7-dawei.li@shingroup.cn
2024-03-11Merge tag 'irq-msi-2024-03-10' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull MSI updates from Thomas Gleixner: "Updates for the MSI interrupt subsystem and initial RISC-V MSI support. The core changes have been adopted from previous work which converted ARM[64] to the new per device MSI domain model, which was merged to support multiple MSI domain per device. The ARM[64] changes are being worked on too, but have not been ready yet. The core and platform-MSI changes have been split out to not hold up RISC-V and to avoid that RISC-V builds on the scheduled for removal interfaces. The core support provides new interfaces to handle wire to MSI bridges in a straight forward way and introduces new platform-MSI interfaces which are built on top of the per device MSI domain model. Once ARM[64] is converted over the old platform-MSI interfaces and the related ugliness in the MSI core code will be removed. The actual MSI parts for RISC-V were finalized late and have been post-poned for the next merge window. Drivers: - Add a new driver for the Andes hart-level interrupt controller - Rework the SiFive PLIC driver to prepare for MSI suport - Expand the RISC-V INTC driver to support the new RISC-V AIA controller which provides the basis for MSI on RISC-V - A few fixup for the fallout of the core changes" * tag 'irq-msi-2024-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (29 commits) irqchip/riscv-intc: Fix low-level interrupt handler setup for AIA x86/apic/msi: Use DOMAIN_BUS_GENERIC_MSI for HPET/IO-APIC domain search genirq/matrix: Dynamic bitmap allocation irqchip/riscv-intc: Add support for RISC-V AIA irqchip/sifive-plic: Improve locking safety by using irqsave/irqrestore irqchip/sifive-plic: Parse number of interrupts and contexts early in plic_probe() irqchip/sifive-plic: Cleanup PLIC contexts upon irqdomain creation failure irqchip/sifive-plic: Use riscv_get_intc_hwnode() to get parent fwnode irqchip/sifive-plic: Use devm_xyz() for managed allocation irqchip/sifive-plic: Use dev_xyz() in-place of pr_xyz() irqchip/sifive-plic: Convert PLIC driver into a platform driver irqchip/riscv-intc: Introduce Andes hart-level interrupt controller irqchip/riscv-intc: Allow large non-standard interrupt number genirq/irqdomain: Don't call ops->select for DOMAIN_BUS_ANY tokens irqchip/imx-intmux: Handle pure domain searches correctly genirq/msi: Provide MSI_FLAG_PARENT_PM_DEV genirq/irqdomain: Reroute device MSI create_mapping genirq/msi: Provide allocation/free functions for "wired" MSI interrupts genirq/msi: Optionally use dev->fwnode for device domain genirq/msi: Provide DOMAIN_BUS_WIRED_TO_MSI ...
2024-02-23irqchip/sifive-plic: Improve locking safety by using irqsave/irqrestoreAnup Patel
Now that PLIC driver is probed as a regular platform driver, the lock dependency validator complains about the safety of handler->enable_lock usage: [ 0.956775] Possible interrupt unsafe locking scenario: [ 0.956998] CPU0 CPU1 [ 0.957247] ---- ---- [ 0.957439] lock(&handler->enable_lock); [ 0.957607] local_irq_disable(); [ 0.957793] lock(&irq_desc_lock_class); [ 0.958021] lock(&handler->enable_lock); [ 0.958246] <Interrupt> [ 0.958342] lock(&irq_desc_lock_class); [ 0.958501] *** DEADLOCK *** To address above, use raw_spin_lock_irqsave/unlock_irqrestore() instead of raw_spin_lock/unlock(). Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-8-apatel@ventanamicro.com
2024-02-23irqchip/sifive-plic: Parse number of interrupts and contexts early in ↵Anup Patel
plic_probe() The SiFive PLIC driver needs to know the number of interrupts and contexts to complete initialization. Parse these details early in plic_probe() to avoid unnecessary memory allocations and register mappings if these details are not available. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-7-apatel@ventanamicro.com
2024-02-23irqchip/sifive-plic: Cleanup PLIC contexts upon irqdomain creation failureAnup Patel
The SiFive PLIC contexts should not be left dangling if irqdomain creation fails because plic_starting_cpu() can crash accessing unmapped registers. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-6-apatel@ventanamicro.com
2024-02-23irqchip/sifive-plic: Use riscv_get_intc_hwnode() to get parent fwnodeAnup Patel
The RISC-V INTC irqdomain is always the parent irqdomain of SiFive PLIC so use riscv_get_intc_hwnode() to get the parent fwnode similar to other RISC-V drivers which use local interrupts. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-5-apatel@ventanamicro.com
2024-02-23irqchip/sifive-plic: Use devm_xyz() for managed allocationAnup Patel
Use devm_xyz() for allocations and mappings managed by the Linux device driver framework. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-4-apatel@ventanamicro.com
2024-02-23irqchip/sifive-plic: Use dev_xyz() in-place of pr_xyz()Anup Patel
Use dev_info(), dev_warn(), and dev_err() in-place of pr_info(), pr_warn(), and pr_err(). Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-3-apatel@ventanamicro.com
2024-02-23irqchip/sifive-plic: Convert PLIC driver into a platform driverAnup Patel
The PLIC driver does not require very early initialization so convert it into a platform driver. After conversion, the PLIC driver is probed after CPUs are brought-up so setup cpuhp state after context handler of all online CPUs are initialized otherwise PLIC driver crashes for platforms with multiple PLIC instances. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240222094006.1030709-2-apatel@ventanamicro.com
2024-02-19irqchip/sifive-plic: Enable interrupt if needed before EOINam Cao
RISC-V PLIC cannot "end-of-interrupt" (EOI) disabled interrupts, as explained in the description of Interrupt Completion in the PLIC spec: "The PLIC signals it has completed executing an interrupt handler by writing the interrupt ID it received from the claim to the claim/complete register. The PLIC does not check whether the completion ID is the same as the last claim ID for that target. If the completion ID does not match an interrupt source that *is currently enabled* for the target, the completion is silently ignored." Commit 69ea463021be ("irqchip/sifive-plic: Fixup EOI failed when masked") ensured that EOI is successful by enabling interrupt first, before EOI. Commit a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask operations") removed the interrupt enabling code from the previous commit, because it assumes that interrupt should already be enabled at the point of EOI. However, this is incorrect: there is a window after a hart claiming an interrupt and before irq_desc->lock getting acquired, interrupt can be disabled during this window. Thus, EOI can be invoked while the interrupt is disabled, effectively nullify this EOI. This results in the interrupt never gets asserted again, and the device who uses this interrupt appears frozen. Make sure that interrupt is really enabled before EOI. Fixes: a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask operations") Signed-off-by: Nam Cao <namcao@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <paul.walmsley@sifive.com> Cc: Samuel Holland <samuel@sholland.org> Cc: Marc Zyngier <maz@kernel.org> Cc: Guo Ren <guoren@kernel.org> Cc: linux-riscv@lists.infradead.org Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20240131081933.144512-1-namcao@linutronix.de
2023-10-27irqchip/sifive-plic: Fix syscore registration for multi-socket systemsAnup Patel
Multi-socket systems have a separate PLIC in each socket, so __plic_init() is invoked for each PLIC. __plic_init() registers syscore operations, which obviously fails on the second invocation. Move it into the already existing condition for installing the CPU hotplug state so it is only invoked once when the first PLIC is initialized. [ tglx: Massaged changelog ] Fixes: e80f0b6a2cf3 ("irqchip/irq-sifive-plic: Add syscore callbacks for hibernation") Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20231025142820.390238-4-apatel@ventanamicro.com
2023-04-08irqchip/irq-sifive-plic: Add syscore callbacks for hibernationMason Huo
The priority and enable registers of plic will be reset during hibernation power cycle in poweroff mode, add the syscore callbacks to save/restore those registers. Signed-off-by: Mason Huo <mason.huo@starfivetech.com> Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com> Reviewed-by: Sia Jee Heng <jeeheng.sia@starfivetech.com> Reported-by: Dan Carpenter <error27@gmail.com> Link: https://lore.kernel.org/r/202302140709.CdkxgtPi-lkp@intel.com/ Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230404032908.89638-1-mason.huo@starfivetech.com
2022-11-28irqchip/sifive-plic: Support wake IRQsSamuel Holland
The PLIC does not define any special method for marking interrupts as wakeup-capable, so it should have the IRQCHIP_SKIP_SET_WAKE flag set. Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20221126194805.19431-1-samuel@sholland.org
2022-08-06Merge tag 'riscv-for-linus-5.20-mw0' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V updates from Palmer Dabbelt: - Enabling the FPU is now a static_key - Improvements to the Svpbmt support - CPU topology bindings for a handful of systems - Support for systems with 64-bit hart IDs - Many settings have been enabled in the defconfig, including both support for the StarFive systems and many of the Docker requirements There are also a handful of cleanups and improvements, as usual. * tag 'riscv-for-linus-5.20-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (28 commits) riscv: enable Docker requirements in defconfig riscv: convert the t-head pbmt errata to use the __nops macro riscv: introduce nops and __nops macros for NOP sequences RISC-V: Add fast call path of crash_kexec() riscv: mmap with PROT_WRITE but no PROT_READ is invalid riscv/efi_stub: Add 64bit boot-hartid support on RV64 riscv: cpu: Add 64bit hartid support on RV64 riscv: smp: Add 64bit hartid support on RV64 riscv: spinwait: Fix hartid variable type riscv: cpu_ops_sbi: Add 64bit hartid support on RV64 riscv: dts: sifive: "fix" pmic watchdog node name riscv: dts: canaan: Add k210 topology information riscv: dts: sifive: Add fu740 topology information riscv: dts: sifive: Add fu540 topology information riscv: dts: starfive: Add JH7100 CPU topology RISC-V: Add CONFIG_{NON,}PORTABLE riscv: config: enable SOC_STARFIVE in defconfig riscv: dts: microchip: Add mpfs' topology information riscv: Kconfig.socs: Add comments riscv: Kconfig.erratas: Add comments ...
2022-07-19riscv: cpu: Add 64bit hartid support on RV64Sunil V L
The hartid can be a 64bit value on RV64 platforms. Add support for 64bit hartid in riscv_of_processor_hartid() and update its callers. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> Reviewed-by: Atish Patra <atishp@rivosinc.com> Link: https://lore.kernel.org/r/20220527051743.2829940-5-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2022-07-10irqchip/sifive-plic: Separate the enable and mask operationsSamuel Holland
The PLIC has two per-IRQ checks before sending an IRQ to a hart context. First, it checks that the IRQ's priority is nonzero. Then, it checks that the enable bit is set for that combination of IRQ and context. Currently, the PLIC driver sets both the priority value and the enable bit in its (un)mask operations. However, modifying the enable bit is problematic for two reasons: 1) The enable bits are packed, so changes are not atomic and require taking a spinlock. 2) The following requirement from the PLIC spec, which explains the racy (un)mask operations in plic_irq_eoi(): If the completion ID does not match an interrupt source that is currently enabled for the target, the completion is silently ignored. Both of these problems are solved by using the priority value to mask IRQs. Each IRQ has a separate priority register, so writing the priority value is atomic. And since the enable bit remains set while an IRQ is masked, the EOI operation works normally. The enable bits are still used to control the IRQ's affinity. Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220701202440.59059-3-samuel@sholland.org
2022-07-10irqchip/sifive-plic: Make better use of the effective affinity maskSamuel Holland
The PLIC driver already updates the effective affinity mask in its .irq_set_affinity callback. Take advantage of that information to only touch bits (and take spinlocks) for the specific relevant hart contexts. First, make sure the effective affinity mask is set before IRQ startup. Then, since this mask already takes priv->lmask into account, checking that mask later is no longer needed (and handler->present is equivalent to the bit being set in priv->lmask). Finally, when (un)masking or changing affinity, only clear/set the enable bits in the specific old/new context(s). The cpumask operations in plic_irq_unmask() are not needed because they duplicate the code in plic_set_affinity(). Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220701202440.59059-2-samuel@sholland.org
2022-07-01irqchip/sifive-plic: Fix T-HEAD PLIC edge trigger handlingSamuel Holland
The T-HEAD PLIC ignores additional edges seen while an edge-triggered interrupt is being handled. Because of this behavior, the driver needs to complete edge-triggered interrupts in the .irq_ack callback before handling them, instead of in the .irq_eoi callback afterward. Otherwise, it could miss some interrupts. Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Signed-off-by: Samuel Holland <samuel@sholland.org> Reviewed-by: Guo Ren <guoren@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220630100241.35233-5-samuel@sholland.org
2022-07-01irqchip/sifive-plic: Add support for Renesas RZ/Five SoCLad Prabhakar
The Renesas RZ/Five SoC has a RISC-V AX45MP AndesCore with NCEPLIC100. The NCEPLIC100 supports both edge-triggered and level-triggered interrupts. In case of edge-triggered interrupts NCEPLIC100 ignores the next interrupt edge until the previous completion message has been received and NCEPLIC100 doesn't support pending interrupt counter, hence losing the interrupts if not acknowledged in time. So the workaround for edge-triggered interrupts to be handled correctly and without losing is that it needs to be acknowledged first and then handler must be run so that we don't miss on the next edge-triggered interrupt. This patch adds a new compatible string for NCEPLIC100 (from Andes Technology) interrupt controller found on Renesas RZ/Five SoC and adds quirk bits to priv structure and implements PLIC_QUIRK_EDGE_INTERRUPT quirk to change the interrupt flow. Suggested-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220630100241.35233-3-samuel@sholland.org
2022-03-14Merge tag 'irqchip-5.18' of ↵Thomas Gleixner
git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/core Pull irqchip updates from Marc Zyngier: - Add support for the STM32MP13 variant - Move parent device away from struct irq_chip - Remove all instances of non-const strings assigned to struct irq_chip::name, enabling a nice cleanup for VIC and GIC) - Simplify the Qualcomm PDC driver - A bunch of SiFive PLIC cleanups - Add support for a new variant of the Meson GPIO block - Add support for the irqchip side of the Apple M1 PMU - Add support for the Apple M1 Pro/Max AICv2 irqchip - Add support for the Qualcomm MPM wakeup gadget - Move the Xilinx driver over to the generic irqdomain handling - Tiny speedup for IPIs on GICv3 systems - The usual odd cleanups Link: https://lore.kernel.org/all/20220313105142.704579-1-maz@kernel.org
2022-03-02irqchip/sifive-plic: Disable S-mode IRQs if running in M-modeNiklas Cassel
When detecting a context for a privilege mode different from the current running privilege mode, we simply skip to the next context register. This means that we never clear the S-mode enable bits when running in M-mode. On canaan k210, a bunch of S-mode interrupts are enabled by the bootrom. These S-mode specific interrupts should never trigger, since we never set the mie.SEIE bit in the parent interrupt controller (riscv-intc). However, we will be able to see the mip.SEIE bit set as pending. This isn't a good default when CONFIG_RISCV_M_MODE is set, since in that case we will never enter a lower privilege mode (e.g. S-mode). Let's clear the S-mode enable bits when running the kernel in M-mode, such that we won't have a interrupt pending bit set, which we will never clear. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220302131544.3166154-3-Niklas.Cassel@wdc.com
2022-03-02irqchip/sifive-plic: Improve naming scheme for per context offsetsNiklas Cassel
The PLIC supports a fixed number of contexts (15872). Each context has fixed register offsets in PLIC. The number of contexts that we need to initialize depends on the privilege modes supported by each hart. Therefore, this mapping between PLIC context registers to hart privilege modes is platform specific, and is currently supplied via device tree. For example, canaan,k210 has the following mapping: Context0: hart0 M-mode Context1: hart0 S-mode Context2: hart1 M-mode Context3: hart1 S-mode While sifive,fu540 has the following mapping: Context0: hart0 M-mode Context1: hart1 M-mode Context2: hart1 S-mode Because the number of contexts per hart is not fixed, the names ENABLE_PER_HART and CONTEXT_PER_HART for the register offsets are quite confusing and might mislead the reader to think that these are fixed register offsets per hart. Rename the offsets to more clearly highlight that these are per PLIC context and not per hart. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220302131544.3166154-2-Niklas.Cassel@wdc.com
2022-02-02irqchip/sifive-plic: Add missing thead,c900-plic match stringGuo Ren
The thead,c900-plic has been used in opensbi to distinguish PLIC [1]. Although PLICs have the same behaviors in Linux, they are different hardware with some custom initializing in firmware(opensbi). Qute opensbi patch commit-msg by Samuel: The T-HEAD PLIC implementation requires setting a delegation bit to allow access from S-mode. Now that the T-HEAD PLIC has its own compatible string, set this bit automatically from the PLIC driver, instead of reaching into the PLIC's MMIO space from another driver. [1]: https://github.com/riscv-software-src/opensbi/commit/78c2b19218bd62653b9fb31623a42ced45f38ea6 Signed-off-by: Guo Ren <guoren@linux.alibaba.com> Cc: Anup Patel <anup@brainfault.org> Cc: Marc Zyngier <maz@kernel.org> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Samuel Holland <samuel@sholland.org> Cc: Thomas Gleixner <tglx@linutronix.de> Tested-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220130135634.1213301-3-guoren@kernel.org
2021-11-12irqchip/sifive-plic: Fixup EOI failed when maskedGuo Ren
When using "devm_request_threaded_irq(,,,,IRQF_ONESHOT,,)" in a driver, only the first interrupt is handled, and following interrupts are never delivered (initially reported in [1]). That's because the RISC-V PLIC cannot EOI masked interrupts, as explained in the description of Interrupt Completion in the PLIC spec [2]: <quote> The PLIC signals it has completed executing an interrupt handler by writing the interrupt ID it received from the claim to the claim/complete register. The PLIC does not check whether the completion ID is the same as the last claim ID for that target. If the completion ID does not match an interrupt source that *is currently enabled* for the target, the completion is silently ignored. </quote> Re-enable the interrupt before completion if it has been masked during the handling, and remask it afterwards. [1] http://lists.infradead.org/pipermail/linux-riscv/2021-July/007441.html [2] https://github.com/riscv/riscv-plic-spec/blob/8bc15a35d07c9edf7b5d23fec9728302595ffc4d/riscv-plic.adoc Fixes: bb0fed1c60cc ("irqchip/sifive-plic: Switch to fasteoi flow") Reported-by: Vincent Pelletier <plr.vincent@gmail.com> Tested-by: Nikita Shubin <nikita.shubin@maquefel.me> Signed-off-by: Guo Ren <guoren@linux.alibaba.com> Cc: stable@vger.kernel.org Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup@brainfault.org> [maz: amended commit message] Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20211105094748.3894453-1-guoren@kernel.org
2021-06-10irqchip: Bulk conversion to generic_handle_domain_irq()Marc Zyngier
Wherever possible, replace constructs that match either generic_handle_irq(irq_find_mapping()) or generic_handle_irq(irq_linear_revmap()) to a single call to generic_handle_domain_irq(). Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
2021-04-07irqchip/sifive-plic: Mark two global variables __ro_after_initJisheng Zhang
All of these two are never modified after init, so they can be __ro_after_init. Signed-off-by: Jisheng Zhang <jszhang@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210330020911.26423e9e@xhacker
2020-11-01irqchip/sifive-plic: Fix chip_data access within a hierarchyGreentime Hu
The plic driver crashes in plic_irq_unmask() when the interrupt is within a hierarchy, as it picks the top-level chip_data instead of its local one. Using irq_data_get_irq_chip_data() instead of irq_get_chip_data() solves the issue for good. Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs") Signed-off-by: Greentime Hu <greentime.hu@sifive.com> [maz: rewrote commit message] Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Atish Patra <atish.patra@wdc.com> Link: https://lore.kernel.org/r/20201029023738.127472-1-greentime.hu@sifive.com
2020-10-25irqchip/sifive-plic: Fix broken irq_set_affinity() callbackGreentime Hu
An interrupt submitted to an affinity change will always be left enabled after plic_set_affinity() has been called, while the expectation is that it should stay in whatever state it was before the call. Preserving the configuration fixes a PWM hang issue on the Unleashed board. [ 919.015783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks: [ 919.020922] rcu: 0-...0: (0 ticks this GP) idle=7d2/1/0x4000000000000002 softirq=1424/1424 fqs=105807 [ 919.030295] (detected by 1, t=225825 jiffies, g=1561, q=3496) [ 919.036109] Task dump for CPU 0: [ 919.039321] kworker/0:1 R running task 0 30 2 0x00000008 [ 919.046359] Workqueue: events set_brightness_delayed [ 919.051302] Call Trace: [ 919.053738] [<ffffffe000930d92>] __schedule+0x194/0x4de [ 982.035783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks: [ 982.040923] rcu: 0-...0: (0 ticks this GP) idle=7d2/1/0x4000000000000002 softirq=1424/1424 fqs=113325 [ 982.050294] (detected by 1, t=241580 jiffies, g=1561, q=3509) [ 982.056108] Task dump for CPU 0: [ 982.059321] kworker/0:1 R running task 0 30 2 0x00000008 [ 982.066359] Workqueue: events set_brightness_delayed [ 982.071302] Call Trace: [ 982.073739] [<ffffffe000930d92>] __schedule+0x194/0x4de [..] Fixes: bb0fed1c60cc ("irqchip/sifive-plic: Switch to fasteoi flow") Signed-off-by: Greentime Hu <greentime.hu@sifive.com> [maz: tidy-up commit message] Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20201020081532.2377-1-greentime.hu@sifive.com
2020-06-09irqchip: RISC-V per-HART local interrupt controller driverAnup Patel
The RISC-V per-HART local interrupt controller manages software interrupts, timer interrupts, external interrupts (which are routed via the platform level interrupt controller) and other per-HART local interrupts. We add a driver for the RISC-V local interrupt controller, which eventually replaces the RISC-V architecture code, allowing for a better split between arch code and drivers. The driver is compliant with RISC-V Hart-Level Interrupt Controller DT bindings located at: Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt Co-developed-by: Palmer Dabbelt <palmer@dabbelt.com> Signed-off-by: Anup Patel <anup.patel@wdc.com> [Palmer: Cleaned up warnings] Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
2020-06-09RISC-V: Rename and move plic_find_hart_id() to arch directoryAnup Patel
The plic_find_hart_id() can be useful to other interrupt controller drivers (such as RISC-V local interrupt driver) so we rename this function to riscv_of_parent_hartid() and place it in arch directory along with riscv_of_processor_hartid(). Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Acked-by: Palmer Dabbelt <palmerdabbelt@google.com> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com> Reviewed-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
2020-05-25irqchip/sifive-plic: Improve boot prints for multiple PLIC instancesAnup Patel
We improve PLIC banner to help distinguish multiple PLIC instances in boot time prints. Signed-off-by: Anup Patel <anup.patel@wdc.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Acked-by: Palmer Dabbelt <palmerdabbelt@google.com> Link: https://lore.kernel.org/r/20200518091441.94843-4-anup.patel@wdc.com
2020-05-25irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is presentAnup Patel
For multiple PLIC instances, the plic_init() is called once for each PLIC instance. Due to this we have two issues: 1. cpuhp_setup_state() is called multiple times 2. plic_starting_cpu() can crash for boot CPU if cpuhp_setup_state() is called before boot CPU PLIC handler is available. Address both issues by only initializing the HP notifiers when the boot CPU setup is complete. Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs") Signed-off-by: Anup Patel <anup.patel@wdc.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Acked-by: Palmer Dabbelt <palmerdabbelt@google.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200518091441.94843-3-anup.patel@wdc.com
2020-05-25irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()Anup Patel
For multiple PLIC instances, each PLIC can only target a subset of CPUs which is represented by "lmask" in the "struct plic_priv". Currently, the default irq affinity for each PLIC interrupt is all online CPUs which is illegal value for default irq affinity when we have multiple PLIC instances. To fix this, we now set "lmask" as the default irq affinity in for each interrupt in plic_irqdomain_map(). Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs") Signed-off-by: Anup Patel <anup.patel@wdc.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Acked-by: Palmer Dabbelt <palmerdabbelt@google.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200518091441.94843-2-anup.patel@wdc.com
2020-05-18irqchip/sifive-plic: Remove incorrect requirement about number of irq contextsWesley W. Terpstra
A PLIC may not be connected to all the cores. In that case, nr_contexts may be less than num_possible_cpus. This requirement is only valid a single PLIC is the only interrupt controller for the whole system. Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: "Wesley W. Terpstra" <wesley@sifive.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Acked-by: Palmer Dabbelt <palmerdabbelt@google.com> Link: https://lore.kernel.org/r/20200512172636.96299-1-atish.patra@wdc.com [Atish: Modified the commit text]
2020-04-17irqchip/sifive-plic: Fix maximum priority threshold valueAtish Patra
As per the PLIC specification, maximum priority threshold value is 0x7 not 0xF. Even though it doesn't cause any error in qemu/hifive unleashed, there may be some implementation which checks the upper bound resulting in an illegal access. Fixes: ccbe80bad571 ("irqchip/sifive-plic: Enable/Disable external interrupts upon cpu online/offline") Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20200403014609.71831-1-atish.patra@wdc.com
2020-03-16irqchip/sifive-plic: Add support for multiple PLICsAtish Patra
Current, PLIC driver can support only 1 PLIC on the board. However, there can be multiple PLICs present on a two socket systems in RISC-V. Modify the driver so that each PLIC handler can have a information about individual PLIC registers and an irqdomain associated with it. Tested on two socket RISC-V system based on VCU118 FPGA connected via OmniXtend protocol. Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20200302231146.15530-3-atish.patra@wdc.com
2020-03-16irqchip/sifive-plic: Enable/Disable external interrupts upon cpu online/offlineAtish Patra
Currently, PLIC threshold is only initialized once in the beginning. However, threshold can be set to disabled if a CPU is marked offline with CPU hotplug feature. This will not allow to change the irq affinity to a CPU that just came online. Add PLIC specific CPU hotplug callbacks and enable the threshold when a CPU comes online. Take this opportunity to move the external interrupt enable code from trap init to PLIC driver as well. On cpu offline path, the driver performs the exact opposite operations i.e. disable the interrupt and the threshold. Signed-off-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20200302231146.15530-2-atish.patra@wdc.com
2020-01-24Merge tag 'irqchip-5.6' of ↵Thomas Gleixner
git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/core Pull irqchip updates from Marc Zyngier: - Conversion of the SiFive PLIC to hierarchical domains - New SiFive GPIO irqchip driver - New Aspeed SCI irqchip driver - New NXP INTMUX irqchip driver - Additional support for the Meson A1 GPIO irqchip - First part of the GICv4.1 support - Assorted fixes
2020-01-20irqchip/sifive-plic: Support irq domain hierarchyYash Shah
Add support for hierarchical irq domains. This is needed as pre-requisite for gpio-sifive driver. Signed-off-by: Yash Shah <yash.shah@sifive.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/1575976274-13487-4-git-send-email-yash.shah@sifive.com
2020-01-04riscv: prefix IRQ_ macro names with an RV_ namespacePaul Walmsley
"IRQ_TIMER", used in the arch/riscv CSR header file, is a sufficiently generic macro name that it's used by several source files across the Linux code base. Some of these other files ultimately include the arch/riscv CSR include file, causing collisions. Fix by prefixing the RISC-V csr.h IRQ_ macro names with an RV_ prefix. Fixes: a4c3733d32a72 ("riscv: abstract out CSR names for supervisor vs machine mode") Reported-by: Olof Johansson <olof@lixom.net> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
2019-11-05riscv: abstract out CSR names for supervisor vs machine modeChristoph Hellwig
Many of the privileged CSRs exist in a supervisor and machine version that are used very similarly. Provide versions of the CSR names and fields that map to either the S-mode or M-mode variant depending on a new CONFIG_RISCV_M_MODE kconfig symbol. Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com> and Paul Walmsley <paul.walmsley@sifive.com>. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Thomas Gleixner <tglx@linutronix.de> # for drivers/clocksource, drivers/irqchip [paul.walmsley@sifive.com: updated to apply] Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
2019-10-25Merge tag 'irqchip-fixes-5.4-2' of ↵Thomas Gleixner
git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Pull the second lot of irqchip updates for 5.4 from Marc Zyngier: - Sifive PLIC: force driver to skip non-relevant contexts - GICv4: Don't send VMOVP commands to ITSs that don't have this vPE mapped
2019-10-25irqchip/sifive-plic: Skip contexts except supervisor in plic_init()Alan Mikhak
Modify plic_init() to skip .dts interrupt contexts other than supervisor external interrupt. The .dts entry for plic may specify multiple interrupt contexts. For example, it may assign two entries IRQ_M_EXT and IRQ_S_EXT, in that order, to the same interrupt controller. This patch modifies plic_init() to skip the IRQ_M_EXT context since IRQ_S_EXT is currently the only supported context. If IRQ_M_EXT is not skipped, plic_init() will report "handler already present for context" when it comes across the IRQ_S_EXT context in the next iteration of its loop. Without this patch, .dts would have to be edited to replace the value of IRQ_M_EXT with -1 for it to be skipped. Signed-off-by: Alan Mikhak <alan.mikhak@sifive.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Paul Walmsley <paul.walmsley@sifive.com> # arch/riscv Link: https://lkml.kernel.org/r/1571933503-21504-1-git-send-email-alan.mikhak@sifive.com
2019-10-14Merge tag 'irqchip-fixes-5.4-1' of ↵Thomas Gleixner
git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Pull irqchip fixes from Marc Zyngier: - Add retrigger support to Amazon's al-fic driver - Add SAM9X60 support to Atmel's AIC5 irqchip - Fix GICv3 maximum interrupt calculation - Convert SiFive's PLIC to the fasteoi IRQ flow
2019-09-18irqchip/sifive-plic: Switch to fasteoi flowMarc Zyngier
The SiFive PLIC interrupt controller seems to have all the HW features to support the fasteoi flow, but the driver seems to be stuck in a distant past. Bring it into the 21st century. Signed-off-by: Marc Zyngier <maz@kernel.org> Tested-by: Palmer Dabbelt <palmer@sifive.com> (QEMU Boot) Tested-by: Darius Rad <darius@bluespec.com> (on 2 HW PLIC implementations) Tested-by: Paul Walmsley <paul.walmsley@sifive.com> (HiFive Unleashed) Reviewed-by: Palmer Dabbelt <palmer@sifive.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/8636gxskmj.wl-maz@kernel.org