diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/irq-gt641xx.c | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/irq-gt641xx.c')
-rw-r--r-- | arch/mips/kernel/irq-gt641xx.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c new file mode 100644 index 000000000..93bcf5736 --- /dev/null +++ b/arch/mips/kernel/irq-gt641xx.c | |||
@@ -0,0 +1,118 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
2 | /* | ||
3 | * GT641xx IRQ routines. | ||
4 | * | ||
5 | * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> | ||
6 | */ | ||
7 | #include <linux/hardirq.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/irq.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/types.h> | ||
12 | |||
13 | #include <asm/gt64120.h> | ||
14 | |||
15 | #define GT641XX_IRQ_TO_BIT(irq) (1U << (irq - GT641XX_IRQ_BASE)) | ||
16 | |||
17 | static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock); | ||
18 | |||
19 | static void ack_gt641xx_irq(struct irq_data *d) | ||
20 | { | ||
21 | unsigned long flags; | ||
22 | u32 cause; | ||
23 | |||
24 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | ||
25 | cause = GT_READ(GT_INTRCAUSE_OFS); | ||
26 | cause &= ~GT641XX_IRQ_TO_BIT(d->irq); | ||
27 | GT_WRITE(GT_INTRCAUSE_OFS, cause); | ||
28 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | ||
29 | } | ||
30 | |||
31 | static void mask_gt641xx_irq(struct irq_data *d) | ||
32 | { | ||
33 | unsigned long flags; | ||
34 | u32 mask; | ||
35 | |||
36 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | ||
37 | mask = GT_READ(GT_INTRMASK_OFS); | ||
38 | mask &= ~GT641XX_IRQ_TO_BIT(d->irq); | ||
39 | GT_WRITE(GT_INTRMASK_OFS, mask); | ||
40 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | ||
41 | } | ||
42 | |||
43 | static void mask_ack_gt641xx_irq(struct irq_data *d) | ||
44 | { | ||
45 | unsigned long flags; | ||
46 | u32 cause, mask; | ||
47 | |||
48 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | ||
49 | mask = GT_READ(GT_INTRMASK_OFS); | ||
50 | mask &= ~GT641XX_IRQ_TO_BIT(d->irq); | ||
51 | GT_WRITE(GT_INTRMASK_OFS, mask); | ||
52 | |||
53 | cause = GT_READ(GT_INTRCAUSE_OFS); | ||
54 | cause &= ~GT641XX_IRQ_TO_BIT(d->irq); | ||
55 | GT_WRITE(GT_INTRCAUSE_OFS, cause); | ||
56 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | ||
57 | } | ||
58 | |||
59 | static void unmask_gt641xx_irq(struct irq_data *d) | ||
60 | { | ||
61 | unsigned long flags; | ||
62 | u32 mask; | ||
63 | |||
64 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | ||
65 | mask = GT_READ(GT_INTRMASK_OFS); | ||
66 | mask |= GT641XX_IRQ_TO_BIT(d->irq); | ||
67 | GT_WRITE(GT_INTRMASK_OFS, mask); | ||
68 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | ||
69 | } | ||
70 | |||
71 | static struct irq_chip gt641xx_irq_chip = { | ||
72 | .name = "GT641xx", | ||
73 | .irq_ack = ack_gt641xx_irq, | ||
74 | .irq_mask = mask_gt641xx_irq, | ||
75 | .irq_mask_ack = mask_ack_gt641xx_irq, | ||
76 | .irq_unmask = unmask_gt641xx_irq, | ||
77 | }; | ||
78 | |||
79 | void gt641xx_irq_dispatch(void) | ||
80 | { | ||
81 | u32 cause, mask; | ||
82 | int i; | ||
83 | |||
84 | cause = GT_READ(GT_INTRCAUSE_OFS); | ||
85 | mask = GT_READ(GT_INTRMASK_OFS); | ||
86 | cause &= mask; | ||
87 | |||
88 | /* | ||
89 | * bit0 : logical or of all the interrupt bits. | ||
90 | * bit30: logical or of bits[29:26,20:1]. | ||
91 | * bit31: logical or of bits[25:1]. | ||
92 | */ | ||
93 | for (i = 1; i < 30; i++) { | ||
94 | if (cause & (1U << i)) { | ||
95 | do_IRQ(GT641XX_IRQ_BASE + i); | ||
96 | return; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | atomic_inc(&irq_err_count); | ||
101 | } | ||
102 | |||
103 | void __init gt641xx_irq_init(void) | ||
104 | { | ||
105 | int i; | ||
106 | |||
107 | GT_WRITE(GT_INTRMASK_OFS, 0); | ||
108 | GT_WRITE(GT_INTRCAUSE_OFS, 0); | ||
109 | |||
110 | /* | ||
111 | * bit0 : logical or of all the interrupt bits. | ||
112 | * bit30: logical or of bits[29:26,20:1]. | ||
113 | * bit31: logical or of bits[25:1]. | ||
114 | */ | ||
115 | for (i = 1; i < 30; i++) | ||
116 | irq_set_chip_and_handler(GT641XX_IRQ_BASE + i, | ||
117 | >641xx_irq_chip, handle_level_irq); | ||
118 | } | ||