static void sh_wdt_start(struct sh_wdt *wdt)
{
    unsigned long flags;
    u8 csr;

    spin_lock_irqsave(&shwdt_lock, flags);

    next_heartbeat = jiffies + (heartbeat * HZ);
    mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));

    csr = sh_wdt_read_csr();
    csr |= WTCSR_WT | clock_division_ratio;
    sh_wdt_write_csr(csr);

    sh_wdt_write_cnt(0);

    csr = sh_wdt_read_csr();
    csr |= WTCSR_TME;
    csr &= ~WTCSR_RSTS;
    sh_wdt_write_csr(csr);

#ifdef CONFIG_CPU_SH2
    csr = sh_wdt_read_rstcsr();
    csr &= ~RSTCSR_RSTS;
    sh_wdt_write_rstcsr(csr);
#endif
    spin_unlock_irqrestore(&shwdt_lock, flags);
}
Esempio n. 2
0
/**
 * 	sh_wdt_ping - Ping the Watchdog
 *
 *	@data: Unused
 *
 * 	Clears overflow bit, resets timer counter.
 */
static void sh_wdt_ping(unsigned long data)
{
    if (time_before(jiffies, next_heartbeat)) {
        sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
        sh_wdt_write_cnt(0);

        timer.expires = next_ping_period(clock_division_ratio);
        add_timer(&timer);
    }
}
Esempio n. 3
0
/**
 * 	sh_wdt_start - Start the Watchdog
 *
 * 	Starts the watchdog.
 */
static void sh_wdt_start(void)
{
    timer.expires = next_ping_period(clock_division_ratio);
    next_heartbeat = jiffies + (sh_heartbeat * HZ);
    add_timer(&timer);

    sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096);
    sh_wdt_write_cnt(0);
    sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME));
}
Esempio n. 4
0
File: shwdt.c Progetto: wxlong/Test
/**
 * 	sh_wdt_ping - Ping the Watchdog
 *
 *	@data: Unused
 *
 * 	Clears overflow bit, resets timer counter.
 */
static void sh_wdt_ping(unsigned long data)
{
	if (time_before(jiffies, next_heartbeat)) {
		__u8 csr;

		csr = sh_wdt_read_csr();
		csr &= ~WTCSR_IOVF;
		sh_wdt_write_csr(csr);

		sh_wdt_write_cnt(0);

		mod_timer(&timer, next_ping_period(clock_division_ratio));
	} else {
		printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
	}
}
Esempio n. 5
0
static int sh_wdt_start(struct watchdog_device *wdt_dev)
{
	struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev);
	unsigned long flags;
	u8 csr;

	pm_runtime_get_sync(wdt->dev);
	clk_enable(wdt->clk);

	spin_lock_irqsave(&wdt->lock, flags);

	next_heartbeat = jiffies + (heartbeat * HZ);
	mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));

	csr = sh_wdt_read_csr();
	csr |= WTCSR_WT | clock_division_ratio;
	sh_wdt_write_csr(csr);

	sh_wdt_write_cnt(0);

	/*
	 * These processors have a bit of an inconsistent initialization
	 * process.. starting with SH-3, RSTS was moved to WTCSR, and the
	 * RSTCSR register was removed.
	 *
	 * On the SH-2 however, in addition with bits being in different
	 * locations, we must deal with RSTCSR outright..
	 */
	csr = sh_wdt_read_csr();
	csr |= WTCSR_TME;
	csr &= ~WTCSR_RSTS;
	sh_wdt_write_csr(csr);

#ifdef CONFIG_CPU_SH2
	csr = sh_wdt_read_rstcsr();
	csr &= ~RSTCSR_RSTS;
	sh_wdt_write_rstcsr(csr);
#endif
	spin_unlock_irqrestore(&wdt->lock, flags);

	return 0;
}
Esempio n. 6
0
File: shwdt.c Progetto: wxlong/Test
/**
 * 	sh_wdt_start - Start the Watchdog
 *
 * 	Starts the watchdog.
 */
