@@ -86,15 +86,15 @@ struct pcc_chan_reg {
86
86
* struct pcc_chan_info - PCC channel specific information
87
87
*
88
88
* @chan: PCC channel information with Shared Memory Region info
89
- * @db_vaddr: cached virtual address for doorbell register
90
- * @plat_irq_ack_vaddr: cached virtual address for platform interrupt
91
- * acknowledge register
89
+ * @db: PCC register bundle for the doorbell register
90
+ * @plat_irq_ack: PCC register bundle for the platform interrupt acknowledge
91
+ * register
92
92
* @plat_irq: platform interrupt
93
93
*/
94
94
struct pcc_chan_info {
95
95
struct pcc_mbox_chan chan ;
96
- void __iomem * db_vaddr ;
97
- void __iomem * plat_irq_ack_vaddr ;
96
+ struct pcc_chan_reg db ;
97
+ struct pcc_chan_reg plat_irq_ack ;
98
98
int plat_irq ;
99
99
};
100
100
@@ -242,40 +242,15 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
242
242
*/
243
243
static irqreturn_t pcc_mbox_irq (int irq , void * p )
244
244
{
245
- struct acpi_generic_address * doorbell_ack ;
246
- struct acpi_pcct_hw_reduced * pcct_ss ;
247
245
struct pcc_chan_info * pchan ;
248
246
struct mbox_chan * chan = p ;
249
- u64 doorbell_ack_preserve ;
250
- u64 doorbell_ack_write ;
251
- u64 doorbell_ack_val ;
252
- int ret ;
253
247
254
- pcct_ss = chan -> con_priv ;
248
+ pchan = chan -> con_priv ;
255
249
256
- mbox_chan_received_data (chan , NULL );
250
+ if (pcc_chan_reg_read_modify_write (& pchan -> plat_irq_ack ))
251
+ return IRQ_NONE ;
257
252
258
- if (pcct_ss -> header .type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2 ) {
259
- struct acpi_pcct_hw_reduced_type2 * pcct2_ss = chan -> con_priv ;
260
- u32 id = chan - pcc_mbox_channels ;
261
-
262
- pchan = chan_info + id ;
263
- doorbell_ack = & pcct2_ss -> platform_ack_register ;
264
- doorbell_ack_preserve = pcct2_ss -> ack_preserve_mask ;
265
- doorbell_ack_write = pcct2_ss -> ack_write_mask ;
266
-
267
- ret = read_register (pchan -> plat_irq_ack_vaddr ,
268
- & doorbell_ack_val , doorbell_ack -> bit_width );
269
- if (ret )
270
- return IRQ_NONE ;
271
-
272
- ret = write_register (pchan -> plat_irq_ack_vaddr ,
273
- (doorbell_ack_val & doorbell_ack_preserve )
274
- | doorbell_ack_write ,
275
- doorbell_ack -> bit_width );
276
- if (ret )
277
- return IRQ_NONE ;
278
- }
253
+ mbox_chan_received_data (chan , NULL );
279
254
280
255
return IRQ_HANDLED ;
281
256
}
@@ -381,42 +356,9 @@ EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
381
356
*/
382
357
static int pcc_send_data (struct mbox_chan * chan , void * data )
383
358
{
384
- struct acpi_pcct_hw_reduced * pcct_ss = chan -> con_priv ;
385
- struct acpi_generic_address * doorbell ;
386
- struct pcc_chan_info * pchan ;
387
- u64 doorbell_preserve ;
388
- u64 doorbell_val ;
389
- u64 doorbell_write ;
390
- u32 id = chan - pcc_mbox_channels ;
391
- int ret = 0 ;
359
+ struct pcc_chan_info * pchan = chan -> con_priv ;
392
360
393
- if (id >= pcc_mbox_ctrl .num_chans ) {
394
- pr_debug ("pcc_send_data: Invalid mbox_chan passed\n" );
395
- return - ENOENT ;
396
- }
397
-
398
- pchan = chan_info + id ;
399
- doorbell = & pcct_ss -> doorbell_register ;
400
- doorbell_preserve = pcct_ss -> preserve_mask ;
401
- doorbell_write = pcct_ss -> write_mask ;
402
-
403
- /* Sync notification from OS to Platform. */
404
- if (pchan -> db_vaddr ) {
405
- ret = read_register (pchan -> db_vaddr , & doorbell_val ,
406
- doorbell -> bit_width );
407
- if (ret )
408
- return ret ;
409
- ret = write_register (pchan -> db_vaddr ,
410
- (doorbell_val & doorbell_preserve )
411
- | doorbell_write , doorbell -> bit_width );
412
- } else {
413
- ret = acpi_read (& doorbell_val , doorbell );
414
- if (ret )
415
- return ret ;
416
- ret = acpi_write ((doorbell_val & doorbell_preserve ) | doorbell_write ,
417
- doorbell );
418
- }
419
- return ret ;
361
+ return pcc_chan_reg_read_modify_write (& pchan -> db );
420
362
}
421
363
422
364
static const struct mbox_chan_ops pcc_chan_ops = {
@@ -484,6 +426,7 @@ pcc_chan_reg_init(struct pcc_chan_reg *reg, struct acpi_generic_address *gas,
484
426
static int pcc_parse_subspace_irq (struct pcc_chan_info * pchan ,
485
427
struct acpi_subtable_header * pcct_entry )
486
428
{
429
+ int ret = 0 ;
487
430
struct acpi_pcct_hw_reduced * pcct_ss ;
488
431
489
432
if (pcct_entry -> type < ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
@@ -502,16 +445,14 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
502
445
if (pcct_ss -> header .type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2 ) {
503
446
struct acpi_pcct_hw_reduced_type2 * pcct2_ss = (void * )pcct_ss ;
504
447
505
- pchan -> plat_irq_ack_vaddr =
506
- acpi_os_ioremap (pcct2_ss -> platform_ack_register .address ,
507
- pcct2_ss -> platform_ack_register .bit_width / 8 );
508
- if (!pchan -> plat_irq_ack_vaddr ) {
509
- pr_err ("Failed to ioremap PCC ACK register\n" );
510
- return - ENOMEM ;
511
- }
448
+ ret = pcc_chan_reg_init (& pchan -> plat_irq_ack ,
449
+ & pcct2_ss -> platform_ack_register ,
450
+ pcct2_ss -> ack_preserve_mask ,
451
+ pcct2_ss -> ack_write_mask , 0 ,
452
+ "PLAT IRQ ACK" );
512
453
}
513
454
514
- return 0 ;
455
+ return ret ;
515
456
}
516
457
517
458
/**
@@ -520,20 +461,22 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
520
461
* @pchan: Pointer to the PCC channel info structure.
521
462
* @pcct_entry: Pointer to the ACPI subtable header.
522
463
*
464
+ * Return: 0 for Success, else errno.
523
465
*/
524
- static void pcc_parse_subspace_db_reg (struct pcc_chan_info * pchan ,
525
- struct acpi_subtable_header * pcct_entry )
466
+ static int pcc_parse_subspace_db_reg (struct pcc_chan_info * pchan ,
467
+ struct acpi_subtable_header * pcct_entry )
526
468
{
469
+ int ret = 0 ;
470
+
527
471
struct acpi_pcct_subspace * pcct_ss ;
528
- struct acpi_generic_address * db_reg ;
529
472
530
473
pcct_ss = (struct acpi_pcct_subspace * )pcct_entry ;
531
474
532
- /* If doorbell is in system memory cache the virt address */
533
- db_reg = & pcct_ss -> doorbell_register ;
534
- if ( db_reg -> space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY )
535
- pchan -> db_vaddr = acpi_os_ioremap ( db_reg -> address ,
536
- db_reg -> bit_width / 8 ) ;
475
+ ret = pcc_chan_reg_init ( & pchan -> db ,
476
+ & pcct_ss -> doorbell_register ,
477
+ pcct_ss -> preserve_mask ,
478
+ pcct_ss -> write_mask , 0 , "Doorbell" );
479
+ return ret ;
537
480
}
538
481
539
482
/**
@@ -622,16 +565,18 @@ static int __init acpi_pcc_probe(void)
622
565
623
566
for (i = 0 ; i < count ; i ++ ) {
624
567
struct pcc_chan_info * pchan = chan_info + i ;
625
- pcc_mbox_channels [i ].con_priv = pcct_entry ;
626
568
569
+ pcc_mbox_channels [i ].con_priv = pchan ;
627
570
pchan -> chan .mchan = & pcc_mbox_channels [i ];
628
571
629
572
if (pcc_mbox_ctrl .txdone_irq ) {
630
573
rc = pcc_parse_subspace_irq (pchan , pcct_entry );
631
574
if (rc < 0 )
632
575
goto err ;
633
576
}
634
- pcc_parse_subspace_db_reg (pchan , pcct_entry );
577
+ rc = pcc_parse_subspace_db_reg (pchan , pcct_entry );
578
+ if (rc < 0 )
579
+ goto err ;
635
580
636
581
pcc_parse_subspace_shmem (pchan , pcct_entry );
637
582
0 commit comments