in pcc.c [627:716]
static int pcc_mbox_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mbox_controller *pcc_mbox_ctrl;
struct mbox_chan *pcc_mbox_channels;
struct acpi_table_header *pcct_tbl;
struct acpi_subtable_header *pcct_entry;
struct acpi_table_pcct *acpi_pcct_tbl;
acpi_status status = AE_OK;
int i, rc, count = pcc_chan_count;
/* Search for PCCT */
status = acpi_get_table(ACPI_SIG_PCCT, 0, &pcct_tbl);
if (ACPI_FAILURE(status) || !pcct_tbl)
return -ENODEV;
pcc_mbox_channels = devm_kcalloc(dev, count, sizeof(*pcc_mbox_channels),
GFP_KERNEL);
if (!pcc_mbox_channels) {
rc = -ENOMEM;
goto err;
}
chan_info = devm_kcalloc(dev, count, sizeof(*chan_info), GFP_KERNEL);
if (!chan_info) {
rc = -ENOMEM;
goto err;
}
pcc_mbox_ctrl = devm_kmalloc(dev, sizeof(*pcc_mbox_ctrl), GFP_KERNEL);
if (!pcc_mbox_ctrl) {
rc = -ENOMEM;
goto err;
}
/* Point to the first PCC subspace entry */
pcct_entry = (struct acpi_subtable_header *) (
(unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct));
acpi_pcct_tbl = (struct acpi_table_pcct *) pcct_tbl;
if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL)
pcc_mbox_ctrl->txdone_irq = true;
for (i = 0; i < count; i++) {
struct pcc_chan_info *pchan = chan_info + i;
pcc_mbox_channels[i].con_priv = pchan;
pchan->chan.mchan = &pcc_mbox_channels[i];
if (pcct_entry->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE &&
!pcc_mbox_ctrl->txdone_irq) {
pr_err("Plaform Interrupt flag must be set to 1");
rc = -EINVAL;
goto err;
}
if (pcc_mbox_ctrl->txdone_irq) {
rc = pcc_parse_subspace_irq(pchan, pcct_entry);
if (rc < 0)
goto err;
}
rc = pcc_parse_subspace_db_reg(pchan, pcct_entry);
if (rc < 0)
goto err;
pcc_parse_subspace_shmem(pchan, pcct_entry);
pcct_entry = (struct acpi_subtable_header *)
((unsigned long) pcct_entry + pcct_entry->length);
}
pcc_mbox_ctrl->num_chans = count;
pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl->num_chans);
pcc_mbox_ctrl->chans = pcc_mbox_channels;
pcc_mbox_ctrl->ops = &pcc_chan_ops;
pcc_mbox_ctrl->dev = dev;
pr_info("Registering PCC driver as Mailbox controller\n");
rc = mbox_controller_register(pcc_mbox_ctrl);
if (rc)
pr_err("Err registering PCC as Mailbox controller: %d\n", rc);
else
return 0;
err:
acpi_put_table(pcct_tbl);
return rc;
}