4
4
* Copyright (C) 2022 Ventana Micro Systems Inc.
5
5
*/
6
6
7
+ #include <linux/acpi.h>
7
8
#include <linux/bitfield.h>
8
9
#include <linux/irqchip/riscv-aplic.h>
10
+ #include <linux/irqchip/riscv-imsic.h>
9
11
#include <linux/module.h>
10
12
#include <linux/of.h>
11
13
#include <linux/of_irq.h>
@@ -125,39 +127,50 @@ static void aplic_init_hw_irqs(struct aplic_priv *priv)
125
127
writel (0 , priv -> regs + APLIC_DOMAINCFG );
126
128
}
127
129
130
+ #ifdef CONFIG_ACPI
131
+ static const struct acpi_device_id aplic_acpi_match [] = {
132
+ { "RSCV0002" , 0 },
133
+ {}
134
+ };
135
+ MODULE_DEVICE_TABLE (acpi , aplic_acpi_match );
136
+
137
+ #endif
138
+
128
139
int aplic_setup_priv (struct aplic_priv * priv , struct device * dev , void __iomem * regs )
129
140
{
130
141
struct device_node * np = to_of_node (dev -> fwnode );
131
142
struct of_phandle_args parent ;
132
143
int rc ;
133
144
134
- /*
135
- * Currently, only OF fwnode is supported so extend this
136
- * function for ACPI support.
137
- */
138
- if (!np )
139
- return - EINVAL ;
140
-
141
145
/* Save device pointer and register base */
142
146
priv -> dev = dev ;
143
147
priv -> regs = regs ;
144
148
145
- /* Find out number of interrupt sources */
146
- rc = of_property_read_u32 (np , "riscv,num-sources" , & priv -> nr_irqs );
147
- if (rc ) {
148
- dev_err (dev , "failed to get number of interrupt sources\n" );
149
- return rc ;
150
- }
151
-
152
- /*
153
- * Find out number of IDCs based on parent interrupts
154
- *
155
- * If "msi-parent" property is present then we ignore the
156
- * APLIC IDCs which forces the APLIC driver to use MSI mode.
157
- */
158
- if (!of_property_present (np , "msi-parent" )) {
159
- while (!of_irq_parse_one (np , priv -> nr_idcs , & parent ))
160
- priv -> nr_idcs ++ ;
149
+ if (np ) {
150
+ /* Find out number of interrupt sources */
151
+ rc = of_property_read_u32 (np , "riscv,num-sources" , & priv -> nr_irqs );
152
+ if (rc ) {
153
+ dev_err (dev , "failed to get number of interrupt sources\n" );
154
+ return rc ;
155
+ }
156
+
157
+ /*
158
+ * Find out number of IDCs based on parent interrupts
159
+ *
160
+ * If "msi-parent" property is present then we ignore the
161
+ * APLIC IDCs which forces the APLIC driver to use MSI mode.
162
+ */
163
+ if (!of_property_present (np , "msi-parent" )) {
164
+ while (!of_irq_parse_one (np , priv -> nr_idcs , & parent ))
165
+ priv -> nr_idcs ++ ;
166
+ }
167
+ } else {
168
+ rc = riscv_acpi_get_gsi_info (dev -> fwnode , & priv -> gsi_base , & priv -> acpi_aplic_id ,
169
+ & priv -> nr_irqs , & priv -> nr_idcs );
170
+ if (rc ) {
171
+ dev_err (dev , "failed to find GSI mapping\n" );
172
+ return rc ;
173
+ }
161
174
}
162
175
163
176
/* Setup initial state APLIC interrupts */
@@ -184,14 +197,23 @@ static int aplic_probe(struct platform_device *pdev)
184
197
* If msi-parent property is present then setup APLIC MSI
185
198
* mode otherwise setup APLIC direct mode.
186
199
*/
187
- msi_mode = of_property_present (to_of_node (dev -> fwnode ), "msi-parent" );
200
+ if (is_of_node (dev -> fwnode ))
201
+ msi_mode = of_property_present (to_of_node (dev -> fwnode ), "msi-parent" );
202
+ else
203
+ msi_mode = imsic_acpi_get_fwnode (NULL ) ? 1 : 0 ;
204
+
188
205
if (msi_mode )
189
206
rc = aplic_msi_setup (dev , regs );
190
207
else
191
208
rc = aplic_direct_setup (dev , regs );
192
209
if (rc )
193
210
dev_err (dev , "failed to setup APLIC in %s mode\n" , msi_mode ? "MSI" : "direct" );
194
211
212
+ #ifdef CONFIG_ACPI
213
+ if (!acpi_disabled )
214
+ acpi_dev_clear_dependencies (ACPI_COMPANION (dev ));
215
+ #endif
216
+
195
217
return rc ;
196
218
}
197
219
@@ -204,6 +226,7 @@ static struct platform_driver aplic_driver = {
204
226
.driver = {
205
227
.name = "riscv-aplic" ,
206
228
.of_match_table = aplic_match ,
229
+ .acpi_match_table = ACPI_PTR (aplic_acpi_match ),
207
230
},
208
231
.probe = aplic_probe ,
209
232
};
0 commit comments