diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1374.c')
-rw-r--r-- | drivers/rtc/rtc-ds1374.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 1f0007fd4431..e6e71deb188f 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/bcd.h> | 25 | #include <linux/bcd.h> |
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/pm.h> | ||
28 | 29 | ||
29 | #define DS1374_REG_TOD0 0x00 /* Time of Day */ | 30 | #define DS1374_REG_TOD0 0x00 /* Time of Day */ |
30 | #define DS1374_REG_TOD1 0x01 | 31 | #define DS1374_REG_TOD1 0x01 |
@@ -307,42 +308,25 @@ unlock: | |||
307 | mutex_unlock(&ds1374->mutex); | 308 | mutex_unlock(&ds1374->mutex); |
308 | } | 309 | } |
309 | 310 | ||
310 | static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 311 | static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled) |
311 | { | 312 | { |
312 | struct i2c_client *client = to_i2c_client(dev); | 313 | struct i2c_client *client = to_i2c_client(dev); |
313 | struct ds1374 *ds1374 = i2c_get_clientdata(client); | 314 | struct ds1374 *ds1374 = i2c_get_clientdata(client); |
314 | int ret = -ENOIOCTLCMD; | 315 | int ret; |
315 | 316 | ||
316 | mutex_lock(&ds1374->mutex); | 317 | mutex_lock(&ds1374->mutex); |
317 | 318 | ||
318 | switch (cmd) { | 319 | ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); |
319 | case RTC_AIE_OFF: | 320 | if (ret < 0) |
320 | ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); | 321 | goto out; |
321 | if (ret < 0) | ||
322 | goto out; | ||
323 | |||
324 | ret &= ~DS1374_REG_CR_WACE; | ||
325 | |||
326 | ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); | ||
327 | if (ret < 0) | ||
328 | goto out; | ||
329 | |||
330 | break; | ||
331 | |||
332 | case RTC_AIE_ON: | ||
333 | ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); | ||
334 | if (ret < 0) | ||
335 | goto out; | ||
336 | 322 | ||
323 | if (enabled) { | ||
337 | ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; | 324 | ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; |
338 | ret &= ~DS1374_REG_CR_WDALM; | 325 | ret &= ~DS1374_REG_CR_WDALM; |
339 | 326 | } else { | |
340 | ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); | 327 | ret &= ~DS1374_REG_CR_WACE; |
341 | if (ret < 0) | ||
342 | goto out; | ||
343 | |||
344 | break; | ||
345 | } | 328 | } |
329 | ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); | ||
346 | 330 | ||
347 | out: | 331 | out: |
348 | mutex_unlock(&ds1374->mutex); | 332 | mutex_unlock(&ds1374->mutex); |
@@ -354,7 +338,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = { | |||
354 | .set_time = ds1374_set_time, | 338 | .set_time = ds1374_set_time, |
355 | .read_alarm = ds1374_read_alarm, | 339 | .read_alarm = ds1374_read_alarm, |
356 | .set_alarm = ds1374_set_alarm, | 340 | .set_alarm = ds1374_set_alarm, |
357 | .ioctl = ds1374_ioctl, | 341 | .alarm_irq_enable = ds1374_alarm_irq_enable, |
358 | }; | 342 | }; |
359 | 343 | ||
360 | static int ds1374_probe(struct i2c_client *client, | 344 | static int ds1374_probe(struct i2c_client *client, |
@@ -417,7 +401,7 @@ static int __devexit ds1374_remove(struct i2c_client *client) | |||
417 | mutex_unlock(&ds1374->mutex); | 401 | mutex_unlock(&ds1374->mutex); |
418 | 402 | ||
419 | free_irq(client->irq, client); | 403 | free_irq(client->irq, client); |
420 | flush_scheduled_work(); | 404 | cancel_work_sync(&ds1374->work); |
421 | } | 405 | } |
422 | 406 | ||
423 | rtc_device_unregister(ds1374->rtc); | 407 | rtc_device_unregister(ds1374->rtc); |
@@ -426,32 +410,38 @@ static int __devexit ds1374_remove(struct i2c_client *client) | |||
426 | } | 410 | } |
427 | 411 | ||
428 | #ifdef CONFIG_PM | 412 | #ifdef CONFIG_PM |
429 | static int ds1374_suspend(struct i2c_client *client, pm_message_t state) | 413 | static int ds1374_suspend(struct device *dev) |
430 | { | 414 | { |
415 | struct i2c_client *client = to_i2c_client(dev); | ||
416 | |||
431 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) | 417 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) |
432 | enable_irq_wake(client->irq); | 418 | enable_irq_wake(client->irq); |
433 | return 0; | 419 | return 0; |
434 | } | 420 | } |
435 | 421 | ||
436 | static int ds1374_resume(struct i2c_client *client) | 422 | static int ds1374_resume(struct device *dev) |
437 | { | 423 | { |
424 | struct i2c_client *client = to_i2c_client(dev); | ||
425 | |||
438 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) | 426 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) |
439 | disable_irq_wake(client->irq); | 427 | disable_irq_wake(client->irq); |
440 | return 0; | 428 | return 0; |
441 | } | 429 | } |
430 | |||
431 | static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume); | ||
432 | |||
433 | #define DS1374_PM (&ds1374_pm) | ||
442 | #else | 434 | #else |
443 | #define ds1374_suspend NULL | 435 | #define DS1374_PM NULL |
444 | #define ds1374_resume NULL | ||
445 | #endif | 436 | #endif |
446 | 437 | ||
447 | static struct i2c_driver ds1374_driver = { | 438 | static struct i2c_driver ds1374_driver = { |
448 | .driver = { | 439 | .driver = { |
449 | .name = "rtc-ds1374", | 440 | .name = "rtc-ds1374", |
450 | .owner = THIS_MODULE, | 441 | .owner = THIS_MODULE, |
442 | .pm = DS1374_PM, | ||
451 | }, | 443 | }, |
452 | .probe = ds1374_probe, | 444 | .probe = ds1374_probe, |
453 | .suspend = ds1374_suspend, | ||
454 | .resume = ds1374_resume, | ||
455 | .remove = __devexit_p(ds1374_remove), | 445 | .remove = __devexit_p(ds1374_remove), |
456 | .id_table = ds1374_id, | 446 | .id_table = ds1374_id, |
457 | }; | 447 | }; |