summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/ioc4.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 3336ddca45ac..8758d033db23 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -144,9 +144,9 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
144{ 144{
145 union ioc4_int_out int_out; 145 union ioc4_int_out int_out;
146 union ioc4_gpcr gpcr; 146 union ioc4_gpcr gpcr;
147 unsigned int state, last_state = 1; 147 unsigned int state, last_state;
148 uint64_t start, end, period; 148 uint64_t start, end, period;
149 unsigned int count = 0; 149 unsigned int count;
150 150
151 /* Enable output */ 151 /* Enable output */
152 gpcr.raw = 0; 152 gpcr.raw = 0;
@@ -167,19 +167,20 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
167 mmiowb(); 167 mmiowb();
168 168
169 /* Check square wave period averaged over some number of cycles */ 169 /* Check square wave period averaged over some number of cycles */
170 do { 170 start = ktime_get_ns();
171 int_out.raw = readl(&idd->idd_misc_regs->int_out.raw); 171 state = 1; /* make sure the first read isn't a rising edge */
172 state = int_out.fields.int_out; 172 for (count = 0; count <= IOC4_CALIBRATE_END; count++) {
173 if (!last_state && state) { 173 do { /* wait for a rising edge */
174 count++; 174 last_state = state;
175 if (count == IOC4_CALIBRATE_END) { 175 int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
176 end = ktime_get_ns(); 176 state = int_out.fields.int_out;
177 break; 177 } while (last_state || !state);
178 } else if (count == IOC4_CALIBRATE_DISCARD) 178
179 start = ktime_get_ns(); 179 /* discard the first few cycles */
180 } 180 if (count == IOC4_CALIBRATE_DISCARD)
181 last_state = state; 181 start = ktime_get_ns();
182 } while (1); 182 }
183 end = ktime_get_ns();
183 184
184 /* Calculation rearranged to preserve intermediate precision. 185 /* Calculation rearranged to preserve intermediate precision.
185 * Logically: 186 * Logically: