source: trunk/target/linux/omap24xx/patches-2.6.38/530-cbus-retu-wdt-preemptible.patch @ 25832

Last change on this file since 25832 was 25832, checked in by mb, 6 years ago

cbus-retu-wdt: Some fixes

File size: 3.8 KB
  • drivers/cbus/retu-wdt.c

    old new struct retu_wdt_dev { 
    5858        struct device           *dev; 
    5959        int                     users; 
    6060        struct miscdevice       retu_wdt_miscdev; 
    61         struct timer_list       ping_timer; 
     61        struct delayed_work     ping_work; 
    6262}; 
    6363 
    6464static struct retu_wdt_dev *retu_wdt; 
    6565 
    66 static void retu_wdt_set_ping_timer(unsigned long enable); 
    67  
    6866static int _retu_modify_counter(unsigned int new) 
    6967{ 
    7068        if (retu_wdt) 
    static int retu_modify_counter(unsigned 
    8684        return 0; 
    8785} 
    8886 
     87/* 
     88 * Since retu watchdog cannot be disabled in hardware, we must kick it 
     89 * with a timer until userspace watchdog software takes over. Do this 
     90 * unless /dev/watchdog is open or CONFIG_WATCHDOG_NOWAYOUT is set. 
     91 */ 
     92static void retu_wdt_ping_enable(struct retu_wdt_dev *wdev) 
     93{ 
     94        _retu_modify_counter(RETU_WDT_MAX_TIMER); 
     95        schedule_delayed_work(&wdev->ping_work, 
     96                              round_jiffies_relative(RETU_WDT_DEFAULT_TIMER * HZ)); 
     97} 
     98 
     99static void retu_wdt_ping_disable(struct retu_wdt_dev *wdev) 
     100{ 
     101        _retu_modify_counter(RETU_WDT_MAX_TIMER); 
     102        cancel_delayed_work_sync(&wdev->ping_work); 
     103} 
     104 
     105static void retu_wdt_ping_work(struct work_struct *work) 
     106{ 
     107        struct retu_wdt_dev *wdev = container_of(to_delayed_work(work), 
     108                                        struct retu_wdt_dev, ping_work); 
     109        retu_wdt_ping_enable(wdev); 
     110} 
     111 
    89112static ssize_t retu_wdt_period_show(struct device *dev, 
    90113                                struct device_attribute *attr, char *buf) 
    91114{ 
    static ssize_t retu_wdt_period_store(str 
    105128        int ret; 
    106129 
    107130#ifdef CONFIG_WATCHDOG_NOWAYOUT 
    108         retu_wdt_set_ping_timer(0); 
     131        retu_wdt_ping_disable(retu_wdt); 
    109132#endif 
    110133 
    111134        if (sscanf(buf, "%u", &new_period) != 1) { 
    static DEVICE_ATTR(period, S_IRUGO | S_I 
    136159                        retu_wdt_period_store); 
    137160static DEVICE_ATTR(counter, S_IRUGO, retu_wdt_counter_show, NULL); 
    138161 
    139 /*----------------------------------------------------------------------------*/ 
    140  
    141 /* 
    142  * Since retu watchdog cannot be disabled in hardware, we must kick it 
    143  * with a timer until userspace watchdog software takes over. Do this 
    144  * unless /dev/watchdog is open or CONFIG_WATCHDOG_NOWAYOUT is set. 
    145  */ 
    146 static void retu_wdt_set_ping_timer(unsigned long enable) 
    147 { 
    148         _retu_modify_counter(RETU_WDT_MAX_TIMER); 
    149         if (enable) 
    150                 mod_timer(&retu_wdt->ping_timer, 
    151                                 jiffies + RETU_WDT_DEFAULT_TIMER * HZ); 
    152         else 
    153                 del_timer_sync(&retu_wdt->ping_timer); 
    154 } 
    155  
    156162static int retu_wdt_open(struct inode *inode, struct file *file) 
    157163{ 
    158164        if (test_and_set_bit(1, (unsigned long *)&(retu_wdt->users))) 
    159165                return -EBUSY; 
    160166 
    161167        file->private_data = (void *)retu_wdt; 
    162         retu_wdt_set_ping_timer(0); 
     168        retu_wdt_ping_disable(retu_wdt); 
    163169 
    164170        return nonseekable_open(inode, file); 
    165171} 
    static int retu_wdt_release(struct inode 
    169175        struct retu_wdt_dev *wdev = file->private_data; 
    170176 
    171177#ifndef CONFIG_WATCHDOG_NOWAYOUT 
    172         retu_wdt_set_ping_timer(1); 
     178        retu_wdt_ping_enable(retu_wdt); 
    173179#endif 
    174180        wdev->users = 0; 
    175181 
    static int __devinit retu_wdt_ping(void) 
    232238#ifdef CONFIG_WATCHDOG_NOWAYOUT 
    233239        retu_modify_counter(RETU_WDT_MAX_TIMER); 
    234240#else 
    235         retu_wdt_set_ping_timer(1); 
     241        retu_wdt_ping_enable(retu_wdt); 
    236242#endif 
    237243 
    238244        return 0; 
    static int __init retu_wdt_probe(struct 
    283289        if (ret) 
    284290                goto free3; 
    285291 
    286         setup_timer(&wdev->ping_timer, retu_wdt_set_ping_timer, 1); 
     292        INIT_DELAYED_WORK(&wdev->ping_work, retu_wdt_ping_work); 
    287293 
    288294        /* passed as module parameter? */ 
    289295        ret = retu_modify_counter(counter_param); 
    static int __devexit retu_wdt_remove(str 
    326332        misc_deregister(&wdev->retu_wdt_miscdev); 
    327333        device_remove_file(&pdev->dev, &dev_attr_period); 
    328334        device_remove_file(&pdev->dev, &dev_attr_counter); 
     335        cancel_delayed_work_sync(&wdev->ping_work); 
    329336        kfree(wdev); 
    330337 
    331338        return 0; 
Note: See TracBrowser for help on using the repository browser.