Skip to content

Commit bf18123

Browse files
sudeep-hollaJassiBrar
authored andcommitted
mailbox: pcc: Avoid accessing PCCT table in pcc_send_data and pcc_mbox_irq
Now that the con_priv is availvale solely for PCC mailbox controller driver, let us use the same to save the channel specific information in it so that we can it whenever required instead of parsing the PCCT table entries every time in both pcc_send_data and pcc_mbox_irq. We can now use the newly introduces PCC register bundle to simplify both saving of channel specific information and accessing them without repeated checks for the subspace type. Reviewed-by: Cristian Marussi <[email protected]> Signed-off-by: Sudeep Holla <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 800cda7 commit bf18123

File tree

1 file changed

+32
-87
lines changed

1 file changed

+32
-87
lines changed

drivers/mailbox/pcc.c

Lines changed: 32 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,15 @@ struct pcc_chan_reg {
8686
* struct pcc_chan_info - PCC channel specific information
8787
*
8888
* @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
9292
* @plat_irq: platform interrupt
9393
*/
9494
struct pcc_chan_info {
9595
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;
9898
int plat_irq;
9999
};
100100

@@ -242,40 +242,15 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
242242
*/
243243
static irqreturn_t pcc_mbox_irq(int irq, void *p)
244244
{
245-
struct acpi_generic_address *doorbell_ack;
246-
struct acpi_pcct_hw_reduced *pcct_ss;
247245
struct pcc_chan_info *pchan;
248246
struct mbox_chan *chan = p;
249-
u64 doorbell_ack_preserve;
250-
u64 doorbell_ack_write;
251-
u64 doorbell_ack_val;
252-
int ret;
253247

254-
pcct_ss = chan->con_priv;
248+
pchan = chan->con_priv;
255249

256-
mbox_chan_received_data(chan, NULL);
250+
if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack))
251+
return IRQ_NONE;
257252

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);
279254

280255
return IRQ_HANDLED;
281256
}
@@ -381,42 +356,9 @@ EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
381356
*/
382357
static int pcc_send_data(struct mbox_chan *chan, void *data)
383358
{
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;
392360

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);
420362
}
421363

422364
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,
484426
static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
485427
struct acpi_subtable_header *pcct_entry)
486428
{
429+
int ret = 0;
487430
struct acpi_pcct_hw_reduced *pcct_ss;
488431

489432
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,
502445
if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
503446
struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
504447

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");
512453
}
513454

514-
return 0;
455+
return ret;
515456
}
516457

517458
/**
@@ -520,20 +461,22 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
520461
* @pchan: Pointer to the PCC channel info structure.
521462
* @pcct_entry: Pointer to the ACPI subtable header.
522463
*
464+
* Return: 0 for Success, else errno.
523465
*/
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)
526468
{
469+
int ret = 0;
470+
527471
struct acpi_pcct_subspace *pcct_ss;
528-
struct acpi_generic_address *db_reg;
529472

530473
pcct_ss = (struct acpi_pcct_subspace *)pcct_entry;
531474

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;
537480
}
538481

539482
/**
@@ -622,16 +565,18 @@ static int __init acpi_pcc_probe(void)
622565

623566
for (i = 0; i < count; i++) {
624567
struct pcc_chan_info *pchan = chan_info + i;
625-
pcc_mbox_channels[i].con_priv = pcct_entry;
626568

569+
pcc_mbox_channels[i].con_priv = pchan;
627570
pchan->chan.mchan = &pcc_mbox_channels[i];
628571

629572
if (pcc_mbox_ctrl.txdone_irq) {
630573
rc = pcc_parse_subspace_irq(pchan, pcct_entry);
631574
if (rc < 0)
632575
goto err;
633576
}
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;
635580

636581
pcc_parse_subspace_shmem(pchan, pcct_entry);
637582

0 commit comments

Comments
 (0)