Skip to content

Commit a10b1c9

Browse files
LiHuiSong1rafaeljw
authored andcommitted
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 <[email protected]> Reviewed-by: Sudeep Holla <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 8338b74 commit a10b1c9

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

drivers/acpi/acpi_pcc.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
5353
struct pcc_data *data;
5454
struct acpi_pcc_info *ctx = handler_context;
5555
struct pcc_mbox_chan *pcc_chan;
56+
static acpi_status ret;
5657

5758
data = kzalloc(sizeof(*data), GFP_KERNEL);
5859
if (!data)
@@ -69,23 +70,35 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
6970
if (IS_ERR(data->pcc_chan)) {
7071
pr_err("Failed to find PCC channel for subspace %d\n",
7172
ctx->subspace_id);
72-
kfree(data);
73-
return AE_NOT_FOUND;
73+
ret = AE_NOT_FOUND;
74+
goto err_free_data;
7475
}
7576

7677
pcc_chan = data->pcc_chan;
78+
if (!pcc_chan->mchan->mbox->txdone_irq) {
79+
pr_err("This channel-%d does not support interrupt.\n",
80+
ctx->subspace_id);
81+
ret = AE_SUPPORT;
82+
goto err_free_channel;
83+
}
7784
data->pcc_comm_addr = acpi_os_ioremap(pcc_chan->shmem_base_addr,
7885
pcc_chan->shmem_size);
7986
if (!data->pcc_comm_addr) {
8087
pr_err("Failed to ioremap PCC comm region mem for %d\n",
8188
ctx->subspace_id);
82-
pcc_mbox_free_channel(data->pcc_chan);
83-
kfree(data);
84-
return AE_NO_MEMORY;
89+
ret = AE_NO_MEMORY;
90+
goto err_free_channel;
8591
}
8692

8793
*region_context = data;
8894
return AE_OK;
95+
96+
err_free_channel:
97+
pcc_mbox_free_channel(data->pcc_chan);
98+
err_free_data:
99+
kfree(data);
100+
101+
return ret;
89102
}
90103

91104
static acpi_status
@@ -106,19 +119,17 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
106119
if (ret < 0)
107120
return AE_ERROR;
108121

109-
if (data->pcc_chan->mchan->mbox->txdone_irq) {
110-
/*
111-
* pcc_chan->latency is just a Nominal value. In reality the remote
112-
* processor could be much slower to reply. So add an arbitrary
113-
* amount of wait on top of Nominal.
114-
*/
115-
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
116-
ret = wait_for_completion_timeout(&data->done,
117-
usecs_to_jiffies(usecs_lat));
118-
if (ret == 0) {
119-
pr_err("PCC command executed timeout!\n");
120-
return AE_TIME;
121-
}
122+
/*
123+
* pcc_chan->latency is just a Nominal value. In reality the remote
124+
* processor could be much slower to reply. So add an arbitrary
125+
* amount of wait on top of Nominal.
126+
*/
127+
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
128+
ret = wait_for_completion_timeout(&data->done,
129+
usecs_to_jiffies(usecs_lat));
130+
if (ret == 0) {
131+
pr_err("PCC command executed timeout!\n");
132+
return AE_TIME;
122133
}
123134

124135
mbox_chan_txdone(data->pcc_chan->mchan, ret);

0 commit comments

Comments
 (0)