usb: typec: mux: fix static inline syntax error
[platform/kernel/linux-starfive.git] / drivers / irqchip / irq-gic-common.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2002 ARM Limited, All Rights Reserved.
4  */
5
6 #include <linux/interrupt.h>
7 #include <linux/io.h>
8 #include <linux/irq.h>
9 #include <linux/irqchip/arm-gic.h>
10
11 #include "irq-gic-common.h"
12
13 static DEFINE_RAW_SPINLOCK(irq_controller_lock);
14
15 void gic_enable_of_quirks(const struct device_node *np,
16                           const struct gic_quirk *quirks, void *data)
17 {
18         for (; quirks->desc; quirks++) {
19                 if (quirks->compatible &&
20                     !of_device_is_compatible(np, quirks->compatible))
21                         continue;
22                 if (quirks->property &&
23                     !of_property_read_bool(np, quirks->property))
24                         continue;
25                 if (quirks->init(data))
26                         pr_info("GIC: enabling workaround for %s\n",
27                                 quirks->desc);
28         }
29 }
30
31 void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
32                 void *data)
33 {
34         for (; quirks->desc; quirks++) {
35                 if (quirks->compatible || quirks->property)
36                         continue;
37                 if (quirks->iidr != (quirks->mask & iidr))
38                         continue;
39                 if (quirks->init(data))
40                         pr_info("GIC: enabling workaround for %s\n",
41                                 quirks->desc);
42         }
43 }
44
45 int gic_configure_irq(unsigned int irq, unsigned int type,
46                        void __iomem *base, void (*sync_access)(void))
47 {
48         u32 confmask = 0x2 << ((irq % 16) * 2);
49         u32 confoff = (irq / 16) * 4;
50         u32 val, oldval;
51         int ret = 0;
52         unsigned long flags;
53
54         /*
55          * Read current configuration register, and insert the config
56          * for "irq", depending on "type".
57          */
58         raw_spin_lock_irqsave(&irq_controller_lock, flags);
59         val = oldval = readl_relaxed(base + confoff);
60         if (type & IRQ_TYPE_LEVEL_MASK)
61                 val &= ~confmask;
62         else if (type & IRQ_TYPE_EDGE_BOTH)
63                 val |= confmask;
64
65         /* If the current configuration is the same, then we are done */
66         if (val == oldval) {
67                 raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
68                 return 0;
69         }
70
71         /*
72          * Write back the new configuration, and possibly re-enable
73          * the interrupt. If we fail to write a new configuration for
74          * an SPI then WARN and return an error. If we fail to write the
75          * configuration for a PPI this is most likely because the GIC
76          * does not allow us to set the configuration or we are in a
77          * non-secure mode, and hence it may not be catastrophic.
78          */
79         writel_relaxed(val, base + confoff);
80         if (readl_relaxed(base + confoff) != val)
81                 ret = -EINVAL;
82
83         raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
84
85         if (sync_access)
86                 sync_access();
87
88         return ret;
89 }
90
91 void gic_dist_config(void __iomem *base, int gic_irqs,
92                      void (*sync_access)(void))
93 {
94         unsigned int i;
95
96         /*
97          * Set all global interrupts to be level triggered, active low.
98          */
99         for (i = 32; i < gic_irqs; i += 16)
100                 writel_relaxed(GICD_INT_ACTLOW_LVLTRIG,
101                                         base + GIC_DIST_CONFIG + i / 4);
102
103         /*
104          * Set priority on all global interrupts.
105          */
106         for (i = 32; i < gic_irqs; i += 4)
107                 writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
108
109         /*
110          * Deactivate and disable all SPIs. Leave the PPI and SGIs
111          * alone as they are in the redistributor registers on GICv3.
112          */
113         for (i = 32; i < gic_irqs; i += 32) {
114                 writel_relaxed(GICD_INT_EN_CLR_X32,
115                                base + GIC_DIST_ACTIVE_CLEAR + i / 8);
116                 writel_relaxed(GICD_INT_EN_CLR_X32,
117                                base + GIC_DIST_ENABLE_CLEAR + i / 8);
118         }
119
120         if (sync_access)
121                 sync_access();
122 }
123
124 void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
125 {
126         int i;
127
128         /*
129          * Deal with the banked PPI and SGI interrupts - disable all
130          * private interrupts. Make sure everything is deactivated.
131          */
132         for (i = 0; i < nr; i += 32) {
133                 writel_relaxed(GICD_INT_EN_CLR_X32,
134                                base + GIC_DIST_ACTIVE_CLEAR + i / 8);
135                 writel_relaxed(GICD_INT_EN_CLR_X32,
136                                base + GIC_DIST_ENABLE_CLEAR + i / 8);
137         }
138
139         /*
140          * Set priority on PPI and SGI interrupts
141          */
142         for (i = 0; i < nr; i += 4)
143                 writel_relaxed(GICD_INT_DEF_PRI_X4,
144                                         base + GIC_DIST_PRI + i * 4 / 4);
145
146         if (sync_access)
147                 sync_access();
148 }