ACPI: PCC: Setup PCC Opregion handler only if platform interrupt is available
Currently, PCC OpRegion handler depends on the availability of platform interrupt to be functional currently. If it is not available, the OpRegion can't be executed successfully or the desired outcome won't be possible. So let's reject setting up the PCC OpRegion handler on the platform if it doesn't support or have platform interrupt available. Signed-off-by: Huisong Li <lihuisong@huawei.com> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Родитель
8338b74a75
Коммит
a10b1c99e2
|
@ -53,6 +53,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
|||
struct pcc_data *data;
|
||||
struct acpi_pcc_info *ctx = handler_context;
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
static acpi_status ret;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
|
@ -69,23 +70,35 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
|||
if (IS_ERR(data->pcc_chan)) {
|
||||
pr_err("Failed to find PCC channel for subspace %d\n",
|
||||
ctx->subspace_id);
|
||||
kfree(data);
|
||||
return AE_NOT_FOUND;
|
||||
ret = AE_NOT_FOUND;
|
||||
goto err_free_data;
|
||||
}
|
||||
|
||||
pcc_chan = data->pcc_chan;
|
||||
if (!pcc_chan->mchan->mbox->txdone_irq) {
|
||||
pr_err("This channel-%d does not support interrupt.\n",
|
||||
ctx->subspace_id);
|
||||
ret = AE_SUPPORT;
|
||||
goto err_free_channel;
|
||||
}
|
||||
data->pcc_comm_addr = acpi_os_ioremap(pcc_chan->shmem_base_addr,
|
||||
pcc_chan->shmem_size);
|
||||
if (!data->pcc_comm_addr) {
|
||||
pr_err("Failed to ioremap PCC comm region mem for %d\n",
|
||||
ctx->subspace_id);
|
||||
pcc_mbox_free_channel(data->pcc_chan);
|
||||
kfree(data);
|
||||
return AE_NO_MEMORY;
|
||||
ret = AE_NO_MEMORY;
|
||||
goto err_free_channel;
|
||||
}
|
||||
|
||||
*region_context = data;
|
||||
return AE_OK;
|
||||
|
||||
err_free_channel:
|
||||
pcc_mbox_free_channel(data->pcc_chan);
|
||||
err_free_data:
|
||||
kfree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
|
@ -106,19 +119,17 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
|
|||
if (ret < 0)
|
||||
return AE_ERROR;
|
||||
|
||||
if (data->pcc_chan->mchan->mbox->txdone_irq) {
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
|
||||
ret = wait_for_completion_timeout(&data->done,
|
||||
usecs_to_jiffies(usecs_lat));
|
||||
if (ret == 0) {
|
||||
pr_err("PCC command executed timeout!\n");
|
||||
return AE_TIME;
|
||||
}
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
|
||||
ret = wait_for_completion_timeout(&data->done,
|
||||
usecs_to_jiffies(usecs_lat));
|
||||
if (ret == 0) {
|
||||
pr_err("PCC command executed timeout!\n");
|
||||
return AE_TIME;
|
||||
}
|
||||
|
||||
mbox_chan_txdone(data->pcc_chan->mchan, ret);
|
||||
|
|
Загрузка…
Ссылка в новой задаче