static void sh_wdt_start(void)
{
	__u8 csr;

	next_heartbeat = jiffies + (heartbeat * HZ);
	mod_timer(&timer, next_ping_period(clock_division_ratio));

	csr = sh_wdt_read_csr();
	csr |= WTCSR_WT | clock_division_ratio;
	sh_wdt_write_csr(csr);

	sh_wdt_write_cnt(0);

	/*
	 * These processors have a bit of an inconsistent initialization
	 * process.. starting with SH-3, RSTS was moved to WTCSR, and the
	 * RSTCSR register was removed.
	 *
	 * On the SH-2 however, in addition with bits being in different
	 * locations, we must deal with RSTCSR outright..
	 */
	csr = sh_wdt_read_csr();
	csr |= WTCSR_TME;
	csr &= ~WTCSR_RSTS;
	sh_wdt_write_csr(csr);

#ifdef CONFIG_CPU_SH2
	/*
	 * Whoever came up with the RSTCSR semantics must've been smoking
	 * some of the good stuff, since in addition to the WTCSR/WTCNT write
	 * brain-damage, it's managed to f**k things up one step further..
	 *
	 * If we need to clear the WOVF bit, the upper byte has to be 0xa5..
	 * but if we want to touch RSTE or RSTS, the upper byte has to be
	 * 0x5a..
	 */
	csr = sh_wdt_read_rstcsr();
	csr &= ~RSTCSR_RSTS;
	sh_wdt_write_rstcsr(csr);
#endif
}
Esempio n. 7
0
static void sh_wdt_ping(unsigned long data)
{
	struct sh_wdt *wdt = (struct sh_wdt *)data;
	unsigned long flags;

	spin_lock_irqsave(&wdt->lock, flags);
	if (time_before(jiffies, next_heartbeat)) {
		u8 csr;

		csr = sh_wdt_read_csr();
		csr &= ~WTCSR_IOVF;
		sh_wdt_write_csr(csr);

		sh_wdt_write_cnt(0);

		mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
	} else
		dev_warn(wdt->dev, "Heartbeat lost! Will not ping "
		         "the watchdog\n");
	spin_unlock_irqrestore(&wdt->lock, flags);
}
Esempio n. 8
0
static int __devinit sh_wdt_probe(struct platform_device *pdev)
{
	struct sh_wdt *wdt;
	struct resource *res;
	int rc;

	/*
	 * As this driver only covers the global watchdog case, reject
	 * any attempts to register per-CPU watchdogs.
	 */
	if (pdev->id != -1)
		return -EINVAL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(!res))
		return -EINVAL;

	wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL);
	if (unlikely(!wdt))
		return -ENOMEM;

	wdt->dev = &pdev->dev;

	wdt->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(wdt->clk)) {
		/*
		 * Clock framework support is optional, continue on
		 * anyways if we don't find a matching clock.
		 */
		wdt->clk = NULL;
	}

	wdt->base = devm_request_and_ioremap(wdt->dev, res);
	if (unlikely(!wdt->base)) {
		rc = -EADDRNOTAVAIL;
		goto err;
	}

	watchdog_set_nowayout(&sh_wdt_dev, nowayout);
	watchdog_set_drvdata(&sh_wdt_dev, wdt);

	spin_lock_init(&wdt->lock);

	rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat);
	if (unlikely(rc)) {
		/* Default timeout if invalid */
		sh_wdt_set_heartbeat(&sh_wdt_dev, WATCHDOG_HEARTBEAT);

		dev_warn(&pdev->dev,
			 "heartbeat value must be 1<=x<=3600, using %d\n",
			 sh_wdt_dev.timeout);
	}

	dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n",
		 sh_wdt_dev.timeout, nowayout);

	rc = watchdog_register_device(&sh_wdt_dev);
	if (unlikely(rc)) {
		dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc);
		goto err;
	}

	init_timer(&wdt->timer);
	wdt->timer.function	= sh_wdt_ping;
	wdt->timer.data		= (unsigned long)wdt;
	wdt->timer.expires	= next_ping_period(clock_division_ratio);

	platform_set_drvdata(pdev, wdt);

	dev_info(&pdev->dev, "initialized.\n");

	pm_runtime_enable(&pdev->dev);

	return 0;

err:
	clk_put(wdt->clk);

	return rc;
}