1515#include <linux/pci.h>
1616#include <linux/slab.h>
1717
18+ static int nr_pics ;
19+
1820struct pch_msi_data {
1921 struct mutex msi_map_lock ;
2022 phys_addr_t doorbell ;
@@ -23,6 +25,8 @@ struct pch_msi_data {
2325 unsigned long * msi_map ;
2426};
2527
28+ static struct fwnode_handle * pch_msi_handle [MAX_IO_PICS ];
29+
2630static void pch_msi_mask_msi_irq (struct irq_data * d )
2731{
2832 pci_msi_mask_irq (d );
@@ -154,12 +158,12 @@ static const struct irq_domain_ops pch_msi_middle_domain_ops = {
154158};
155159
156160static int pch_msi_init_domains (struct pch_msi_data * priv ,
157- struct device_node * node ,
158- struct irq_domain * parent )
161+ struct irq_domain * parent ,
162+ struct fwnode_handle * domain_handle )
159163{
160164 struct irq_domain * middle_domain , * msi_domain ;
161165
162- middle_domain = irq_domain_create_linear (of_node_to_fwnode ( node ) ,
166+ middle_domain = irq_domain_create_linear (domain_handle ,
163167 priv -> num_irqs ,
164168 & pch_msi_middle_domain_ops ,
165169 priv );
@@ -171,7 +175,7 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
171175 middle_domain -> parent = parent ;
172176 irq_domain_update_bus_token (middle_domain , DOMAIN_BUS_NEXUS );
173177
174- msi_domain = pci_msi_create_irq_domain (of_node_to_fwnode ( node ) ,
178+ msi_domain = pci_msi_create_irq_domain (domain_handle ,
175179 & pch_msi_domain_info ,
176180 middle_domain );
177181 if (!msi_domain ) {
@@ -183,68 +187,107 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
183187 return 0 ;
184188}
185189
186- static int pch_msi_init (struct device_node * node ,
187- struct device_node * parent )
190+ static int pch_msi_init (phys_addr_t msg_address , int irq_base , int irq_count ,
191+ struct irq_domain * parent_domain , struct fwnode_handle * domain_handle )
188192{
189- struct pch_msi_data * priv ;
190- struct irq_domain * parent_domain ;
191- struct resource res ;
192193 int ret ;
193-
194- parent_domain = irq_find_host (parent );
195- if (!parent_domain ) {
196- pr_err ("Failed to find the parent domain\n" );
197- return - ENXIO ;
198- }
194+ struct pch_msi_data * priv ;
199195
200196 priv = kzalloc (sizeof (* priv ), GFP_KERNEL );
201197 if (!priv )
202198 return - ENOMEM ;
203199
204200 mutex_init (& priv -> msi_map_lock );
205201
206- ret = of_address_to_resource (node , 0 , & res );
207- if (ret ) {
208- pr_err ("Failed to allocate resource\n" );
209- goto err_priv ;
210- }
211-
212- priv -> doorbell = res .start ;
213-
214- if (of_property_read_u32 (node , "loongson,msi-base-vec" ,
215- & priv -> irq_first )) {
216- pr_err ("Unable to parse MSI vec base\n" );
217- ret = - EINVAL ;
218- goto err_priv ;
219- }
220-
221- if (of_property_read_u32 (node , "loongson,msi-num-vecs" ,
222- & priv -> num_irqs )) {
223- pr_err ("Unable to parse MSI vec number\n" );
224- ret = - EINVAL ;
225- goto err_priv ;
226- }
202+ priv -> doorbell = msg_address ;
203+ priv -> irq_first = irq_base ;
204+ priv -> num_irqs = irq_count ;
227205
228206 priv -> msi_map = bitmap_zalloc (priv -> num_irqs , GFP_KERNEL );
229- if (!priv -> msi_map ) {
230- ret = - ENOMEM ;
207+ if (!priv -> msi_map )
231208 goto err_priv ;
232- }
233209
234210 pr_debug ("Registering %d MSIs, starting at %d\n" ,
235211 priv -> num_irqs , priv -> irq_first );
236212
237- ret = pch_msi_init_domains (priv , node , parent_domain );
213+ ret = pch_msi_init_domains (priv , parent_domain , domain_handle );
238214 if (ret )
239215 goto err_map ;
240216
217+ pch_msi_handle [nr_pics ++ ] = domain_handle ;
241218 return 0 ;
242219
243220err_map :
244221 bitmap_free (priv -> msi_map );
245222err_priv :
246223 kfree (priv );
247- return ret ;
224+
225+ return - EINVAL ;
226+ }
227+
228+ #ifdef CONFIG_OF
229+ static int pch_msi_of_init (struct device_node * node , struct device_node * parent )
230+ {
231+ int err ;
232+ int irq_base , irq_count ;
233+ struct resource res ;
234+ struct irq_domain * parent_domain ;
235+
236+ parent_domain = irq_find_host (parent );
237+ if (!parent_domain ) {
238+ pr_err ("Failed to find the parent domain\n" );
239+ return - ENXIO ;
240+ }
241+
242+ if (of_address_to_resource (node , 0 , & res )) {
243+ pr_err ("Failed to allocate resource\n" );
244+ return - EINVAL ;
245+ }
246+
247+ if (of_property_read_u32 (node , "loongson,msi-base-vec" , & irq_base )) {
248+ pr_err ("Unable to parse MSI vec base\n" );
249+ return - EINVAL ;
250+ }
251+
252+ if (of_property_read_u32 (node , "loongson,msi-num-vecs" , & irq_count )) {
253+ pr_err ("Unable to parse MSI vec number\n" );
254+ return - EINVAL ;
255+ }
256+
257+ err = pch_msi_init (res .start , irq_base , irq_count , parent_domain , of_node_to_fwnode (node ));
258+ if (err < 0 )
259+ return err ;
260+
261+ return 0 ;
248262}
249263
250- IRQCHIP_DECLARE (pch_msi , "loongson,pch-msi-1.0" , pch_msi_init );
264+ IRQCHIP_DECLARE (pch_msi , "loongson,pch-msi-1.0" , pch_msi_of_init );
265+ #endif
266+
267+ #ifdef CONFIG_ACPI
268+ struct fwnode_handle * get_pch_msi_handle (int pci_segment )
269+ {
270+ int i ;
271+
272+ for (i = 0 ; i < MAX_IO_PICS ; i ++ ) {
273+ if (msi_group [i ].pci_segment == pci_segment )
274+ return pch_msi_handle [i ];
275+ }
276+ return NULL ;
277+ }
278+
279+ int __init pch_msi_acpi_init (struct irq_domain * parent ,
280+ struct acpi_madt_msi_pic * acpi_pchmsi )
281+ {
282+ int ret ;
283+ struct fwnode_handle * domain_handle ;
284+
285+ domain_handle = irq_domain_alloc_fwnode ((phys_addr_t * )acpi_pchmsi );
286+ ret = pch_msi_init (acpi_pchmsi -> msg_address , acpi_pchmsi -> start ,
287+ acpi_pchmsi -> count , parent , domain_handle );
288+ if (ret < 0 )
289+ irq_domain_free_fwnode (domain_handle );
290+
291+ return ret ;
292+ }
293+ #endif
0 commit comments