diff options
| -rw-r--r-- | drivers/acpi/cppc_acpi.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 4446fa6c820e..d9ce4b162e2c 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #include <linux/cpufreq.h> | 40 | #include <linux/cpufreq.h> |
| 41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
| 42 | #include <linux/iopoll.h> | ||
| 42 | #include <linux/ktime.h> | 43 | #include <linux/ktime.h> |
| 43 | #include <linux/rwsem.h> | 44 | #include <linux/rwsem.h> |
| 44 | #include <linux/wait.h> | 45 | #include <linux/wait.h> |
| @@ -49,7 +50,7 @@ struct cppc_pcc_data { | |||
| 49 | struct mbox_chan *pcc_channel; | 50 | struct mbox_chan *pcc_channel; |
| 50 | void __iomem *pcc_comm_addr; | 51 | void __iomem *pcc_comm_addr; |
| 51 | bool pcc_channel_acquired; | 52 | bool pcc_channel_acquired; |
| 52 | ktime_t deadline; | 53 | unsigned int deadline_us; |
| 53 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; | 54 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; |
| 54 | 55 | ||
| 55 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ | 56 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ |
| @@ -198,42 +199,31 @@ static struct kobj_type cppc_ktype = { | |||
| 198 | 199 | ||
| 199 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) | 200 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) |
| 200 | { | 201 | { |
| 201 | int ret = -EIO, status = 0; | 202 | int ret, status; |
| 202 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | 203 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; |
| 203 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = | 204 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = |
| 204 | pcc_ss_data->pcc_comm_addr; | 205 | pcc_ss_data->pcc_comm_addr; |
| 205 | ktime_t next_deadline = ktime_add(ktime_get(), | ||
| 206 | pcc_ss_data->deadline); | ||
| 207 | 206 | ||
| 208 | if (!pcc_ss_data->platform_owns_pcc) | 207 | if (!pcc_ss_data->platform_owns_pcc) |
| 209 | return 0; | 208 | return 0; |
| 210 | 209 | ||
| 211 | /* Retry in case the remote processor was too slow to catch up. */ | 210 | /* |
| 212 | while (!ktime_after(ktime_get(), next_deadline)) { | 211 | * Poll PCC status register every 3us(delay_us) for maximum of |
| 213 | /* | 212 | * deadline_us(timeout_us) until PCC command complete bit is set(cond) |
| 214 | * Per spec, prior to boot the PCC space wil be initialized by | 213 | */ |
| 215 | * platform and should have set the command completion bit when | 214 | ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status, |
| 216 | * PCC can be used by OSPM | 215 | status & PCC_CMD_COMPLETE_MASK, 3, |
| 217 | */ | 216 | pcc_ss_data->deadline_us); |
| 218 | status = readw_relaxed(&generic_comm_base->status); | ||
| 219 | if (status & PCC_CMD_COMPLETE_MASK) { | ||
| 220 | ret = 0; | ||
| 221 | if (chk_err_bit && (status & PCC_ERROR_MASK)) | ||
| 222 | ret = -EIO; | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | /* | ||
| 226 | * Reducing the bus traffic in case this loop takes longer than | ||
| 227 | * a few retries. | ||
| 228 | */ | ||
| 229 | udelay(3); | ||
| 230 | } | ||
| 231 | 217 | ||
| 232 | if (likely(!ret)) | 218 | if (likely(!ret)) { |
| 233 | pcc_ss_data->platform_owns_pcc = false; | 219 | pcc_ss_data->platform_owns_pcc = false; |
| 234 | else | 220 | if (chk_err_bit && (status & PCC_ERROR_MASK)) |
| 235 | pr_err("PCC check channel failed for ss: %d. Status=%x\n", | 221 | ret = -EIO; |
| 236 | pcc_ss_id, status); | 222 | } |
| 223 | |||
| 224 | if (unlikely(ret)) | ||
| 225 | pr_err("PCC check channel failed for ss: %d. ret=%d\n", | ||
| 226 | pcc_ss_id, ret); | ||
| 237 | 227 | ||
| 238 | return ret; | 228 | return ret; |
| 239 | } | 229 | } |
| @@ -585,7 +575,7 @@ static int register_pcc_channel(int pcc_ss_idx) | |||
| 585 | * So add an arbitrary amount of wait on top of Nominal. | 575 | * So add an arbitrary amount of wait on top of Nominal. |
| 586 | */ | 576 | */ |
| 587 | usecs_lat = NUM_RETRIES * cppc_ss->latency; | 577 | usecs_lat = NUM_RETRIES * cppc_ss->latency; |
| 588 | pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); | 578 | pcc_data[pcc_ss_idx]->deadline_us = usecs_lat; |
| 589 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; | 579 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; |
| 590 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; | 580 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; |
| 591 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; | 581 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; |
