static long s3c2410wdt_ioctl(struct file *file,	unsigned int cmd,
							unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_margin;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &s3c2410_wdt_ident,
			sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_KEEPALIVE:
		s3c2410wdt_keepalive();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_margin, p))
			return -EFAULT;
		if (s3c2410wdt_set_heartbeat(new_margin))
			return -EINVAL;
		s3c2410wdt_keepalive();
		return put_user(tmr_margin, p);
	case WDIOC_GETTIMEOUT:
		return put_user(tmr_margin, p);
	default:
		return -ENOTTY;
	}
}
示例#2
0
static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
					  unsigned long val, void *data)
{
	if (!s3c2410wdt_is_running())
		return 0;

	if (val == CPUFREQ_PRECHANGE) {
		/* To ensure that over the change we don't cause the
		 * watchdog to trigger, we perform an keep-alive if
		 * the watchdog is running.
		 */
		s3c2410wdt_keepalive(&s3c2410_wdd);
	} else if (val == CPUFREQ_POSTCHANGE) {
	/* Exynos4 do not change pclk freq after boot, so don't need to do this */
#if !defined (CONFIG_MX_SERIAL_TYPE) && !defined(CONFIG_MX2_SERIAL_TYPE)
		int ret;
		s3c2410wdt_stop(&s3c2410_wdd);
		ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout);
		if (ret >= 0) {
			s3c2410wdt_start(&s3c2410_wdd);
		} else {
			dev_err(wdt_dev, "cannot set new value for timeout %d\n",
				s3c2410_wdd.timeout);
			return ret;
		}
#endif
	}

	return 0;
}
static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
{
	dev_info(wdt_dev, "watchdog timer expired (irq)\n");

	s3c2410wdt_keepalive(&s3c2410_wdd);
	return IRQ_HANDLED;
}
示例#4
0
static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
				size_t len, loff_t *ppos)
{
	/*
	 *	Refresh the timer.
	 */
	if(len) {
		if (!nowayout) {
			size_t i;

			/* In case it was set long ago */
			allow_close = CLOSE_STATE_NOT;

			for (i = 0; i != len; i++) {
				char c;

				if (get_user(c, data + i))
					return -EFAULT;
				if (c == 'V')
					allow_close = CLOSE_STATE_ALLOW;
			}
		}

		s3c2410wdt_keepalive();
	}
	return len;
}
示例#5
0
static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
					  unsigned long val, void *data)
{
	int ret;

	if (!s3c2410wdt_is_running())
		goto done;

	if (val == CPUFREQ_PRECHANGE) {
		/* To ensure that over the change we don't cause the
		 * watchdog to trigger, we perform an keep-alive if
		 * the watchdog is running.
		 */

		s3c2410wdt_keepalive(&s3c2410_wdd);
	} else if (val == CPUFREQ_POSTCHANGE) {
		s3c2410wdt_stop(&s3c2410_wdd);

		ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout);

		if (ret >= 0)
			s3c2410wdt_start(&s3c2410_wdd);
		else
			goto err;
	}

done:
	return 0;

 err:
	dev_err(wdt_dev, "cannot set new value for timeout %d\n",
				s3c2410_wdd.timeout);
	return ret;
}
示例#6
0
static irqreturn_t s3c2410wdt_irq(int irqno, void *param,
				  struct pt_regs *regs)
{
	printk(KERN_INFO PFX "Watchdog timer expired!\n");

	s3c2410wdt_keepalive();
	return IRQ_HANDLED;
}
示例#7
0
static int watchdog_thread(void *data)
{
	pr_info("%s: Enter into watchdog_thread\n", __func__);
	while (1) {
		pr_debug("%s: feed the watchdog\n", __func__);
		s3c2410wdt_keepalive(&s3c2410_wdd);
		schedule_timeout_interruptible(HZ);
	}
	return 0;
}
示例#8
0
static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
{
	dev_info(wdt_dev, "watchdog timer expired (irq)\n");

	s3c2410wdt_keepalive(&s3c2410_wdd);

	/* Clear the interrupt */
	__raw_writel(0xff, wdt_base + S3C2410_WTCLRINT);

	/* Print backtrace of all cpus. */
	handle_sysrq('l');

	return IRQ_HANDLED;
}
示例#9
0
static int watchdog_thread(void *data)
{
	unsigned int keepalive_cycle = tmr_margin / 2;
	pr_info("%s: Enter into watchdog_thread\n", __func__);

	while (1) {
		msleep_interruptible(keepalive_cycle * 1000);

		pr_debug("%s: feed the watchdog\n", __func__);
		s3c2410wdt_keepalive(&s3c2410_wdd);
	}

	return 0;
}
示例#10
0
static int s3c2410wdt_release(struct inode *inode, struct file *file)
{
	/*
	 *	Shut off the timer.
	 * 	Lock it in if it's a module and we set nowayout
	 */
	if (allow_close == CLOSE_STATE_ALLOW) {
		s3c2410wdt_stop();
	} else {
		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
		s3c2410wdt_keepalive();
	}

	allow_close = CLOSE_STATE_NOT;
	up(&open_lock);
	return 0;
}
static int s3c2410wdt_release(struct inode *inode, struct file *file)
{
	/*
	 *	Shut off the timer.
	 * 	Lock it in if it's a module and we set nowayout
	 */

	if (expect_close == 42)
		s3c2410wdt_stop();
	else {
		dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
		s3c2410wdt_keepalive();
	}
	expect_close = 0;
	clear_bit(0, &open_lock);
	return 0;
}
示例#12
0
static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
{
	dev_info(wdt_dev, "watchdog timer expired (irq)\n");
	s3c2410wdt_keepalive(&s3c2410_wdd);

	/* Clear the interrupt */
	s3c2410wdt_int_clear(&s3c2410_wdd);

	/* Print backtrace of all cpus. */
	handle_sysrq('l');

	/* Restart for availability */
	pr_info("%s: emergency reboot\n", __func__);
	emergency_restart();

	return IRQ_HANDLED;
}
示例#13
0
static int 
wdt_thread(void *arg)
{
	int ret = 0;
	int ms = (tmr_margin*1000)>>1;

	DEBG("--- enter WATCHDOG KTHREAD ---\n");
	while (1) {
		// check whether we should exit or not
		if(kthread_should_stop()){
			DEBG("--- WATCHDOG KTHREAD should stop ---\n");
			break;
		}

		s3c2410wdt_keepalive();
		DEBG("--- feed the s3c2410 watchdog before timeout = %d ---\n", tmr_margin);
		msleep(ms);
		
	}
	DEBG("--- exit WATCHDOG KTHREAD ---\n");

	return ret;
}
示例#14
0
void touch_s3c2410wdt(void)
{
	s3c2410wdt_keepalive(&s3c2410_wdd);
}