4646#define DS1374_REG_WDALM2 0x06
4747#define DS1374_REG_CR 0x07 /* Control */
4848#define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */
49+ #define DS1374_REG_CR_WDSTR 0x08 /* 1=INT, 0=RST */
4950#define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */
5051#define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */
5152#define DS1374_REG_SR 0x08 /* Status */
@@ -71,7 +72,9 @@ struct ds1374 {
7172 struct i2c_client * client ;
7273 struct rtc_device * rtc ;
7374 struct work_struct work ;
74-
75+ #ifdef CONFIG_RTC_DRV_DS1374_WDT
76+ struct watchdog_device wdt ;
77+ #endif
7578 /* The mutex protects alarm operations, and prevents a race
7679 * between the enable_irq() in the workqueue and the free_irq()
7780 * in the remove function.
@@ -369,238 +372,98 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
369372 *
370373 *****************************************************************************
371374 */
372- static struct i2c_client * save_client ;
373375/* Default margin */
374- #define WD_TIMO 131762
376+ #define TIMER_MARGIN_DEFAULT 32
377+ #define TIMER_MARGIN_MIN 1
378+ #define TIMER_MARGIN_MAX 4095 /* 24-bit value */
375379
376380#define DRV_NAME "DS1374 Watchdog"
377381
378- static int wdt_margin = WD_TIMO ;
379- static unsigned long wdt_is_open ;
382+ static int wdt_margin ;
380383module_param (wdt_margin , int , 0 );
381384MODULE_PARM_DESC (wdt_margin , "Watchdog timeout in seconds (default 32s)" );
382385
386+ static bool nowayout = WATCHDOG_NOWAYOUT ;
387+ module_param (nowayout , bool , 0 );
388+ MODULE_PARM_DESC (nowayout , "Watchdog cannot be stopped once started (default ="
389+ __MODULE_STRING (WATCHDOG_NOWAYOUT )")" );
390+
383391static const struct watchdog_info ds1374_wdt_info = {
384392 .identity = "DS1374 WTD" ,
385393 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
386394 WDIOF_MAGICCLOSE ,
387395};
388396
389- static int ds1374_wdt_settimeout (unsigned int timeout )
397+ static int ds1374_wdt_settimeout (struct watchdog_device * wdt , unsigned int timeout )
390398{
391- int ret = - ENOIOCTLCMD ;
392- int cr ;
399+ struct ds1374 * ds1374 = watchdog_get_drvdata (wdt );
400+ struct i2c_client * client = ds1374 -> client ;
401+ int ret , cr ;
393402
394- ret = cr = i2c_smbus_read_byte_data (save_client , DS1374_REG_CR );
395- if (ret < 0 )
396- goto out ;
403+ wdt -> timeout = timeout ;
404+
405+ cr = i2c_smbus_read_byte_data (client , DS1374_REG_CR );
406+ if (cr < 0 )
407+ return cr ;
397408
398409 /* Disable any existing watchdog/alarm before setting the new one */
399410 cr &= ~DS1374_REG_CR_WACE ;
400411
401- ret = i2c_smbus_write_byte_data (save_client , DS1374_REG_CR , cr );
412+ ret = i2c_smbus_write_byte_data (client , DS1374_REG_CR , cr );
402413 if (ret < 0 )
403- goto out ;
414+ return ret ;
404415
405416 /* Set new watchdog time */
406- ret = ds1374_write_rtc (save_client , timeout , DS1374_REG_WDALM0 , 3 );
407- if (ret ) {
408- pr_info ("couldn't set new watchdog time\n" );
409- goto out ;
410- }
417+ timeout = timeout * 4096 ;
418+ ret = ds1374_write_rtc (client , timeout , DS1374_REG_WDALM0 , 3 );
419+ if (ret )
420+ return ret ;
411421
412422 /* Enable watchdog timer */
413423 cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM ;
424+ cr &= ~DS1374_REG_CR_WDSTR ;/* for RST PIN */
414425 cr &= ~DS1374_REG_CR_AIE ;
415426
416- ret = i2c_smbus_write_byte_data (save_client , DS1374_REG_CR , cr );
427+ ret = i2c_smbus_write_byte_data (client , DS1374_REG_CR , cr );
417428 if (ret < 0 )
418- goto out ;
429+ return ret ;
419430
420431 return 0 ;
421- out :
422- return ret ;
423432}
424433
425-
426434/*
427435 * Reload the watchdog timer. (ie, pat the watchdog)
428436 */
429- static void ds1374_wdt_ping ( void )
437+ static int ds1374_wdt_start ( struct watchdog_device * wdt )
430438{
439+ struct ds1374 * ds1374 = watchdog_get_drvdata (wdt );
431440 u32 val ;
432- int ret = 0 ;
433441
434- ret = ds1374_read_rtc (save_client , & val , DS1374_REG_WDALM0 , 3 );
435- if (ret )
436- pr_info ("WD TICK FAIL!!!!!!!!!! %i\n" , ret );
442+ return ds1374_read_rtc (ds1374 -> client , & val , DS1374_REG_WDALM0 , 3 );
437443}
438444
439- static void ds1374_wdt_disable ( void )
445+ static int ds1374_wdt_stop ( struct watchdog_device * wdt )
440446{
447+ struct ds1374 * ds1374 = watchdog_get_drvdata (wdt );
448+ struct i2c_client * client = ds1374 -> client ;
441449 int cr ;
442450
443- cr = i2c_smbus_read_byte_data (save_client , DS1374_REG_CR );
451+ cr = i2c_smbus_read_byte_data (client , DS1374_REG_CR );
452+ if (cr < 0 )
453+ return cr ;
454+
444455 /* Disable watchdog timer */
445456 cr &= ~DS1374_REG_CR_WACE ;
446457
447- i2c_smbus_write_byte_data (save_client , DS1374_REG_CR , cr );
448- }
449-
450- /*
451- * Watchdog device is opened, and watchdog starts running.
452- */
453- static int ds1374_wdt_open (struct inode * inode , struct file * file )
454- {
455- struct ds1374 * ds1374 = i2c_get_clientdata (save_client );
456-
457- if (MINOR (inode -> i_rdev ) == WATCHDOG_MINOR ) {
458- mutex_lock (& ds1374 -> mutex );
459- if (test_and_set_bit (0 , & wdt_is_open )) {
460- mutex_unlock (& ds1374 -> mutex );
461- return - EBUSY ;
462- }
463- /*
464- * Activate
465- */
466- wdt_is_open = 1 ;
467- mutex_unlock (& ds1374 -> mutex );
468- return stream_open (inode , file );
469- }
470- return - ENODEV ;
471- }
472-
473- /*
474- * Close the watchdog device.
475- */
476- static int ds1374_wdt_release (struct inode * inode , struct file * file )
477- {
478- if (MINOR (inode -> i_rdev ) == WATCHDOG_MINOR )
479- clear_bit (0 , & wdt_is_open );
480-
481- return 0 ;
458+ return i2c_smbus_write_byte_data (client , DS1374_REG_CR , cr );
482459}
483460
484- /*
485- * Pat the watchdog whenever device is written to.
486- */
487- static ssize_t ds1374_wdt_write (struct file * file , const char __user * data ,
488- size_t len , loff_t * ppos )
489- {
490- if (len ) {
491- ds1374_wdt_ping ();
492- return 1 ;
493- }
494- return 0 ;
495- }
496-
497- static ssize_t ds1374_wdt_read (struct file * file , char __user * data ,
498- size_t len , loff_t * ppos )
499- {
500- return 0 ;
501- }
502-
503- /*
504- * Handle commands from user-space.
505- */
506- static long ds1374_wdt_ioctl (struct file * file , unsigned int cmd ,
507- unsigned long arg )
508- {
509- int new_margin , options ;
510-
511- switch (cmd ) {
512- case WDIOC_GETSUPPORT :
513- return copy_to_user ((struct watchdog_info __user * )arg ,
514- & ds1374_wdt_info , sizeof (ds1374_wdt_info )) ? - EFAULT : 0 ;
515-
516- case WDIOC_GETSTATUS :
517- case WDIOC_GETBOOTSTATUS :
518- return put_user (0 , (int __user * )arg );
519- case WDIOC_KEEPALIVE :
520- ds1374_wdt_ping ();
521- return 0 ;
522- case WDIOC_SETTIMEOUT :
523- if (get_user (new_margin , (int __user * )arg ))
524- return - EFAULT ;
525-
526- /* the hardware's tick rate is 4096 Hz, so
527- * the counter value needs to be scaled accordingly
528- */
529- new_margin <<= 12 ;
530- if (new_margin < 1 || new_margin > 16777216 )
531- return - EINVAL ;
532-
533- wdt_margin = new_margin ;
534- ds1374_wdt_settimeout (new_margin );
535- ds1374_wdt_ping ();
536- /* fallthrough */
537- case WDIOC_GETTIMEOUT :
538- /* when returning ... inverse is true */
539- return put_user ((wdt_margin >> 12 ), (int __user * )arg );
540- case WDIOC_SETOPTIONS :
541- if (copy_from_user (& options , (int __user * )arg , sizeof (int )))
542- return - EFAULT ;
543-
544- if (options & WDIOS_DISABLECARD ) {
545- pr_info ("disable watchdog\n" );
546- ds1374_wdt_disable ();
547- return 0 ;
548- }
549-
550- if (options & WDIOS_ENABLECARD ) {
551- pr_info ("enable watchdog\n" );
552- ds1374_wdt_settimeout (wdt_margin );
553- ds1374_wdt_ping ();
554- return 0 ;
555- }
556- return - EINVAL ;
557- }
558- return - ENOTTY ;
559- }
560-
561- static long ds1374_wdt_unlocked_ioctl (struct file * file , unsigned int cmd ,
562- unsigned long arg )
563- {
564- int ret ;
565- struct ds1374 * ds1374 = i2c_get_clientdata (save_client );
566-
567- mutex_lock (& ds1374 -> mutex );
568- ret = ds1374_wdt_ioctl (file , cmd , arg );
569- mutex_unlock (& ds1374 -> mutex );
570-
571- return ret ;
572- }
573-
574- static int ds1374_wdt_notify_sys (struct notifier_block * this ,
575- unsigned long code , void * unused )
576- {
577- if (code == SYS_DOWN || code == SYS_HALT )
578- /* Disable Watchdog */
579- ds1374_wdt_disable ();
580- return NOTIFY_DONE ;
581- }
582-
583- static const struct file_operations ds1374_wdt_fops = {
584- .owner = THIS_MODULE ,
585- .read = ds1374_wdt_read ,
586- .unlocked_ioctl = ds1374_wdt_unlocked_ioctl ,
587- .compat_ioctl = compat_ptr_ioctl ,
588- .write = ds1374_wdt_write ,
589- .open = ds1374_wdt_open ,
590- .release = ds1374_wdt_release ,
591- .llseek = no_llseek ,
592- };
593-
594- static struct miscdevice ds1374_miscdev = {
595- .minor = WATCHDOG_MINOR ,
596- .name = "watchdog" ,
597- .fops = & ds1374_wdt_fops ,
598- };
599-
600- static struct notifier_block ds1374_wdt_notifier = {
601- .notifier_call = ds1374_wdt_notify_sys ,
461+ static const struct watchdog_ops ds1374_wdt_ops = {
462+ .owner = THIS_MODULE ,
463+ .start = ds1374_wdt_start ,
464+ .stop = ds1374_wdt_stop ,
465+ .set_timeout = ds1374_wdt_settimeout ,
602466};
603-
604467#endif /*CONFIG_RTC_DRV_DS1374_WDT*/
605468/*
606469 *****************************************************************************
@@ -652,16 +515,22 @@ static int ds1374_probe(struct i2c_client *client,
652515 return ret ;
653516
654517#ifdef CONFIG_RTC_DRV_DS1374_WDT
655- save_client = client ;
656- ret = misc_register (& ds1374_miscdev );
518+ ds1374 -> wdt .info = & ds1374_wdt_info ;
519+ ds1374 -> wdt .ops = & ds1374_wdt_ops ;
520+ ds1374 -> wdt .timeout = TIMER_MARGIN_DEFAULT ;
521+ ds1374 -> wdt .min_timeout = TIMER_MARGIN_MIN ;
522+ ds1374 -> wdt .max_timeout = TIMER_MARGIN_MAX ;
523+
524+ watchdog_init_timeout (& ds1374 -> wdt , wdt_margin , & client -> dev );
525+ watchdog_set_nowayout (& ds1374 -> wdt , nowayout );
526+ watchdog_stop_on_reboot (& ds1374 -> wdt );
527+ watchdog_stop_on_unregister (& ds1374 -> wdt );
528+ watchdog_set_drvdata (& ds1374 -> wdt , ds1374 );
529+ ds1374_wdt_settimeout (& ds1374 -> wdt , ds1374 -> wdt .timeout );
530+
531+ ret = devm_watchdog_register_device (& client -> dev , & ds1374 -> wdt );
657532 if (ret )
658533 return ret ;
659- ret = register_reboot_notifier (& ds1374_wdt_notifier );
660- if (ret ) {
661- misc_deregister (& ds1374_miscdev );
662- return ret ;
663- }
664- ds1374_wdt_settimeout (131072 );
665534#endif
666535
667536 return 0 ;
@@ -670,11 +539,6 @@ static int ds1374_probe(struct i2c_client *client,
670539static int ds1374_remove (struct i2c_client * client )
671540{
672541 struct ds1374 * ds1374 = i2c_get_clientdata (client );
673- #ifdef CONFIG_RTC_DRV_DS1374_WDT
674- misc_deregister (& ds1374_miscdev );
675- ds1374_miscdev .parent = NULL ;
676- unregister_reboot_notifier (& ds1374_wdt_notifier );
677- #endif
678542
679543 if (client -> irq > 0 ) {
680544 mutex_lock (& ds1374 -> mutex );
0 commit comments