mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-20 04:44:26 +08:00
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "A rather small set of irq updates this time: - removal of the old and now obsolete irq domain debugging code - the new Goldfish PIC driver - the usual pile of small fixes and updates" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqdomain: Kill CONFIG_IRQ_DOMAIN_DEBUG irq/work: Improve the flag definitions irqchip/gic-v3: Fix the driver probe() fail due to disabled GICC entry irqchip/irq-goldfish-pic: Add Goldfish PIC driver dt-bindings/goldfish-pic: Add device tree binding for Goldfish PIC driver irqchip/ompic: fix return value check in ompic_of_init() dt-bindings/bcm283x: Define polarity of per-cpu interrupts irqchip/irq-bcm2836: Add support for DT interrupt polarity dt-bindings/bcm2836-l1-intc: Add interrupt polarity support
This commit is contained in:
commit
7bcd342594
@ -265,37 +265,5 @@ support other architectures, such as ARM, ARM64 etc.
|
|||||||
|
|
||||||
=== Debugging ===
|
=== Debugging ===
|
||||||
|
|
||||||
If you switch on CONFIG_IRQ_DOMAIN_DEBUG (which depends on
|
Most of the internals of the IRQ subsystem are exposed in debugfs by
|
||||||
CONFIG_IRQ_DOMAIN and CONFIG_DEBUG_FS), you will find a new file in
|
turning CONFIG_GENERIC_IRQ_DEBUGFS on.
|
||||||
your debugfs mount point, called irq_domain_mapping. This file
|
|
||||||
contains a live snapshot of all the IRQ domains in the system:
|
|
||||||
|
|
||||||
name mapped linear-max direct-max devtree-node
|
|
||||||
pl061 8 8 0 /smb/gpio@e0080000
|
|
||||||
pl061 8 8 0 /smb/gpio@e1050000
|
|
||||||
pMSI 0 0 0 /interrupt-controller@e1101000/v2m@e0080000
|
|
||||||
MSI 37 0 0 /interrupt-controller@e1101000/v2m@e0080000
|
|
||||||
GICv2m 37 0 0 /interrupt-controller@e1101000/v2m@e0080000
|
|
||||||
GICv2 448 448 0 /interrupt-controller@e1101000
|
|
||||||
|
|
||||||
it also iterates over the interrupts to display their mapping in the
|
|
||||||
domains, and makes the domain stacking visible:
|
|
||||||
|
|
||||||
|
|
||||||
irq hwirq chip name chip data active type domain
|
|
||||||
1 0x00019 GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
|
||||||
2 0x0001d GICv2 0xffff00000916bfd8 LINEAR GICv2
|
|
||||||
3 0x0001e GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
|
||||||
4 0x0001b GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
|
||||||
5 0x0001a GICv2 0xffff00000916bfd8 LINEAR GICv2
|
|
||||||
[...]
|
|
||||||
96 0x81808 MSI 0x (null) RADIX MSI
|
|
||||||
96+ 0x00063 GICv2m 0xffff8003ee116980 RADIX GICv2m
|
|
||||||
96+ 0x00063 GICv2 0xffff00000916bfd8 LINEAR GICv2
|
|
||||||
97 0x08800 MSI 0x (null) * RADIX MSI
|
|
||||||
97+ 0x00064 GICv2m 0xffff8003ee116980 * RADIX GICv2m
|
|
||||||
97+ 0x00064 GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
|
||||||
|
|
||||||
Here, interrupts 1-5 are only using a single domain, while 96 and 97
|
|
||||||
are build out of a stack of three domain, each level performing a
|
|
||||||
particular function.
|
|
||||||
|
@ -12,7 +12,7 @@ Required properties:
|
|||||||
registers
|
registers
|
||||||
- interrupt-controller: Identifies the node as an interrupt controller
|
- interrupt-controller: Identifies the node as an interrupt controller
|
||||||
- #interrupt-cells: Specifies the number of cells needed to encode an
|
- #interrupt-cells: Specifies the number of cells needed to encode an
|
||||||
interrupt source. The value shall be 1
|
interrupt source. The value shall be 2
|
||||||
|
|
||||||
Please refer to interrupts.txt in this directory for details of the common
|
Please refer to interrupts.txt in this directory for details of the common
|
||||||
Interrupt Controllers bindings used by client devices.
|
Interrupt Controllers bindings used by client devices.
|
||||||
@ -32,6 +32,6 @@ local_intc: local_intc {
|
|||||||
compatible = "brcm,bcm2836-l1-intc";
|
compatible = "brcm,bcm2836-l1-intc";
|
||||||
reg = <0x40000000 0x100>;
|
reg = <0x40000000 0x100>;
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <2>;
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
Android Goldfish PIC
|
||||||
|
|
||||||
|
Android Goldfish programmable interrupt device used by Android
|
||||||
|
emulator.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : should contain "google,goldfish-pic"
|
||||||
|
- reg : <registers mapping>
|
||||||
|
- interrupts : <interrupt mapping>
|
||||||
|
|
||||||
|
Example for mips when used in cascade mode:
|
||||||
|
|
||||||
|
cpuintc {
|
||||||
|
#interrupt-cells = <0x1>;
|
||||||
|
#address-cells = <0>;
|
||||||
|
interrupt-controller;
|
||||||
|
compatible = "mti,cpu-interrupt-controller";
|
||||||
|
};
|
||||||
|
|
||||||
|
interrupt-controller@1f000000 {
|
||||||
|
compatible = "google,goldfish-pic";
|
||||||
|
reg = <0x1f000000 0x1000>;
|
||||||
|
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <0x1>;
|
||||||
|
|
||||||
|
interrupt-parent = <&cpuintc>;
|
||||||
|
interrupts = <0x2>;
|
||||||
|
};
|
@ -875,6 +875,12 @@ S: Supported
|
|||||||
F: drivers/android/
|
F: drivers/android/
|
||||||
F: drivers/staging/android/
|
F: drivers/staging/android/
|
||||||
|
|
||||||
|
ANDROID GOLDFISH PIC DRIVER
|
||||||
|
M: Miodrag Dinic <miodrag.dinic@mips.com>
|
||||||
|
S: Supported
|
||||||
|
F: Documentation/devicetree/bindings/interrupt-controller/google,goldfish-pic.txt
|
||||||
|
F: drivers/irqchip/irq-goldfish-pic.c
|
||||||
|
|
||||||
ANDROID GOLDFISH RTC DRIVER
|
ANDROID GOLDFISH RTC DRIVER
|
||||||
M: Miodrag Dinic <miodrag.dinic@mips.com>
|
M: Miodrag Dinic <miodrag.dinic@mips.com>
|
||||||
S: Supported
|
S: Supported
|
||||||
|
@ -13,24 +13,24 @@
|
|||||||
compatible = "brcm,bcm2836-l1-intc";
|
compatible = "brcm,bcm2836-l1-intc";
|
||||||
reg = <0x40000000 0x100>;
|
reg = <0x40000000 0x100>;
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <2>;
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
};
|
};
|
||||||
|
|
||||||
arm-pmu {
|
arm-pmu {
|
||||||
compatible = "arm,cortex-a7-pmu";
|
compatible = "arm,cortex-a7-pmu";
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
interrupts = <9>;
|
interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
timer {
|
timer {
|
||||||
compatible = "arm,armv7-timer";
|
compatible = "arm,armv7-timer";
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
interrupts = <0>, // PHYS_SECURE_PPI
|
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, // PHYS_SECURE_PPI
|
||||||
<1>, // PHYS_NONSECURE_PPI
|
<1 IRQ_TYPE_LEVEL_HIGH>, // PHYS_NONSECURE_PPI
|
||||||
<3>, // VIRT_PPI
|
<3 IRQ_TYPE_LEVEL_HIGH>, // VIRT_PPI
|
||||||
<2>; // HYP_PPI
|
<2 IRQ_TYPE_LEVEL_HIGH>; // HYP_PPI
|
||||||
always-on;
|
always-on;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,7 +76,7 @@
|
|||||||
compatible = "brcm,bcm2836-armctrl-ic";
|
compatible = "brcm,bcm2836-armctrl-ic";
|
||||||
reg = <0x7e00b200 0x200>;
|
reg = <0x7e00b200 0x200>;
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
interrupts = <8>;
|
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
||||||
&cpu_thermal {
|
&cpu_thermal {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
compatible = "brcm,bcm2836-l1-intc";
|
compatible = "brcm,bcm2836-l1-intc";
|
||||||
reg = <0x40000000 0x100>;
|
reg = <0x40000000 0x100>;
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <2>;
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -20,10 +20,10 @@
|
|||||||
timer {
|
timer {
|
||||||
compatible = "arm,armv7-timer";
|
compatible = "arm,armv7-timer";
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
interrupts = <0>, // PHYS_SECURE_PPI
|
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, // PHYS_SECURE_PPI
|
||||||
<1>, // PHYS_NONSECURE_PPI
|
<1 IRQ_TYPE_LEVEL_HIGH>, // PHYS_NONSECURE_PPI
|
||||||
<3>, // VIRT_PPI
|
<3 IRQ_TYPE_LEVEL_HIGH>, // VIRT_PPI
|
||||||
<2>; // HYP_PPI
|
<2 IRQ_TYPE_LEVEL_HIGH>; // HYP_PPI
|
||||||
always-on;
|
always-on;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,7 +73,7 @@
|
|||||||
compatible = "brcm,bcm2836-armctrl-ic";
|
compatible = "brcm,bcm2836-armctrl-ic";
|
||||||
reg = <0x7e00b200 0x200>;
|
reg = <0x7e00b200 0x200>;
|
||||||
interrupt-parent = <&local_intc>;
|
interrupt-parent = <&local_intc>;
|
||||||
interrupts = <8>;
|
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
||||||
&cpu_thermal {
|
&cpu_thermal {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <dt-bindings/clock/bcm2835.h>
|
#include <dt-bindings/clock/bcm2835.h>
|
||||||
#include <dt-bindings/clock/bcm2835-aux.h>
|
#include <dt-bindings/clock/bcm2835-aux.h>
|
||||||
#include <dt-bindings/gpio/gpio.h>
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
|
||||||
/* firmware-provided startup stubs live here, where the secondary CPUs are
|
/* firmware-provided startup stubs live here, where the secondary CPUs are
|
||||||
* spinning.
|
* spinning.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_KERNEL_XZ=y
|
CONFIG_KERNEL_XZ=y
|
||||||
# CONFIG_SWAP is not set
|
# CONFIG_SWAP is not set
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_LOG_BUF_SHIFT=14
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_KERNEL_XZ=y
|
CONFIG_KERNEL_XZ=y
|
||||||
# CONFIG_SWAP is not set
|
# CONFIG_SWAP is not set
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_LOG_BUF_SHIFT=14
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_CGROUPS=y
|
CONFIG_CGROUPS=y
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_LOG_BUF_SHIFT=14
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_BSD_PROCESS_ACCT=y
|
CONFIG_BSD_PROCESS_ACCT=y
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
# CONFIG_SWAP is not set
|
# CONFIG_SWAP is not set
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_LOG_BUF_SHIFT=14
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_IKCONFIG=y
|
CONFIG_IKCONFIG=y
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
|
@ -71,7 +71,6 @@ CONFIG_IP_ROUTE_MULTIPATH=y
|
|||||||
CONFIG_IP_ROUTE_VERBOSE=y
|
CONFIG_IP_ROUTE_VERBOSE=y
|
||||||
CONFIG_IP_SCTP=m
|
CONFIG_IP_SCTP=m
|
||||||
CONFIG_IPV6=y
|
CONFIG_IPV6=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_ISO9660_FS=m
|
CONFIG_ISO9660_FS=m
|
||||||
CONFIG_JFFS2_FS_DEBUG=1
|
CONFIG_JFFS2_FS_DEBUG=1
|
||||||
CONFIG_JFFS2_FS=y
|
CONFIG_JFFS2_FS=y
|
||||||
|
@ -4,7 +4,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_AUDIT=y
|
CONFIG_AUDIT=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_TASKSTATS=y
|
CONFIG_TASKSTATS=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_PPC64=y
|
CONFIG_PPC64=y
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_TASKSTATS=y
|
CONFIG_TASKSTATS=y
|
||||||
|
@ -3,7 +3,6 @@ CONFIG_NR_CPUS=2048
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_AUDIT=y
|
CONFIG_AUDIT=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_TASKSTATS=y
|
CONFIG_TASKSTATS=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_USELIB=y
|
CONFIG_USELIB=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
CONFIG_FHANDLE=y
|
CONFIG_FHANDLE=y
|
||||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||||
|
@ -343,4 +343,12 @@ config MESON_IRQ_GPIO
|
|||||||
help
|
help
|
||||||
Support Meson SoC Family GPIO Interrupt Multiplexer
|
Support Meson SoC Family GPIO Interrupt Multiplexer
|
||||||
|
|
||||||
|
config GOLDFISH_PIC
|
||||||
|
bool "Goldfish programmable interrupt controller"
|
||||||
|
depends on MIPS && (GOLDFISH || COMPILE_TEST)
|
||||||
|
select IRQ_DOMAIN
|
||||||
|
help
|
||||||
|
Say yes here to enable Goldfish interrupt controller driver used
|
||||||
|
for Goldfish based virtual platforms.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -84,3 +84,4 @@ obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o
|
|||||||
obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o
|
obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o
|
||||||
obj-$(CONFIG_ARCH_SYNQUACER) += irq-sni-exiu.o
|
obj-$(CONFIG_ARCH_SYNQUACER) += irq-sni-exiu.o
|
||||||
obj-$(CONFIG_MESON_IRQ_GPIO) += irq-meson-gpio.o
|
obj-$(CONFIG_MESON_IRQ_GPIO) += irq-meson-gpio.o
|
||||||
|
obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o
|
||||||
|
@ -98,13 +98,35 @@ static struct irq_chip bcm2836_arm_irqchip_gpu = {
|
|||||||
.irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq,
|
.irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bcm2836_arm_irqchip_register_irq(int hwirq, struct irq_chip *chip)
|
static int bcm2836_map(struct irq_domain *d, unsigned int irq,
|
||||||
|
irq_hw_number_t hw)
|
||||||
{
|
{
|
||||||
int irq = irq_create_mapping(intc.domain, hwirq);
|
struct irq_chip *chip;
|
||||||
|
|
||||||
|
switch (hw) {
|
||||||
|
case LOCAL_IRQ_CNTPSIRQ:
|
||||||
|
case LOCAL_IRQ_CNTPNSIRQ:
|
||||||
|
case LOCAL_IRQ_CNTHPIRQ:
|
||||||
|
case LOCAL_IRQ_CNTVIRQ:
|
||||||
|
chip = &bcm2836_arm_irqchip_timer;
|
||||||
|
break;
|
||||||
|
case LOCAL_IRQ_GPU_FAST:
|
||||||
|
chip = &bcm2836_arm_irqchip_gpu;
|
||||||
|
break;
|
||||||
|
case LOCAL_IRQ_PMU_FAST:
|
||||||
|
chip = &bcm2836_arm_irqchip_pmu;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_warn_once("Unexpected hw irq: %lu\n", hw);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
irq_set_percpu_devid(irq);
|
irq_set_percpu_devid(irq);
|
||||||
irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq);
|
irq_domain_set_info(d, irq, hw, chip, d->host_data,
|
||||||
|
handle_percpu_devid_irq, NULL, NULL);
|
||||||
irq_set_status_flags(irq, IRQ_NOAUTOEN);
|
irq_set_status_flags(irq, IRQ_NOAUTOEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -165,7 +187,8 @@ static int bcm2836_cpu_dying(unsigned int cpu)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
|
static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
|
||||||
.xlate = irq_domain_xlate_onecell
|
.xlate = irq_domain_xlate_onetwocell,
|
||||||
|
.map = bcm2836_map,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -218,19 +241,6 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
|
|||||||
if (!intc.domain)
|
if (!intc.domain)
|
||||||
panic("%pOF: unable to create IRQ domain\n", node);
|
panic("%pOF: unable to create IRQ domain\n", node);
|
||||||
|
|
||||||
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPSIRQ,
|
|
||||||
&bcm2836_arm_irqchip_timer);
|
|
||||||
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPNSIRQ,
|
|
||||||
&bcm2836_arm_irqchip_timer);
|
|
||||||
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTHPIRQ,
|
|
||||||
&bcm2836_arm_irqchip_timer);
|
|
||||||
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTVIRQ,
|
|
||||||
&bcm2836_arm_irqchip_timer);
|
|
||||||
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_GPU_FAST,
|
|
||||||
&bcm2836_arm_irqchip_gpu);
|
|
||||||
bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_PMU_FAST,
|
|
||||||
&bcm2836_arm_irqchip_pmu);
|
|
||||||
|
|
||||||
bcm2836_arm_irqchip_smp_init();
|
bcm2836_arm_irqchip_smp_init();
|
||||||
|
|
||||||
set_handle_irq(bcm2836_arm_irqchip_handle_irq);
|
set_handle_irq(bcm2836_arm_irqchip_handle_irq);
|
||||||
|
@ -1331,6 +1331,10 @@ gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
|
|||||||
u32 size = reg == GIC_PIDR2_ARCH_GICv4 ? SZ_64K * 4 : SZ_64K * 2;
|
u32 size = reg == GIC_PIDR2_ARCH_GICv4 ? SZ_64K * 4 : SZ_64K * 2;
|
||||||
void __iomem *redist_base;
|
void __iomem *redist_base;
|
||||||
|
|
||||||
|
/* GICC entry which has !ACPI_MADT_ENABLED is not unusable so skip */
|
||||||
|
if (!(gicc->flags & ACPI_MADT_ENABLED))
|
||||||
|
return 0;
|
||||||
|
|
||||||
redist_base = ioremap(gicc->gicr_base_address, size);
|
redist_base = ioremap(gicc->gicr_base_address, size);
|
||||||
if (!redist_base)
|
if (!redist_base)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -1380,6 +1384,13 @@ static int __init gic_acpi_match_gicc(struct acpi_subtable_header *header,
|
|||||||
if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
|
if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's perfectly valid firmware can pass disabled GICC entry, driver
|
||||||
|
* should not treat as errors, skip the entry instead of probe fail.
|
||||||
|
*/
|
||||||
|
if (!(gicc->flags & ACPI_MADT_ENABLED))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
139
drivers/irqchip/irq-goldfish-pic.c
Normal file
139
drivers/irqchip/irq-goldfish-pic.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Driver for MIPS Goldfish Programmable Interrupt Controller.
|
||||||
|
*
|
||||||
|
* Author: Miodrag Dinic <miodrag.dinic@mips.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/irqchip.h>
|
||||||
|
#include <linux/irqchip/chained_irq.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
|
||||||
|
#define GFPIC_NR_IRQS 32
|
||||||
|
|
||||||
|
/* 8..39 Cascaded Goldfish PIC interrupts */
|
||||||
|
#define GFPIC_IRQ_BASE 8
|
||||||
|
|
||||||
|
#define GFPIC_REG_IRQ_PENDING 0x04
|
||||||
|
#define GFPIC_REG_IRQ_DISABLE_ALL 0x08
|
||||||
|
#define GFPIC_REG_IRQ_DISABLE 0x0c
|
||||||
|
#define GFPIC_REG_IRQ_ENABLE 0x10
|
||||||
|
|
||||||
|
struct goldfish_pic_data {
|
||||||
|
void __iomem *base;
|
||||||
|
struct irq_domain *irq_domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void goldfish_pic_cascade(struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
struct goldfish_pic_data *gfpic = irq_desc_get_handler_data(desc);
|
||||||
|
struct irq_chip *host_chip = irq_desc_get_chip(desc);
|
||||||
|
u32 pending, hwirq, virq;
|
||||||
|
|
||||||
|
chained_irq_enter(host_chip, desc);
|
||||||
|
|
||||||
|
pending = readl(gfpic->base + GFPIC_REG_IRQ_PENDING);
|
||||||
|
while (pending) {
|
||||||
|
hwirq = __fls(pending);
|
||||||
|
virq = irq_linear_revmap(gfpic->irq_domain, hwirq);
|
||||||
|
generic_handle_irq(virq);
|
||||||
|
pending &= ~(1 << hwirq);
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_irq_exit(host_chip, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct irq_domain_ops goldfish_irq_domain_ops = {
|
||||||
|
.xlate = irq_domain_xlate_onecell,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init goldfish_pic_of_init(struct device_node *of_node,
|
||||||
|
struct device_node *parent)
|
||||||
|
{
|
||||||
|
struct goldfish_pic_data *gfpic;
|
||||||
|
struct irq_chip_generic *gc;
|
||||||
|
struct irq_chip_type *ct;
|
||||||
|
unsigned int parent_irq;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
gfpic = kzalloc(sizeof(*gfpic), GFP_KERNEL);
|
||||||
|
if (!gfpic) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_irq = irq_of_parse_and_map(of_node, 0);
|
||||||
|
if (!parent_irq) {
|
||||||
|
pr_err("Failed to map parent IRQ!\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfpic->base = of_iomap(of_node, 0);
|
||||||
|
if (!gfpic->base) {
|
||||||
|
pr_err("Failed to map base address!\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_unmap_irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mask interrupts. */
|
||||||
|
writel(1, gfpic->base + GFPIC_REG_IRQ_DISABLE_ALL);
|
||||||
|
|
||||||
|
gc = irq_alloc_generic_chip("GFPIC", 1, GFPIC_IRQ_BASE, gfpic->base,
|
||||||
|
handle_level_irq);
|
||||||
|
if (!gc) {
|
||||||
|
pr_err("Failed to allocate chip structures!\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_iounmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ct = gc->chip_types;
|
||||||
|
ct->regs.enable = GFPIC_REG_IRQ_ENABLE;
|
||||||
|
ct->regs.disable = GFPIC_REG_IRQ_DISABLE;
|
||||||
|
ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
|
||||||
|
ct->chip.irq_mask = irq_gc_mask_disable_reg;
|
||||||
|
|
||||||
|
irq_setup_generic_chip(gc, IRQ_MSK(GFPIC_NR_IRQS), 0,
|
||||||
|
IRQ_NOPROBE | IRQ_LEVEL, 0);
|
||||||
|
|
||||||
|
gfpic->irq_domain = irq_domain_add_legacy(of_node, GFPIC_NR_IRQS,
|
||||||
|
GFPIC_IRQ_BASE, 0,
|
||||||
|
&goldfish_irq_domain_ops,
|
||||||
|
NULL);
|
||||||
|
if (!gfpic->irq_domain) {
|
||||||
|
pr_err("Failed to add irqdomain!\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_destroy_generic_chip;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq_set_chained_handler_and_data(parent_irq,
|
||||||
|
goldfish_pic_cascade, gfpic);
|
||||||
|
|
||||||
|
pr_info("Successfully registered.\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_destroy_generic_chip:
|
||||||
|
irq_destroy_generic_chip(gc, IRQ_MSK(GFPIC_NR_IRQS),
|
||||||
|
IRQ_NOPROBE | IRQ_LEVEL, 0);
|
||||||
|
out_iounmap:
|
||||||
|
iounmap(gfpic->base);
|
||||||
|
out_unmap_irq:
|
||||||
|
irq_dispose_mapping(parent_irq);
|
||||||
|
out_free:
|
||||||
|
kfree(gfpic);
|
||||||
|
out_err:
|
||||||
|
pr_err("Failed to initialize! (errno = %d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
IRQCHIP_DECLARE(google_gf_pic, "google,goldfish-pic", goldfish_pic_of_init);
|
@ -171,9 +171,9 @@ static int __init ompic_of_init(struct device_node *node,
|
|||||||
|
|
||||||
/* Setup the device */
|
/* Setup the device */
|
||||||
ompic_base = ioremap(res.start, resource_size(&res));
|
ompic_base = ioremap(res.start, resource_size(&res));
|
||||||
if (IS_ERR(ompic_base)) {
|
if (!ompic_base) {
|
||||||
pr_err("ompic: unable to map registers");
|
pr_err("ompic: unable to map registers");
|
||||||
return PTR_ERR(ompic_base);
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
irq = irq_of_parse_and_map(node, 0);
|
irq = irq_of_parse_and_map(node, 0);
|
||||||
|
@ -13,10 +13,13 @@
|
|||||||
* busy NULL, 2 -> {free, claimed} : callback in progress, can be claimed
|
* busy NULL, 2 -> {free, claimed} : callback in progress, can be claimed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define IRQ_WORK_PENDING 1UL
|
#define IRQ_WORK_PENDING BIT(0)
|
||||||
#define IRQ_WORK_BUSY 2UL
|
#define IRQ_WORK_BUSY BIT(1)
|
||||||
#define IRQ_WORK_FLAGS 3UL
|
|
||||||
#define IRQ_WORK_LAZY 4UL /* Doesn't want IPI, wait for tick */
|
/* Doesn't want IPI, wait for tick: */
|
||||||
|
#define IRQ_WORK_LAZY BIT(2)
|
||||||
|
|
||||||
|
#define IRQ_WORK_CLAIMED (IRQ_WORK_PENDING | IRQ_WORK_BUSY)
|
||||||
|
|
||||||
struct irq_work {
|
struct irq_work {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -103,16 +103,6 @@ config GENERIC_IRQ_MATRIX_ALLOCATOR
|
|||||||
config GENERIC_IRQ_RESERVATION_MODE
|
config GENERIC_IRQ_RESERVATION_MODE
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config IRQ_DOMAIN_DEBUG
|
|
||||||
bool "Expose hardware/virtual IRQ mapping via debugfs"
|
|
||||||
depends on IRQ_DOMAIN && DEBUG_FS
|
|
||||||
help
|
|
||||||
This option will show the mapping relationship between hardware irq
|
|
||||||
numbers and Linux irq numbers. The mapping is exposed via debugfs
|
|
||||||
in the file "irq_domain_mapping".
|
|
||||||
|
|
||||||
If you don't know what this means you don't need it.
|
|
||||||
|
|
||||||
# Support forced irq threading
|
# Support forced irq threading
|
||||||
config IRQ_FORCED_THREADING
|
config IRQ_FORCED_THREADING
|
||||||
bool
|
bool
|
||||||
|
@ -897,124 +897,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_find_mapping);
|
EXPORT_SYMBOL_GPL(irq_find_mapping);
|
||||||
|
|
||||||
#ifdef CONFIG_IRQ_DOMAIN_DEBUG
|
|
||||||
static void virq_debug_show_one(struct seq_file *m, struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
struct irq_domain *domain;
|
|
||||||
struct irq_data *data;
|
|
||||||
|
|
||||||
domain = desc->irq_data.domain;
|
|
||||||
data = &desc->irq_data;
|
|
||||||
|
|
||||||
while (domain) {
|
|
||||||
unsigned int irq = data->irq;
|
|
||||||
unsigned long hwirq = data->hwirq;
|
|
||||||
struct irq_chip *chip;
|
|
||||||
bool direct;
|
|
||||||
|
|
||||||
if (data == &desc->irq_data)
|
|
||||||
seq_printf(m, "%5d ", irq);
|
|
||||||
else
|
|
||||||
seq_printf(m, "%5d+ ", irq);
|
|
||||||
seq_printf(m, "0x%05lx ", hwirq);
|
|
||||||
|
|
||||||
chip = irq_data_get_irq_chip(data);
|
|
||||||
seq_printf(m, "%-15s ", (chip && chip->name) ? chip->name : "none");
|
|
||||||
|
|
||||||
seq_printf(m, "0x%p ", irq_data_get_irq_chip_data(data));
|
|
||||||
|
|
||||||
seq_printf(m, " %c ", (desc->action && desc->action->handler) ? '*' : ' ');
|
|
||||||
direct = (irq == hwirq) && (irq < domain->revmap_direct_max_irq);
|
|
||||||
seq_printf(m, "%6s%-8s ",
|
|
||||||
(hwirq < domain->revmap_size) ? "LINEAR" : "RADIX",
|
|
||||||
direct ? "(DIRECT)" : "");
|
|
||||||
seq_printf(m, "%s\n", domain->name);
|
|
||||||
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
|
|
||||||
domain = domain->parent;
|
|
||||||
data = data->parent_data;
|
|
||||||
#else
|
|
||||||
domain = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int virq_debug_show(struct seq_file *m, void *private)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
struct irq_desc *desc;
|
|
||||||
struct irq_domain *domain;
|
|
||||||
struct radix_tree_iter iter;
|
|
||||||
void __rcu **slot;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
seq_printf(m, " %-16s %-6s %-10s %-10s %s\n",
|
|
||||||
"name", "mapped", "linear-max", "direct-max", "devtree-node");
|
|
||||||
mutex_lock(&irq_domain_mutex);
|
|
||||||
list_for_each_entry(domain, &irq_domain_list, link) {
|
|
||||||
struct device_node *of_node;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
of_node = irq_domain_get_of_node(domain);
|
|
||||||
if (of_node)
|
|
||||||
name = of_node_full_name(of_node);
|
|
||||||
else if (is_fwnode_irqchip(domain->fwnode))
|
|
||||||
name = container_of(domain->fwnode, struct irqchip_fwid,
|
|
||||||
fwnode)->name;
|
|
||||||
else
|
|
||||||
name = "";
|
|
||||||
|
|
||||||
radix_tree_for_each_slot(slot, &domain->revmap_tree, &iter, 0)
|
|
||||||
count++;
|
|
||||||
seq_printf(m, "%c%-16s %6u %10u %10u %s\n",
|
|
||||||
domain == irq_default_domain ? '*' : ' ', domain->name,
|
|
||||||
domain->revmap_size + count, domain->revmap_size,
|
|
||||||
domain->revmap_direct_max_irq,
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
mutex_unlock(&irq_domain_mutex);
|
|
||||||
|
|
||||||
seq_printf(m, "%-5s %-7s %-15s %-*s %6s %-14s %s\n", "irq", "hwirq",
|
|
||||||
"chip name", (int)(2 * sizeof(void *) + 2), "chip data",
|
|
||||||
"active", "type", "domain");
|
|
||||||
|
|
||||||
for (i = 1; i < nr_irqs; i++) {
|
|
||||||
desc = irq_to_desc(i);
|
|
||||||
if (!desc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
|
||||||
virq_debug_show_one(m, desc);
|
|
||||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int virq_debug_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, virq_debug_show, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations virq_debug_fops = {
|
|
||||||
.open = virq_debug_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init irq_debugfs_init(void)
|
|
||||||
{
|
|
||||||
if (debugfs_create_file("irq_domain_mapping", S_IRUGO, NULL,
|
|
||||||
NULL, &virq_debug_fops) == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__initcall(irq_debugfs_init);
|
|
||||||
#endif /* CONFIG_IRQ_DOMAIN_DEBUG */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
|
* irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
|
||||||
*
|
*
|
||||||
|
@ -36,7 +36,7 @@ static bool irq_work_claim(struct irq_work *work)
|
|||||||
*/
|
*/
|
||||||
flags = work->flags & ~IRQ_WORK_PENDING;
|
flags = work->flags & ~IRQ_WORK_PENDING;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nflags = flags | IRQ_WORK_FLAGS;
|
nflags = flags | IRQ_WORK_CLAIMED;
|
||||||
oflags = cmpxchg(&work->flags, flags, nflags);
|
oflags = cmpxchg(&work->flags, flags, nflags);
|
||||||
if (oflags == flags)
|
if (oflags == flags)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user