Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
468a903c
Commit
468a903c
authored
Sep 14, 2014
by
Jason Cooper
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'irqchip/handle_domain' into irqchip/core
parents
ce92bfe8
087fe000
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
116 additions
and
130 deletions
+116
-130
arch/arm/Kconfig
arch/arm/Kconfig
+1
-0
arch/arm/kernel/irq.c
arch/arm/kernel/irq.c
+1
-18
arch/arm/mach-imx/avic.c
arch/arm/mach-imx/avic.c
+1
-1
arch/arm/mach-imx/tzic.c
arch/arm/mach-imx/tzic.c
+1
-2
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/irq.c
+1
-2
arch/arm64/Kconfig
arch/arm64/Kconfig
+1
-0
arch/arm64/include/asm/hardirq.h
arch/arm64/include/asm/hardirq.h
+0
-2
arch/arm64/kernel/irq.c
arch/arm64/kernel/irq.c
+0
-27
arch/openrisc/Kconfig
arch/openrisc/Kconfig
+1
-0
arch/openrisc/include/asm/irq.h
arch/openrisc/include/asm/irq.h
+0
-1
arch/openrisc/kernel/irq.c
arch/openrisc/kernel/irq.c
+0
-12
drivers/irqchip/irq-armada-370-xp.c
drivers/irqchip/irq-armada-370-xp.c
+10
-9
drivers/irqchip/irq-atmel-aic.c
drivers/irqchip/irq-atmel-aic.c
+1
-3
drivers/irqchip/irq-atmel-aic5.c
drivers/irqchip/irq-atmel-aic5.c
+1
-3
drivers/irqchip/irq-clps711x.c
drivers/irqchip/irq-clps711x.c
+7
-11
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic-v3.c
+6
-7
drivers/irqchip/irq-gic.c
drivers/irqchip/irq-gic.c
+1
-2
drivers/irqchip/irq-mmp.c
drivers/irqchip/irq-mmp.c
+4
-6
drivers/irqchip/irq-mxs.c
drivers/irqchip/irq-mxs.c
+1
-2
drivers/irqchip/irq-or1k-pic.c
drivers/irqchip/irq-or1k-pic.c
+2
-2
drivers/irqchip/irq-orion.c
drivers/irqchip/irq-orion.c
+2
-3
drivers/irqchip/irq-s3c24xx.c
drivers/irqchip/irq-s3c24xx.c
+1
-3
drivers/irqchip/irq-sirfsoc.c
drivers/irqchip/irq-sirfsoc.c
+2
-4
drivers/irqchip/irq-sun4i.c
drivers/irqchip/irq-sun4i.c
+2
-3
drivers/irqchip/irq-versatile-fpga.c
drivers/irqchip/irq-versatile-fpga.c
+1
-1
drivers/irqchip/irq-vic.c
drivers/irqchip/irq-vic.c
+1
-1
drivers/irqchip/irq-vt8500.c
drivers/irqchip/irq-vt8500.c
+2
-3
drivers/irqchip/irq-zevio.c
drivers/irqchip/irq-zevio.c
+1
-2
include/linux/irqdesc.h
include/linux/irqdesc.h
+19
-0
kernel/irq/Kconfig
kernel/irq/Kconfig
+3
-0
kernel/irq/irqdesc.c
kernel/irq/irqdesc.c
+42
-0
No files found.
arch/arm/Kconfig
View file @
468a903c
...
...
@@ -24,6 +24,7 @@ config ARM
select GENERIC_SMP_IDLE_THREAD
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
...
...
arch/arm/kernel/irq.c
View file @
468a903c
...
...
@@ -65,24 +65,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
*/
void
handle_IRQ
(
unsigned
int
irq
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
old_regs
=
set_irq_regs
(
regs
);
irq_enter
();
/*
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
*/
if
(
unlikely
(
irq
>=
nr_irqs
))
{
if
(
printk_ratelimit
())
printk
(
KERN_WARNING
"Bad IRQ%u
\n
"
,
irq
);
ack_bad_irq
(
irq
);
}
else
{
generic_handle_irq
(
irq
);
}
irq_exit
();
set_irq_regs
(
old_regs
);
__handle_domain_irq
(
NULL
,
irq
,
false
,
regs
);
}
/*
...
...
arch/arm/mach-imx/avic.c
View file @
468a903c
...
...
@@ -144,7 +144,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
if
(
nivector
==
0xffff
)
break
;
handle_
IRQ
(
irq_find_mapping
(
domain
,
nivector
)
,
regs
);
handle_
domain_irq
(
domain
,
nivector
,
regs
);
}
while
(
1
);
}
...
...
arch/arm/mach-imx/tzic.c
View file @
468a903c
...
...
@@ -141,8 +141,7 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
while
(
stat
)
{
handled
=
1
;
irqofs
=
fls
(
stat
)
-
1
;
handle_IRQ
(
irq_find_mapping
(
domain
,
irqofs
+
i
*
32
),
regs
);
handle_domain_irq
(
domain
,
irqofs
+
i
*
32
,
regs
);
stat
&=
~
(
1
<<
irqofs
);
}
}
...
...
arch/arm/mach-omap2/irq.c
View file @
468a903c
...
...
@@ -248,8 +248,7 @@ static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs
irqnr
&=
ACTIVEIRQ_MASK
;
if
(
irqnr
)
{
irqnr
=
irq_find_mapping
(
domain
,
irqnr
);
handle_IRQ
(
irqnr
,
regs
);
handle_domain_irq
(
domain
,
irqnr
,
regs
);
handled_irq
=
1
;
}
}
while
(
irqnr
);
...
...
arch/arm64/Kconfig
View file @
468a903c
...
...
@@ -30,6 +30,7 @@ config ARM64
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
...
...
arch/arm64/include/asm/hardirq.h
View file @
468a903c
...
...
@@ -47,8 +47,6 @@ static inline void ack_bad_irq(unsigned int irq)
irq_err_count
++
;
}
extern
void
handle_IRQ
(
unsigned
int
,
struct
pt_regs
*
);
/*
* No arch-specific IRQ flags.
*/
...
...
arch/arm64/kernel/irq.c
View file @
468a903c
...
...
@@ -40,33 +40,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
return
0
;
}
/*
* handle_IRQ handles all hardware IRQ's. Decoded IRQs should
* not come via this function. Instead, they should provide their
* own 'handler'. Used by platform code implementing C-based 1st
* level decoding.
*/
void
handle_IRQ
(
unsigned
int
irq
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
old_regs
=
set_irq_regs
(
regs
);
irq_enter
();
/*
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
*/
if
(
unlikely
(
irq
>=
nr_irqs
))
{
pr_warn_ratelimited
(
"Bad IRQ%u
\n
"
,
irq
);
ack_bad_irq
(
irq
);
}
else
{
generic_handle_irq
(
irq
);
}
irq_exit
();
set_irq_regs
(
old_regs
);
}
void
__init
set_handle_irq
(
void
(
*
handle_irq
)(
struct
pt_regs
*
))
{
if
(
handle_arch_irq
)
...
...
arch/openrisc/Kconfig
View file @
468a903c
...
...
@@ -8,6 +8,7 @@ config OPENRISC
select OF
select OF_EARLY_FLATTREE
select IRQ_DOMAIN
select HANDLE_DOMAIN_IRQ
select HAVE_MEMBLOCK
select ARCH_REQUIRE_GPIOLIB
select HAVE_ARCH_TRACEHOOK
...
...
arch/openrisc/include/asm/irq.h
View file @
468a903c
...
...
@@ -24,7 +24,6 @@
#define NO_IRQ (-1)
void
handle_IRQ
(
unsigned
int
,
struct
pt_regs
*
);
extern
void
set_handle_irq
(
void
(
*
handle_irq
)(
struct
pt_regs
*
));
#endif
/* __ASM_OPENRISC_IRQ_H__ */
arch/openrisc/kernel/irq.c
View file @
468a903c
...
...
@@ -48,18 +48,6 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
handle_arch_irq
=
handle_irq
;
}
void
handle_IRQ
(
unsigned
int
irq
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
old_regs
=
set_irq_regs
(
regs
);
irq_enter
();
generic_handle_irq
(
irq
);
irq_exit
();
set_irq_regs
(
old_regs
);
}
void
__irq_entry
do_IRQ
(
struct
pt_regs
*
regs
)
{
handle_arch_irq
(
regs
);
...
...
drivers/irqchip/irq-armada-370-xp.c
View file @
468a903c
...
...
@@ -393,13 +393,15 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
if
(
!
(
msimask
&
BIT
(
msinr
)))
continue
;
irq
=
irq_find_mapping
(
armada_370_xp_msi_domain
,
msinr
-
16
);
if
(
is_chained
)
if
(
is_chained
)
{
irq
=
irq_find_mapping
(
armada_370_xp_msi_domain
,
msinr
-
16
);
generic_handle_irq
(
irq
);
else
handle_IRQ
(
irq
,
regs
);
}
else
{
irq
=
msinr
-
16
;
handle_domain_irq
(
armada_370_xp_msi_domain
,
irq
,
regs
);
}
}
}
#else
...
...
@@ -444,9 +446,8 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
break
;
if
(
irqnr
>
1
)
{
irqnr
=
irq_find_mapping
(
armada_370_xp_mpic_domain
,
irqnr
);
handle_IRQ
(
irqnr
,
regs
);
handle_domain_irq
(
armada_370_xp_mpic_domain
,
irqnr
,
regs
);
continue
;
}
...
...
drivers/irqchip/irq-atmel-aic.c
View file @
468a903c
...
...
@@ -68,12 +68,10 @@ aic_handle(struct pt_regs *regs)
irqnr
=
irq_reg_readl
(
gc
->
reg_base
+
AT91_AIC_IVR
);
irqstat
=
irq_reg_readl
(
gc
->
reg_base
+
AT91_AIC_ISR
);
irqnr
=
irq_find_mapping
(
aic_domain
,
irqnr
);
if
(
!
irqstat
)
irq_reg_writel
(
0
,
gc
->
reg_base
+
AT91_AIC_EOICR
);
else
handle_
IRQ
(
irqnr
,
regs
);
handle_
domain_irq
(
aic_domain
,
irqnr
,
regs
);
}
static
int
aic_retrigger
(
struct
irq_data
*
d
)
...
...
drivers/irqchip/irq-atmel-aic5.c
View file @
468a903c
...
...
@@ -78,12 +78,10 @@ aic5_handle(struct pt_regs *regs)
irqnr
=
irq_reg_readl
(
gc
->
reg_base
+
AT91_AIC5_IVR
);
irqstat
=
irq_reg_readl
(
gc
->
reg_base
+
AT91_AIC5_ISR
);
irqnr
=
irq_find_mapping
(
aic5_domain
,
irqnr
);
if
(
!
irqstat
)
irq_reg_writel
(
0
,
gc
->
reg_base
+
AT91_AIC5_EOICR
);
else
handle_
IRQ
(
irqnr
,
regs
);
handle_
domain_irq
(
aic5_domain
,
irqnr
,
regs
);
}
static
void
aic5_mask
(
struct
irq_data
*
d
)
...
...
drivers/irqchip/irq-clps711x.c
View file @
468a903c
...
...
@@ -76,24 +76,20 @@ static struct {
static
asmlinkage
void
__exception_irq_entry
clps711x_irqh
(
struct
pt_regs
*
regs
)
{
u32
irq
nr
,
irq
stat
;
u32
irqstat
;
do
{
irqstat
=
readw_relaxed
(
clps711x_intc
->
intmr
[
0
])
&
readw_relaxed
(
clps711x_intc
->
intsr
[
0
]);
if
(
irqstat
)
{
irqnr
=
irq_find_mapping
(
clps711x_intc
->
domain
,
fls
(
irqstat
)
-
1
);
handle_IRQ
(
irqnr
,
regs
);
}
if
(
irqstat
)
handle_domain_irq
(
clps711x_intc
->
domain
,
fls
(
irqstat
)
-
1
,
regs
);
irqstat
=
readw_relaxed
(
clps711x_intc
->
intmr
[
1
])
&
readw_relaxed
(
clps711x_intc
->
intsr
[
1
]);
if
(
irqstat
)
{
irqnr
=
irq_find_mapping
(
clps711x_intc
->
domain
,
fls
(
irqstat
)
-
1
+
16
);
handle_IRQ
(
irqnr
,
regs
);
}
if
(
irqstat
)
handle_domain_irq
(
clps711x_intc
->
domain
,
fls
(
irqstat
)
-
1
+
16
,
regs
);
}
while
(
irqstat
);
}
...
...
drivers/irqchip/irq-gic-v3.c
View file @
468a903c
...
...
@@ -274,14 +274,13 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
irqnr
=
gic_read_iar
();
if
(
likely
(
irqnr
>
15
&&
irqnr
<
1020
))
{
u64
irq
=
irq_find_mapping
(
gic_data
.
domain
,
irqnr
);
if
(
likely
(
irq
))
{
handle_IRQ
(
irq
,
regs
);
continue
;
int
err
;
err
=
handle_domain_irq
(
gic_data
.
domain
,
irqnr
,
regs
);
if
(
err
)
{
WARN_ONCE
(
true
,
"Unexpected SPI received!
\n
"
);
gic_write_eoir
(
irqnr
);
}
WARN_ONCE
(
true
,
"Unexpected SPI received!
\n
"
);
gic_write_eoir
(
irqnr
);
continue
;
}
if
(
irqnr
<
16
)
{
gic_write_eoir
(
irqnr
);
...
...
drivers/irqchip/irq-gic.c
View file @
468a903c
...
...
@@ -270,8 +270,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
irqnr
=
irqstat
&
GICC_IAR_INT_ID_MASK
;
if
(
likely
(
irqnr
>
15
&&
irqnr
<
1021
))
{
irqnr
=
irq_find_mapping
(
gic
->
domain
,
irqnr
);
handle_IRQ
(
irqnr
,
regs
);
handle_domain_irq
(
gic
->
domain
,
irqnr
,
regs
);
continue
;
}
if
(
irqnr
<
16
)
{
...
...
drivers/irqchip/irq-mmp.c
View file @
468a903c
...
...
@@ -196,26 +196,24 @@ static struct mmp_intc_conf mmp2_conf = {
static
void
__exception_irq_entry
mmp_handle_irq
(
struct
pt_regs
*
regs
)
{
int
irq
,
hwirq
;
int
hwirq
;
hwirq
=
readl_relaxed
(
mmp_icu_base
+
PJ1_INT_SEL
);
if
(
!
(
hwirq
&
SEL_INT_PENDING
))
return
;
hwirq
&=
SEL_INT_NUM_MASK
;
irq
=
irq_find_mapping
(
icu_data
[
0
].
domain
,
hwirq
);
handle_IRQ
(
irq
,
regs
);
handle_domain_irq
(
icu_data
[
0
].
domain
,
hwirq
,
regs
);
}
static
void
__exception_irq_entry
mmp2_handle_irq
(
struct
pt_regs
*
regs
)
{
int
irq
,
hwirq
;
int
hwirq
;
hwirq
=
readl_relaxed
(
mmp_icu_base
+
PJ4_INT_SEL
);
if
(
!
(
hwirq
&
SEL_INT_PENDING
))
return
;
hwirq
&=
SEL_INT_NUM_MASK
;
irq
=
irq_find_mapping
(
icu_data
[
0
].
domain
,
hwirq
);
handle_IRQ
(
irq
,
regs
);
handle_domain_irq
(
icu_data
[
0
].
domain
,
hwirq
,
regs
);
}
/* MMP (ARMv5) */
...
...
drivers/irqchip/irq-mxs.c
View file @
468a903c
...
...
@@ -78,8 +78,7 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
irqnr
=
__raw_readl
(
icoll_base
+
HW_ICOLL_STAT_OFFSET
);
__raw_writel
(
irqnr
,
icoll_base
+
HW_ICOLL_VECTOR
);
irqnr
=
irq_find_mapping
(
icoll_domain
,
irqnr
);
handle_IRQ
(
irqnr
,
regs
);
handle_domain_irq
(
icoll_domain
,
irqnr
,
regs
);
}
static
int
icoll_irq_domain_map
(
struct
irq_domain
*
d
,
unsigned
int
virq
,
...
...
drivers/irqchip/irq-or1k-pic.c
View file @
468a903c
...
...
@@ -113,7 +113,7 @@ static inline int pic_get_irq(int first)
else
hwirq
=
hwirq
+
first
-
1
;
return
irq_find_mapping
(
root_domain
,
hwirq
)
;
return
hwirq
;
}
static
void
or1k_pic_handle_irq
(
struct
pt_regs
*
regs
)
...
...
@@ -121,7 +121,7 @@ static void or1k_pic_handle_irq(struct pt_regs *regs)
int
irq
=
-
1
;
while
((
irq
=
pic_get_irq
(
irq
+
1
))
!=
NO_IRQ
)
handle_
IRQ
(
irq
,
regs
);
handle_
domain_irq
(
root_domain
,
irq
,
regs
);
}
static
int
or1k_map
(
struct
irq_domain
*
d
,
unsigned
int
irq
,
irq_hw_number_t
hw
)
...
...
drivers/irqchip/irq-orion.c
View file @
468a903c
...
...
@@ -43,9 +43,8 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs)
gc
->
mask_cache
;
while
(
stat
)
{
u32
hwirq
=
__fls
(
stat
);
u32
irq
=
irq_find_mapping
(
orion_irq_domain
,
gc
->
irq_base
+
hwirq
);
handle_IRQ
(
irq
,
regs
);
handle_domain_irq
(
orion_irq_domain
,
gc
->
irq_base
+
hwirq
,
regs
);
stat
&=
~
(
1
<<
hwirq
);
}
}
...
...
drivers/irqchip/irq-s3c24xx.c
View file @
468a903c
...
...
@@ -339,7 +339,6 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
{
int
pnd
;
int
offset
;
int
irq
;
pnd
=
__raw_readl
(
intc
->
reg_intpnd
);
if
(
!
pnd
)
...
...
@@ -365,8 +364,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
if
(
!
(
pnd
&
(
1
<<
offset
)))
offset
=
__ffs
(
pnd
);
irq
=
irq_find_mapping
(
intc
->
domain
,
intc_offset
+
offset
);
handle_IRQ
(
irq
,
regs
);
handle_domain_irq
(
intc
->
domain
,
intc_offset
+
offset
,
regs
);
return
true
;
}
...
...
drivers/irqchip/irq-sirfsoc.c
View file @
468a903c
...
...
@@ -50,12 +50,10 @@ sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
static
void
__exception_irq_entry
sirfsoc_handle_irq
(
struct
pt_regs
*
regs
)
{
void
__iomem
*
base
=
sirfsoc_irqdomain
->
host_data
;
u32
irqstat
,
irqnr
;
u32
irqstat
;
irqstat
=
readl_relaxed
(
base
+
SIRFSOC_INIT_IRQ_ID
);
irqnr
=
irq_find_mapping
(
sirfsoc_irqdomain
,
irqstat
&
0xff
);
handle_IRQ
(
irqnr
,
regs
);
handle_domain_irq
(
sirfsoc_irqdomain
,
irqstat
&
0xff
,
regs
);
}
static
int
__init
sirfsoc_irq_init
(
struct
device_node
*
np
,
...
...
drivers/irqchip/irq-sun4i.c
View file @
468a903c
...
...
@@ -136,7 +136,7 @@ IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-a10-ic", sun4i_of_init);
static
void
__exception_irq_entry
sun4i_handle_irq
(
struct
pt_regs
*
regs
)
{
u32
irq
,
hwirq
;
u32
hwirq
;
/*
* hwirq == 0 can mean one of 3 things:
...
...
@@ -154,8 +154,7 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs)
return
;
do
{
irq
=
irq_find_mapping
(
sun4i_irq_domain
,
hwirq
);
handle_IRQ
(
irq
,
regs
);
handle_domain_irq
(
sun4i_irq_domain
,
hwirq
,
regs
);
hwirq
=
readl
(
sun4i_irq_base
+
SUN4I_IRQ_VECTOR_REG
)
>>
2
;
}
while
(
hwirq
!=
0
);
}
drivers/irqchip/irq-versatile-fpga.c
View file @
468a903c
...
...
@@ -96,7 +96,7 @@ static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
while
((
status
=
readl
(
f
->
base
+
IRQ_STATUS
)))
{
irq
=
ffs
(
status
)
-
1
;
handle_
IRQ
(
irq_find_mapping
(
f
->
domain
,
irq
)
,
regs
);
handle_
domain_irq
(
f
->
domain
,
irq
,
regs
);
handled
=
1
;
}
...
...
drivers/irqchip/irq-vic.c
View file @
468a903c
...
...
@@ -219,7 +219,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
while
((
stat
=
readl_relaxed
(
vic
->
base
+
VIC_IRQ_STATUS
)))
{
irq
=
ffs
(
stat
)
-
1
;
handle_
IRQ
(
irq_find_mapping
(
vic
->
domain
,
irq
)
,
regs
);
handle_
domain_irq
(
vic
->
domain
,
irq
,
regs
);
handled
=
1
;
}
...
...
drivers/irqchip/irq-vt8500.c
View file @
468a903c
...
...
@@ -181,7 +181,7 @@ static struct irq_domain_ops vt8500_irq_domain_ops = {
static
void
__exception_irq_entry
vt8500_handle_irq
(
struct
pt_regs
*
regs
)
{
u32
stat
,
i
;
int
irqnr
,
virq
;
int
irqnr
;
void
__iomem
*
base
;
/* Loop through each active controller */
...
...
@@ -198,8 +198,7 @@ static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs)
continue
;
}
virq
=
irq_find_mapping
(
intc
[
i
].
domain
,
irqnr
);
handle_IRQ
(
virq
,
regs
);
handle_domain_irq
(
intc
[
i
].
domain
,
irqnr
,
regs
);
}
}
...
...
drivers/irqchip/irq-zevio.c
View file @
468a903c
...
...
@@ -56,8 +56,7 @@ static void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs)
while
(
readl
(
zevio_irq_io
+
IO_STATUS
))
{
irqnr
=
readl
(
zevio_irq_io
+
IO_CURRENT
);
irqnr
=
irq_find_mapping
(
zevio_irq_domain
,
irqnr
);
handle_IRQ
(
irqnr
,
regs
);
handle_domain_irq
(
zevio_irq_domain
,
irqnr
,
regs
);
};
}
...
...
include/linux/irqdesc.h
View file @
468a903c
...
...
@@ -12,6 +12,8 @@ struct irq_affinity_notify;
struct
proc_dir_entry
;
struct
module
;
struct
irq_desc
;
struct
irq_domain
;
struct
pt_regs
;
/**
* struct irq_desc - interrupt descriptor
...
...
@@ -118,6 +120,23 @@ static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *de
int
generic_handle_irq
(
unsigned
int
irq
);
#ifdef CONFIG_HANDLE_DOMAIN_IRQ
/*
* Convert a HW interrupt number to a logical one using a IRQ domain,
* and handle the result interrupt number. Return -EINVAL if
* conversion failed. Providing a NULL domain indicates that the
* conversion has already been done.
*/
int
__handle_domain_irq
(
struct
irq_domain
*
domain
,
unsigned
int
hwirq
,
bool
lookup
,
struct
pt_regs
*
regs
);
static
inline
int
handle_domain_irq
(
struct
irq_domain
*
domain
,
unsigned
int
hwirq
,
struct
pt_regs
*
regs
)
{
return
__handle_domain_irq
(
domain
,
hwirq
,
true
,
regs
);
}
#endif
/* Test to see if a driver has successfully requested an irq */
static
inline
int
irq_has_action
(
unsigned
int
irq
)
{
...
...
kernel/irq/Kconfig
View file @
468a903c
...
...
@@ -55,6 +55,9 @@ config GENERIC_IRQ_CHIP
config IRQ_DOMAIN
bool
config HANDLE_DOMAIN_IRQ
bool
config IRQ_DOMAIN_DEBUG
bool "Expose hardware/virtual IRQ mapping via debugfs"
depends on IRQ_DOMAIN && DEBUG_FS
...
...
kernel/irq/irqdesc.c
View file @
468a903c
...
...
@@ -14,6 +14,7 @@
#include <linux/kernel_stat.h>
#include <linux/radix-tree.h>
#include <linux/bitmap.h>
#include <linux/irqdomain.h>
#include "internals.h"
...
...
@@ -336,6 +337,47 @@ int generic_handle_irq(unsigned int irq)
}
EXPORT_SYMBOL_GPL
(
generic_handle_irq
);
#ifdef CONFIG_HANDLE_DOMAIN_IRQ
/**
* __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain
* @domain: The domain where to perform the lookup
* @hwirq: The HW irq number to convert to a logical one
* @lookup: Whether to perform the domain lookup or not
* @regs: Register file coming from the low-level handling code
*
* Returns: 0 on success, or -EINVAL if conversion has failed
*/
int
__handle_domain_irq
(
struct
irq_domain
*
domain
,
unsigned
int
hwirq
,
bool
lookup
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
old_regs
=
set_irq_regs
(
regs
);
unsigned
int
irq
=
hwirq
;
int
ret
=
0
;
irq_enter
();
#ifdef CONFIG_IRQ_DOMAIN
if
(
lookup
)
irq
=
irq_find_mapping
(
domain
,
hwirq
);
#endif
/*
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
*/
if
(
unlikely
(
!
irq
||
irq
>=
nr_irqs
))
{
ack_bad_irq
(
irq
);
ret
=
-
EINVAL
;
}
else
{
generic_handle_irq
(
irq
);
}
irq_exit
();
set_irq_regs
(
old_regs
);
return
ret
;
}
#endif
/* Dynamic interrupt handling */
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment