Beispiel #1
0
Datei: wdt.c Projekt: jhbsz/102
irqreturn_t ath_wdt_isr(int cpl, void *dev_id)
{
	unsigned delay;
	extern int ath_gpio_in_val(int);

#define UDELAY_COUNT 4000

	wddbg("%s: invoked\n", __func__);

	for (delay = UDELAY_COUNT; delay; delay--) {
		if (ath_gpio_in_val(ATH_GPIO_RESET)) {
			break;
		}
		udelay(1000);
	}

	wddbg("%s: %d", __func__, delay);

	if (!delay) {
		wake_up(&wdt->wq);
	} else {
		extern void ath_restart(char *);
		ath_restart(NULL);
	}
	return IRQ_HANDLED;
}
Beispiel #2
0
static int
ar7240wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		unsigned long arg)
{
	int ret = 0;

	wddbg("%s: called\n", __func__);

	switch(cmd) {
		case FACTORY_RESET:
			wddbg("%s: intr action\n", __func__);
#ifndef CONFIG_MACH_HORNET
			if ((ret = request_irq(
					AR7240_MISC_IRQ_WATCHDOG,
					ar7240_wdt_isr,
					0,
					"Watchdog Timer",
					wdt))) {
				wddbg("%s: request_irq %d\n", __func__, ret);
				return ret;
			}

			ar7240_set_wd_timer_action(AR7240_WD_ACT_GP_INTR);
			sleep_on(&wdt->wq);
			free_irq(AR7240_MISC_IRQ_WATCHDOG, wdt);
#endif
			break;

		default: ret = -EINVAL;
	}

	return ret;
}
Beispiel #3
0
FAR void *watchdog_register(FAR const char *path,
                            FAR struct watchdog_lowerhalf_s *lower)
{
  FAR struct watchdog_upperhalf_s *upper;
  int ret;

  DEBUGASSERT(path && lower);
  wdvdbg("Entry: path=%s\n", path);

  /* Allocate the upper-half data structure */

  upper = (FAR struct watchdog_upperhalf_s *)
    kzalloc(sizeof(struct watchdog_upperhalf_s));
  if (!upper)
    {
      wddbg("Upper half allocation failed\n");
      goto errout;
    }

  /* Initialize the watchdog timer device structure (it was already zeroed
   * by kzalloc()).
   */

  sem_init(&upper->exclsem, 0, 1);
  upper->lower = lower;

  /* Copy the registration path */

  upper->path = strdup(path);
  if (!upper->path)
    {
      wddbg("Path allocation failed\n");
      goto errout_with_upper;
    }

  /* Register the watchdog timer device */

  ret = register_driver(path, &g_wdogops, 0666, upper);
  if (ret < 0)
    {
      wddbg("register_driver failed: %d\n", ret);
      goto errout_with_path;
    }

  return (FAR void *)upper;

errout_with_path:
  kfree(upper->path);

errout_with_upper:
  sem_destroy(&upper->exclsem);
  kfree(upper);

errout:
  return NULL;
}
Beispiel #4
0
static ssize_t
ar7240wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
	int i;
	char c;

	wddbg("%s: called\n", __func__);

	for (i = 0; i != count; i++) {
		if (get_user(c, buf + i)) {
			return -EFAULT;
		}

		if (c == 'V') {
			wdt->can_close = 1;
			break;
		}
	}

	if (i) {
		ar7240_set_wd_timer(wdt->tmo);
		return 1;
	}

	return 0;
}
Beispiel #5
0
static ssize_t
ar7240wdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
	wddbg("%s: called\n", __func__);

	return -ENOTSUPP;
}
Beispiel #6
0
static int
ar7240wdt_open(struct inode *inode, struct file *file)
{
	wddbg("%s: called\n", __func__);

	if (MINOR(inode->i_rdev) != WATCHDOG_MINOR) {
		return -ENODEV;
	}

	if (wdt->open) {
		return -EBUSY;
	}

	wdt->open = 1;
	wdt->tmo = AR7240_DEFAULT_WD_TMO;
	wdt->action = AR7240_WD_ACT_NONE;
	wdt->can_close = 0;
	init_waitqueue_head(&wdt->wq);

	ar7240_set_wd_timer(wdt->tmo);
#ifndef CONFIG_MACH_HORNET
	ar7240_set_wd_timer_action(AR7240_WD_ACT_NONE);
#endif
	return nonseekable_open(inode, file);
}
Beispiel #7
0
Datei: wdt.c Projekt: jhbsz/102
/* Set the timeout value in the watchdog register */
void ath_set_wd_timer(uint32_t usec /* micro seconds */)
{
#if defined(CONFIG_MACH_QCA956x)
        uint32_t vTmpusec = 0;
        uint32_t vCnt = 0;
#endif
#if defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_QCA955x) || \
    defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x)
	usec = usec * (ath_ref_freq / USEC_PER_SEC);
#else
	usec = usec * (ath_ahb_freq / USEC_PER_SEC);
#endif

	wddbg("%s: 0x%08x\n", __func__, usec);

