64
64
65
65
static struct mbox_chan * pcc_mbox_channels ;
66
66
67
- /* Array of cached virtual address for doorbell registers */
68
- static void __iomem * * pcc_doorbell_vaddr ;
69
- /* Array of cached virtual address for doorbell ack registers */
70
- static void __iomem * * pcc_doorbell_ack_vaddr ;
71
- /* Array of doorbell interrupts */
72
- static int * pcc_doorbell_irq ;
67
+ /**
68
+ * struct pcc_chan_info - PCC channel specific information
69
+ *
70
+ * @db_vaddr: cached virtual address for doorbell register
71
+ * @db_ack_vaddr: cached virtual address for doorbell ack register
72
+ * @db_irq: doorbell interrupt
73
+ */
74
+ struct pcc_chan_info {
75
+ void __iomem * db_vaddr ;
76
+ void __iomem * db_ack_vaddr ;
77
+ int db_irq ;
78
+ };
79
+
80
+ static struct pcc_chan_info * chan_info ;
73
81
74
82
static struct mbox_controller pcc_mbox_ctrl = {};
75
83
/**
@@ -183,6 +191,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
183
191
{
184
192
struct acpi_generic_address * doorbell_ack ;
185
193
struct acpi_pcct_hw_reduced * pcct_ss ;
194
+ struct pcc_chan_info * pchan ;
186
195
struct mbox_chan * chan = p ;
187
196
u64 doorbell_ack_preserve ;
188
197
u64 doorbell_ack_write ;
@@ -197,17 +206,17 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
197
206
struct acpi_pcct_hw_reduced_type2 * pcct2_ss = chan -> con_priv ;
198
207
u32 id = chan - pcc_mbox_channels ;
199
208
209
+ pchan = chan_info + id ;
200
210
doorbell_ack = & pcct2_ss -> platform_ack_register ;
201
211
doorbell_ack_preserve = pcct2_ss -> ack_preserve_mask ;
202
212
doorbell_ack_write = pcct2_ss -> ack_write_mask ;
203
213
204
- ret = read_register (pcc_doorbell_ack_vaddr [id ],
205
- & doorbell_ack_val ,
206
- doorbell_ack -> bit_width );
214
+ ret = read_register (pchan -> db_ack_vaddr ,
215
+ & doorbell_ack_val , doorbell_ack -> bit_width );
207
216
if (ret )
208
217
return IRQ_NONE ;
209
218
210
- ret = write_register (pcc_doorbell_ack_vaddr [ id ] ,
219
+ ret = write_register (pchan -> db_ack_vaddr ,
211
220
(doorbell_ack_val & doorbell_ack_preserve )
212
221
| doorbell_ack_write ,
213
222
doorbell_ack -> bit_width );
@@ -232,8 +241,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
232
241
* ERR_PTR.
233
242
*/
234
243
struct mbox_chan * pcc_mbox_request_channel (struct mbox_client * cl ,
235
- int subspace_id )
244
+ int subspace_id )
236
245
{
246
+ struct pcc_chan_info * pchan ;
237
247
struct device * dev = pcc_mbox_ctrl .dev ;
238
248
struct mbox_chan * chan ;
239
249
unsigned long flags ;
@@ -251,6 +261,7 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
251
261
dev_err (dev , "Channel not found for idx: %d\n" , subspace_id );
252
262
return ERR_PTR (- EBUSY );
253
263
}
264
+ pchan = chan_info + subspace_id ;
254
265
255
266
spin_lock_irqsave (& chan -> lock , flags );
256
267
chan -> msg_free = 0 ;
@@ -264,14 +275,14 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
264
275
265
276
spin_unlock_irqrestore (& chan -> lock , flags );
266
277
267
- if (pcc_doorbell_irq [ subspace_id ] > 0 ) {
278
+ if (pchan -> db_irq > 0 ) {
268
279
int rc ;
269
280
270
- rc = devm_request_irq (dev , pcc_doorbell_irq [ subspace_id ] ,
271
- pcc_mbox_irq , 0 , MBOX_IRQ_NAME , chan );
281
+ rc = devm_request_irq (dev , pchan -> db_irq , pcc_mbox_irq , 0 ,
282
+ MBOX_IRQ_NAME , chan );
272
283
if (unlikely (rc )) {
273
284
dev_err (dev , "failed to register PCC interrupt %d\n" ,
274
- pcc_doorbell_irq [ subspace_id ] );
285
+ pchan -> db_irq );
275
286
pcc_mbox_free_channel (chan );
276
287
chan = ERR_PTR (rc );
277
288
}
@@ -290,6 +301,7 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
290
301
void pcc_mbox_free_channel (struct mbox_chan * chan )
291
302
{
292
303
u32 id = chan - pcc_mbox_channels ;
304
+ struct pcc_chan_info * pchan ;
293
305
unsigned long flags ;
294
306
295
307
if (!chan || !chan -> cl )
@@ -300,8 +312,9 @@ void pcc_mbox_free_channel(struct mbox_chan *chan)
300
312
return ;
301
313
}
302
314
303
- if (pcc_doorbell_irq [id ] > 0 )
304
- devm_free_irq (chan -> mbox -> dev , pcc_doorbell_irq [id ], chan );
315
+ pchan = chan_info + id ;
316
+ if (pchan -> db_irq > 0 )
317
+ devm_free_irq (chan -> mbox -> dev , pchan -> db_irq , chan );
305
318
306
319
spin_lock_irqsave (& chan -> lock , flags );
307
320
chan -> cl = NULL ;
@@ -329,6 +342,7 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
329
342
{
330
343
struct acpi_pcct_hw_reduced * pcct_ss = chan -> con_priv ;
331
344
struct acpi_generic_address * doorbell ;
345
+ struct pcc_chan_info * pchan ;
332
346
u64 doorbell_preserve ;
333
347
u64 doorbell_val ;
334
348
u64 doorbell_write ;
@@ -340,19 +354,20 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
340
354
return - ENOENT ;
341
355
}
342
356
357
+ pchan = chan_info + id ;
343
358
doorbell = & pcct_ss -> doorbell_register ;
344
359
doorbell_preserve = pcct_ss -> preserve_mask ;
345
360
doorbell_write = pcct_ss -> write_mask ;
346
361
347
362
/* Sync notification from OS to Platform. */
348
- if (pcc_doorbell_vaddr [ id ] ) {
349
- ret = read_register (pcc_doorbell_vaddr [ id ] , & doorbell_val ,
350
- doorbell -> bit_width );
363
+ if (pchan -> db_vaddr ) {
364
+ ret = read_register (pchan -> db_vaddr , & doorbell_val ,
365
+ doorbell -> bit_width );
351
366
if (ret )
352
367
return ret ;
353
- ret = write_register (pcc_doorbell_vaddr [ id ] ,
354
- (doorbell_val & doorbell_preserve ) | doorbell_write ,
355
- doorbell -> bit_width );
368
+ ret = write_register (pchan -> db_vaddr ,
369
+ (doorbell_val & doorbell_preserve )
370
+ | doorbell_write , doorbell -> bit_width );
356
371
} else {
357
372
ret = acpi_read (& doorbell_val , doorbell );
358
373
if (ret )
@@ -398,12 +413,13 @@ static int parse_pcc_subspace(union acpi_subtable_headers *header,
398
413
*
399
414
* This gets called for each entry in the PCC table.
400
415
*/
401
- static int pcc_parse_subspace_irq (int id ,
402
- struct acpi_pcct_hw_reduced * pcct_ss )
416
+ static int pcc_parse_subspace_irq (int id , struct acpi_pcct_hw_reduced * pcct_ss )
403
417
{
404
- pcc_doorbell_irq [id ] = pcc_map_interrupt (pcct_ss -> platform_interrupt ,
405
- (u32 )pcct_ss -> flags );
406
- if (pcc_doorbell_irq [id ] <= 0 ) {
418
+ struct pcc_chan_info * pchan = chan_info + id ;
419
+
420
+ pchan -> db_irq = pcc_map_interrupt (pcct_ss -> platform_interrupt ,
421
+ (u32 )pcct_ss -> flags );
422
+ if (pchan -> db_irq <= 0 ) {
407
423
pr_err ("PCC GSI %d not registered\n" ,
408
424
pcct_ss -> platform_interrupt );
409
425
return - EINVAL ;
@@ -413,10 +429,10 @@ static int pcc_parse_subspace_irq(int id,
413
429
== ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2 ) {
414
430
struct acpi_pcct_hw_reduced_type2 * pcct2_ss = (void * )pcct_ss ;
415
431
416
- pcc_doorbell_ack_vaddr [ id ] = acpi_os_ioremap (
417
- pcct2_ss -> platform_ack_register .address ,
418
- pcct2_ss -> platform_ack_register .bit_width / 8 );
419
- if (!pcc_doorbell_ack_vaddr [ id ] ) {
432
+ pchan -> db_ack_vaddr =
433
+ acpi_os_ioremap ( pcct2_ss -> platform_ack_register .address ,
434
+ pcct2_ss -> platform_ack_register .bit_width / 8 );
435
+ if (!pchan -> db_ack_vaddr ) {
420
436
pr_err ("Failed to ioremap PCC ACK register\n" );
421
437
return - ENOMEM ;
422
438
}
@@ -474,24 +490,12 @@ static int __init acpi_pcc_probe(void)
474
490
goto err_put_pcct ;
475
491
}
476
492
477
- pcc_doorbell_vaddr = kcalloc (count , sizeof (void * ), GFP_KERNEL );
478
- if (!pcc_doorbell_vaddr ) {
493
+ chan_info = kcalloc (count , sizeof (* chan_info ), GFP_KERNEL );
494
+ if (!chan_info ) {
479
495
rc = - ENOMEM ;
480
496
goto err_free_mbox ;
481
497
}
482
498
483
- pcc_doorbell_ack_vaddr = kcalloc (count , sizeof (void * ), GFP_KERNEL );
484
- if (!pcc_doorbell_ack_vaddr ) {
485
- rc = - ENOMEM ;
486
- goto err_free_db_vaddr ;
487
- }
488
-
489
- pcc_doorbell_irq = kcalloc (count , sizeof (int ), GFP_KERNEL );
490
- if (!pcc_doorbell_irq ) {
491
- rc = - ENOMEM ;
492
- goto err_free_db_ack_vaddr ;
493
- }
494
-
495
499
/* Point to the first PCC subspace entry */
496
500
pcct_entry = (struct acpi_subtable_header * ) (
497
501
(unsigned long ) pcct_tbl + sizeof (struct acpi_table_pcct ));
@@ -501,6 +505,7 @@ static int __init acpi_pcc_probe(void)
501
505
pcc_mbox_ctrl .txdone_irq = true;
502
506
503
507
for (i = 0 ; i < count ; i ++ ) {
508
+ struct pcc_chan_info * pchan = chan_info + i ;
504
509
struct acpi_generic_address * db_reg ;
505
510
struct acpi_pcct_subspace * pcct_ss ;
506
511
pcc_mbox_channels [i ].con_priv = pcct_entry ;
@@ -522,8 +527,8 @@ static int __init acpi_pcc_probe(void)
522
527
/* If doorbell is in system memory cache the virt address */
523
528
db_reg = & pcct_ss -> doorbell_register ;
524
529
if (db_reg -> space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY )
525
- pcc_doorbell_vaddr [ i ] = acpi_os_ioremap (db_reg -> address ,
526
- db_reg -> bit_width / 8 );
530
+ pchan -> db_vaddr = acpi_os_ioremap (db_reg -> address ,
531
+ db_reg -> bit_width / 8 );
527
532
pcct_entry = (struct acpi_subtable_header * )
528
533
((unsigned long ) pcct_entry + pcct_entry -> length );
529
534
}
@@ -535,11 +540,7 @@ static int __init acpi_pcc_probe(void)
535
540
return 0 ;
536
541
537
542
err :
538
- kfree (pcc_doorbell_irq );
539
- err_free_db_ack_vaddr :
540
- kfree (pcc_doorbell_ack_vaddr );
541
- err_free_db_vaddr :
542
- kfree (pcc_doorbell_vaddr );
543
+ kfree (chan_info );
543
544
err_free_mbox :
544
545
kfree (pcc_mbox_channels );
545
546
err_put_pcct :
0 commit comments