Skip to content

Commit fff2d0f

Browse files
arndbgroeck
authored andcommitted
hwmon: (applesmc) avoid overlong udelay()
Building this driver with "clang -O3" produces a link error after the compiler partially unrolls the loop and 256ms becomes a compile-time constant that triggers the check in udelay(): ld.lld: error: undefined symbol: __bad_udelay >>> referenced by applesmc.c >>> hwmon/applesmc.o:(read_smc) in archive drivers/built-in.a I can see no reason against using a sleeping function here, as no part of the driver runs in atomic context, so instead use usleep_range() with a wide range and use jiffies for the end condition. Signed-off-by: Arnd Bergmann <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]>
1 parent 156ad7f commit fff2d0f

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

drivers/hwmon/applesmc.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,19 @@ static struct workqueue_struct *applesmc_led_wq;
156156
*/
157157
static int wait_read(void)
158158
{
159+
unsigned long end = jiffies + (APPLESMC_MAX_WAIT * HZ) / USEC_PER_SEC;
159160
u8 status;
160161
int us;
162+
161163
for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
162-
udelay(us);
164+
usleep_range(us, us * 16);
163165
status = inb(APPLESMC_CMD_PORT);
164166
/* read: wait for smc to settle */
165167
if (status & 0x01)
166168
return 0;
169+
/* timeout: give up */
170+
if (time_after(jiffies, end))
171+
break;
167172
}
168173

169174
pr_warn("wait_read() fail: 0x%02x\n", status);
@@ -178,10 +183,11 @@ static int send_byte(u8 cmd, u16 port)
178183
{
179184
u8 status;
180185
int us;
186+
unsigned long end = jiffies + (APPLESMC_MAX_WAIT * HZ) / USEC_PER_SEC;
181187

182188
outb(cmd, port);
183189
for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
184-
udelay(us);
190+
usleep_range(us, us * 16);
185191
status = inb(APPLESMC_CMD_PORT);
186192
/* write: wait for smc to settle */
187193
if (status & 0x02)
@@ -190,7 +196,7 @@ static int send_byte(u8 cmd, u16 port)
190196
if (status & 0x04)
191197
return 0;
192198
/* timeout: give up */
193-
if (us << 1 == APPLESMC_MAX_WAIT)
199+
if (time_after(jiffies, end))
194200
break;
195201
/* busy: long wait and resend */
196202
udelay(APPLESMC_RETRY_WAIT);

0 commit comments

Comments
 (0)