44 * Copyright (C) 2022 Ventana Micro Systems Inc.
55 */
66
7+ #include <linux/acpi.h>
78#include <linux/bitfield.h>
89#include <linux/irqchip/riscv-aplic.h>
10+ #include <linux/irqchip/riscv-imsic.h>
911#include <linux/module.h>
1012#include <linux/of.h>
1113#include <linux/of_irq.h>
@@ -125,39 +127,50 @@ static void aplic_init_hw_irqs(struct aplic_priv *priv)
125127 writel (0 , priv -> regs + APLIC_DOMAINCFG );
126128}
127129
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+
128139int aplic_setup_priv (struct aplic_priv * priv , struct device * dev , void __iomem * regs )
129140{
130141 struct device_node * np = to_of_node (dev -> fwnode );
131142 struct of_phandle_args parent ;
132143 int rc ;
133144
134- /*
135- * Currently, only OF fwnode is supported so extend this
136- * function for ACPI support.
137- */
138- if (!np )
139- return - EINVAL ;
140-
141145 /* Save device pointer and register base */
142146 priv -> dev = dev ;
143147 priv -> regs = regs ;
144148
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+ }
161174 }
162175
163176 /* Setup initial state APLIC interrupts */
@@ -184,14 +197,23 @@ static int aplic_probe(struct platform_device *pdev)
184197 * If msi-parent property is present then setup APLIC MSI
185198 * mode otherwise setup APLIC direct mode.
186199 */
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+
188205 if (msi_mode )
189206 rc = aplic_msi_setup (dev , regs );
190207 else
191208 rc = aplic_direct_setup (dev , regs );
192209 if (rc )
193210 dev_err (dev , "failed to setup APLIC in %s mode\n" , msi_mode ? "MSI" : "direct" );
194211
212+ #ifdef CONFIG_ACPI
213+ if (!acpi_disabled )
214+ acpi_dev_clear_dependencies (ACPI_COMPANION (dev ));
215+ #endif
216+
195217 return rc ;
196218}
197219
@@ -204,6 +226,7 @@ static struct platform_driver aplic_driver = {
204226 .driver = {
205227 .name = "riscv-aplic" ,
206228 .of_match_table = aplic_match ,
229+ .acpi_match_table = ACPI_PTR (aplic_acpi_match ),
207230 },
208231 .probe = aplic_probe ,
209232};
0 commit comments