#if defined(CONFIG_MACH_QCA956x)
        //EV[131847], wait WDT timer write in( wait limit time )
        vTmpusec = ath_reg_rd(ATH_WATCHDOG_TMR);
        ath_reg_wr(ATH_WATCHDOG_TMR, usec);

        while(ath_reg_rd(ATH_WATCHDOG_TMR) <= vTmpusec)
        {
            vCnt++;
            if(vCnt >= 100)
            {
                 printk("%s: Write WDT Timer fail !\n",__func__);
                 break;
            }
        }
#else
	ath_reg_wr(ATH_WATCHDOG_TMR, usec);
#endif
		
}
Beispiel #8
0
Datei: wdt.c Projekt: jhbsz/102
static int athwdt_close(struct inode *inode, struct file *file)
{
	wddbg("%s: called\n", __func__);

	if (MINOR(inode->i_rdev) != WATCHDOG_MINOR) {
		return -ENODEV;
	}

	if (!wdt->can_close) {
		wddbg("%s: clearing action\n", __func__);
		ath_set_wd_timer_action(ATH_WD_ACT_NONE);
	} else {
		wddbg("%s: not clearing action\n", __func__);
	}
	wdt->open = 0;
	return 0;
}
Beispiel #9
0
/* Set the timeout value in the watchdog register */
static inline void
ar7240_set_wd_timer(uint32_t usec /* micro seconds */)
{
	usec = usec * (wdt->clk_freq / USEC_PER_SEC);

	wddbg("%s: 0x%08x\n", __func__, usec);

	ar7240_reg_wr(AR7240_WATCHDOG_TMR, usec);
}
Beispiel #10
0
static int
ar7240wdt_close(struct inode *inode, struct file *file)
{
	wddbg("%s: called\n", __func__);

	if (MINOR(inode->i_rdev) != WATCHDOG_MINOR) {
		return -ENODEV;
	}

	if (!wdt->can_close) {
		wddbg("%s: clearing action\n", __func__);
#ifndef CONFIG_MACH_HORNET
		ar7240_set_wd_timer_action(AR7240_WD_ACT_NONE);
#endif
	} else {
		wddbg("%s: not clearing action\n", __func__);
	}
	wdt->open = 0;
	return 0;
}
Beispiel #11
0
irqreturn_t ar7240_wdt_isr(int cpl, void *dev_id, struct pt_regs *regs)
{
	unsigned delay;
	extern int ar7240_gpio_in_val(int);

#define UDELAY_COUNT 4000

	wddbg("%s: invoked\n", __func__);
#ifdef CONFIG_MACH_HORNET
    local_irq_disable();
#endif
	for (delay = UDELAY_COUNT; delay; delay--) {
		if (ar7240_gpio_in_val(AR7240_GPIO_RESET)) {
			break;
		}
		udelay(1000);
	}

	wddbg("%s: %d", __func__, delay);

	if (!delay) {
#ifdef CONFIG_MACH_HORNET
#ifdef AP_WATCHDOG_RESET_DISABLE
        ar7240_set_wd_timer(wdt->tmo);
        ar7240_set_wd_timer_action(AR7240_WD_ACT_RESET);
        udelay(100);
#endif
        ar7240_set_wd_timer(0);
#else
		wake_up(&wdt->wq);
#endif
	} else {
#ifdef CONFIG_MACH_HORNET
        local_irq_enable();
#else
		extern void ar7240_restart(char *);
		ar7240_restart(NULL);
#endif
	}
	return IRQ_HANDLED;
}
Beispiel #12
0
static inline int
ar7240_set_wd_timer_action(uint32_t val)
{
	if (val & ~AR7240_WD_ACT_MASK) {
		return EINVAL;
	}

	wdt->action = val;

	wddbg("%s: 0x%08x\n", __func__, val);
	/*
	 * bits  : 31 30 - 2 0-1
	 * access: RO  rsvd  Action
	 *
	 * Since bit 31 is read only and rest of the bits
	 * are zero, don't have to do a read-modify-write
	 */
	ar7240_reg_wr(AR7240_WATCHDOG_TMR_CONTROL, val);
	return 0;
}
Beispiel #13
0
void
ar7240wdt_init(void)
{
	int ret;
	extern void ar7240_gpio_config_input(int);

	printk("%s: Registering WDT ", __func__);
	if ((ret = misc_register(&ar7240wdt_miscdev))) {
		printk("failed %d\n", ret);
		return;
	} else {
		printk("success\n");
	}

#ifdef CONFIG_WASP_SUPPORT
	wdt->clk_freq = ath_ref_clk_freq;
#else
	wdt->clk_freq = ar7240_ahb_freq;
#endif

#ifdef CONFIG_MACH_HORNET
   	wdt->tmo = AR7240_DEFAULT_WD_TMO;
    ar7240_set_wd_timer(wdt->tmo * 6);
    ar7240_set_wd_timer_action(AR7240_WD_ACT_RESET);
    mod_timer(&wd_timer, AR7240_DEFAULT_MOD_TMO);

    if (request_irq(
        AR7240_GPIO_IRQn(AR7240_GPIO_RESET),
        ar7240_wdt_isr,
        0,
        "Watchdog Reset",
        wdt)) {
        wddbg("%s: request_irq %d\n", __func__, ret);
    }
#endif
	ar7240_gpio_config_input(AR7240_GPIO_RESET);
}