void reset() { mec_reset(); uart_irq_start(); wdog_start(); }
/* Initializes the controller */ void controller_init( void ) { /* initialize variables */ flag_check_delay = 0; flag_new_request = 0; /* clear data structures */ memset( &javiator_data, 0, sizeof( javiator_data ) ); /* initialize hardware */ ports_init( ); wdog_init( ); //adc_init( ); parallel_init( ); bmu09a_init( ); lsm215_init( ); //minia_init( ); leds_init( ); /* register watchdog event and start timer */ wdog_register_flag( (uint8_t *) &flag_check_delay, NOTIFY_PERIOD ); wdog_start( ); #if 0 /* register ADC channels */ adc_add_channel( ADC_CH_SONAR ); adc_add_channel( ADC_CH_BATT ); #endif /* set Robostix signal LEDs */ LED_ON( RED ); LED_ON( BLUE ); LED_ON( YELLOW ); /* enable interrupts */ sei( ); }
/* Initializes the controller */ void controller_init( void ) { /* initialize variables */ flag_shut_down = 1; flag_check_delay = 0; flag_new_signals = 0; flag_new_sensors = 0; /* clear data structures */ memset( &javiator_data, 0, sizeof( javiator_data ) ); memset( &motor_signals, 0, sizeof( motor_signals ) ); /* initialize hardware */ ports_init( ); wdog_init( ); adc_init( ); serial_init( ); //parallel_init( ); dm3gx1_init( ); minia_init( ); pwm_init( ); leds_init( ); /* register watchdog event and start timer */ wdog_register_flag( (uint8_t *) &flag_check_delay, NOTIFY_PERIOD ); wdog_start( ); /* set Robostix signal LEDs */ LED_ON( RED ); LED_ON( BLUE ); LED_ON( YELLOW ); /* enable interrupts */ sei( ); }
static void wdog_ping(void) { wdog_start(wdog_ticks); }
static long wdog_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; int new_heartbeat; int status; int options; uint32_t remaining; struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT| WDIOF_MAGICCLOSE| WDIOF_KEEPALIVEPING, .firmware_version = 1, .identity = "BCM2708", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: status = wdog_get_status(); return put_user(status, p); case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: wdog_ping(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (wdog_set_heartbeat(new_heartbeat)) return -EINVAL; wdog_ping(); /* Fall */ case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); case WDIOC_GETTIMELEFT: remaining = WDOG_TICKS_TO_SECS(wdog_get_remaining()); return put_user(remaining, p); case WDIOC_SETOPTIONS: if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) wdog_stop(); if (options & WDIOS_ENABLECARD) wdog_start(wdog_ticks); return 0; default: return -ENOTTY; } } /** * @inode: inode of device * @file: file handle to device * * The watchdog device has been opened. The watchdog device is single * open and on opening we load the counters. */ static int wdog_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &wdog_is_open)) return -EBUSY; /* * Activate */ wdog_start(wdog_ticks); return nonseekable_open(inode, file); } /** * @inode: inode to board * @file: file handle to board * * The watchdog has a configurable API. There is a religious dispute * between people who want their watchdog to be able to shut down and * those who want to be sure if the watchdog manager dies the machine * reboots. In the former case we disable the counters, in the latter * case you have to open it again very soon. */ static int wdog_release(struct inode *inode, struct file *file) { if (expect_close == 42) { wdog_stop(); } else { printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); wdog_ping(); } clear_bit(0, &wdog_is_open); expect_close = 0; return 0; } /** * @this: our notifier block * @code: the event being reported * @unused: unused * * Our notifier is called on system shutdowns. Turn the watchdog * off so that it does not fire during the next reboot. */ static int wdog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdog_stop(); return NOTIFY_DONE; } /* * Kernel Interfaces */ static const struct file_operations wdog_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wdog_write, .unlocked_ioctl = wdog_ioctl, .open = wdog_open, .release = wdog_release, }; static struct miscdevice wdog_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdog_fops, }; /* * The WDT card needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdog_notifier = { .notifier_call = wdog_notify_sys, }; /** * cleanup_module: * * Unload the watchdog. You cannot do this with any file handles open. * If your watchdog is set to continue ticking on close and you unload * it, well it keeps ticking. We won't get the interrupt but the board * will not touch PC memory so all is fine. You just have to load a new * module in 60 seconds or reboot. */ static void __exit wdog_exit(void) { misc_deregister(&wdog_miscdev); unregister_reboot_notifier(&wdog_notifier); } static int __init wdog_init(void) { int ret; /* Check that the heartbeat value is within it's range; if not reset to the default */ if (wdog_set_heartbeat(heartbeat)) { wdog_set_heartbeat(WD_TIMO); printk(KERN_INFO "bcm2708_wdog: heartbeat value must be " "0 < heartbeat < %d, using %d\n", WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET), WD_TIMO); } ret = register_reboot_notifier(&wdog_notifier); if (ret) { printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret); goto out_reboot; } ret = misc_register(&wdog_miscdev); if (ret) { printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto out_misc; } printk(KERN_INFO "bcm2708 watchdog, heartbeat=%d sec (nowayout=%d)\n", heartbeat, nowayout); return 0; out_misc: unregister_reboot_notifier(&wdog_notifier); out_reboot: return ret; }