aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/cppc_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/cppc_acpi.c')
-rw-r--r--drivers/acpi/cppc_acpi.c48
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
199static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) 200static 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;