Skip to content

Commit 80b2bdd

Browse files
sudeep-hollaJassiBrar
authored andcommitted
mailbox: pcc: Refactor all PCC channel information into a structure
Currently all the PCC channel specific information are stored/maintained in global individual arrays for each of those information. It is not scalable and not clean if we have to stash more channel specific information. Couple of reasons to stash more information are to extend the support to Type 3/4 PCCT subspace and also to avoid accessing the PCCT table entries themselves each time we need the information. This patch moves all those PCC channel specific information into a separate structure pcc_chan_info. Signed-off-by: Sudeep Holla <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 10dcc2d commit 80b2bdd

File tree

1 file changed

+54
-53
lines changed

1 file changed

+54
-53
lines changed

drivers/mailbox/pcc.c

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,20 @@
6464

6565
static struct mbox_chan *pcc_mbox_channels;
6666

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;
7381

7482
static struct mbox_controller pcc_mbox_ctrl = {};
7583
/**
@@ -183,6 +191,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
183191
{
184192
struct acpi_generic_address *doorbell_ack;
185193
struct acpi_pcct_hw_reduced *pcct_ss;
194+
struct pcc_chan_info *pchan;
186195
struct mbox_chan *chan = p;
187196
u64 doorbell_ack_preserve;
188197
u64 doorbell_ack_write;
@@ -197,17 +206,17 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
197206
struct acpi_pcct_hw_reduced_type2 *pcct2_ss = chan->con_priv;
198207
u32 id = chan - pcc_mbox_channels;
199208

209+
pchan = chan_info + id;
200210
doorbell_ack = &pcct2_ss->platform_ack_register;
201211
doorbell_ack_preserve = pcct2_ss->ack_preserve_mask;
202212
doorbell_ack_write = pcct2_ss->ack_write_mask;
203213

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);
207216
if (ret)
208217
return IRQ_NONE;
209218

210-
ret = write_register(pcc_doorbell_ack_vaddr[id],
219+
ret = write_register(pchan->db_ack_vaddr,
211220
(doorbell_ack_val & doorbell_ack_preserve)
212221
| doorbell_ack_write,
213222
doorbell_ack->bit_width);
@@ -232,8 +241,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
232241
* ERR_PTR.
233242
*/
234243
struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
235-
int subspace_id)
244+
int subspace_id)
236245
{
246+
struct pcc_chan_info *pchan;
237247
struct device *dev = pcc_mbox_ctrl.dev;
238248
struct mbox_chan *chan;
239249
unsigned long flags;
@@ -251,6 +261,7 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
251261
dev_err(dev, "Channel not found for idx: %d\n", subspace_id);
252262
return ERR_PTR(-EBUSY);
253263
}
264+
pchan = chan_info + subspace_id;
254265

255266
spin_lock_irqsave(&chan->lock, flags);
256267
chan->msg_free = 0;
@@ -264,14 +275,14 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
264275

265276
spin_unlock_irqrestore(&chan->lock, flags);
266277

267-
if (pcc_doorbell_irq[subspace_id] > 0) {
278+
if (pchan->db_irq > 0) {
268279
int rc;
269280

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);
272283
if (unlikely(rc)) {
273284
dev_err(dev, "failed to register PCC interrupt %d\n",
274-
pcc_doorbell_irq[subspace_id]);
285+
pchan->db_irq);
275286
pcc_mbox_free_channel(chan);
276287
chan = ERR_PTR(rc);
277288
}
@@ -290,6 +301,7 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
290301
void pcc_mbox_free_channel(struct mbox_chan *chan)
291302
{
292303
u32 id = chan - pcc_mbox_channels;
304+
struct pcc_chan_info *pchan;
293305
unsigned long flags;
294306

295307
if (!chan || !chan->cl)
@@ -300,8 +312,9 @@ void pcc_mbox_free_channel(struct mbox_chan *chan)
300312
return;
301313
}
302314

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

306319
spin_lock_irqsave(&chan->lock, flags);
307320
chan->cl = NULL;
@@ -329,6 +342,7 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
329342
{
330343
struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv;
331344
struct acpi_generic_address *doorbell;
345+
struct pcc_chan_info *pchan;
332346
u64 doorbell_preserve;
333347
u64 doorbell_val;
334348
u64 doorbell_write;
@@ -340,19 +354,20 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
340354
return -ENOENT;
341355
}
342356

357+
pchan = chan_info + id;
343358
doorbell = &pcct_ss->doorbell_register;
344359
doorbell_preserve = pcct_ss->preserve_mask;
345360
doorbell_write = pcct_ss->write_mask;
346361

347362
/* 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);
351366
if (ret)
352367
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);
356371
} else {
357372
ret = acpi_read(&doorbell_val, doorbell);
358373
if (ret)
@@ -398,12 +413,13 @@ static int parse_pcc_subspace(union acpi_subtable_headers *header,
398413
*
399414
* This gets called for each entry in the PCC table.
400415
*/
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)
403417
{
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) {
407423
pr_err("PCC GSI %d not registered\n",
408424
pcct_ss->platform_interrupt);
409425
return -EINVAL;
@@ -413,10 +429,10 @@ static int pcc_parse_subspace_irq(int id,
413429
== ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
414430
struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
415431

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) {
420436
pr_err("Failed to ioremap PCC ACK register\n");
421437
return -ENOMEM;
422438
}
@@ -474,24 +490,12 @@ static int __init acpi_pcc_probe(void)
474490
goto err_put_pcct;
475491
}
476492

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) {
479495
rc = -ENOMEM;
480496
goto err_free_mbox;
481497
}
482498

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-
495499
/* Point to the first PCC subspace entry */
496500
pcct_entry = (struct acpi_subtable_header *) (
497501
(unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct));
@@ -501,6 +505,7 @@ static int __init acpi_pcc_probe(void)
501505
pcc_mbox_ctrl.txdone_irq = true;
502506

503507
for (i = 0; i < count; i++) {
508+
struct pcc_chan_info *pchan = chan_info + i;
504509
struct acpi_generic_address *db_reg;
505510
struct acpi_pcct_subspace *pcct_ss;
506511
pcc_mbox_channels[i].con_priv = pcct_entry;
@@ -522,8 +527,8 @@ static int __init acpi_pcc_probe(void)
522527
/* If doorbell is in system memory cache the virt address */
523528
db_reg = &pcct_ss->doorbell_register;
524529
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);
527532
pcct_entry = (struct acpi_subtable_header *)
528533
((unsigned long) pcct_entry + pcct_entry->length);
529534
}
@@ -535,11 +540,7 @@ static int __init acpi_pcc_probe(void)
535540
return 0;
536541

537542
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);
543544
err_free_mbox:
544545
kfree(pcc_mbox_channels);
545546
err_put_pcct:

0 commit comments

Comments
 (0)