Example #1
0
static int coh901327_suspend(struct platform_device *pdev, pm_message_t state)
{
	irqmaskstore = readw(virtbase + U300_WDOG_IMR) & 0x0001U;
	wdogenablestore = readw(virtbase + U300_WDOG_D2R);
	/* If watchdog is on, disable it here and now */
	if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED)
		coh901327_disable();
	return 0;
}
Example #2
0
static int __exit coh901327_remove(struct platform_device *pdev)
{
	watchdog_unregister_device(&coh901327_wdt);
	coh901327_disable();
	free_irq(irq, pdev);
	clk_disable_unprepare(clk);
	clk_put(clk);
	return 0;
}
static int __exit coh901327_remove(struct platform_device *pdev)
{
	watchdog_unregister_device(&coh901327_wdt);
	coh901327_disable();
	free_irq(irq, pdev);
	clk_put(clk);
	iounmap(virtbase);
	release_mem_region(phybase, physize);
	return 0;
}
Example #4
0
static long coh901327_ioctl(struct file *file, unsigned int cmd,
			    unsigned long arg)
{
	int ret = -ENOTTY;
	u16 val;
	int time;
	int new_options;
	union {
		struct watchdog_info __user *ident;
		int __user *i;
	} uarg;
	static const struct watchdog_info ident = {
		.options		= WDIOF_CARDRESET |
					  WDIOF_SETTIMEOUT |
					  WDIOF_KEEPALIVEPING,
		.identity		= "COH 901 327 Watchdog",
		.firmware_version	= 1,
	};
	uarg.i = (int __user *)arg;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		ret = copy_to_user(uarg.ident, &ident,
				   sizeof(ident)) ? -EFAULT : 0;
		break;

	case WDIOC_GETSTATUS:
		ret = put_user(0, uarg.i);
		break;

	case WDIOC_GETBOOTSTATUS:
		ret = put_user(boot_status, uarg.i);
		break;

	case WDIOC_SETOPTIONS:
		ret = get_user(new_options, uarg.i);
		if (ret)
			break;
		if (new_options & WDIOS_DISABLECARD)
			coh901327_disable();
		if (new_options & WDIOS_ENABLECARD)
			coh901327_start();
		ret = 0;
		break;

	case WDIOC_KEEPALIVE:
		coh901327_keepalive();
		ret = 0;
		break;

	case WDIOC_SETTIMEOUT:
		ret = get_user(time, uarg.i);
		if (ret)
			break;

		ret = coh901327_settimeout(time);
		if (ret)
			break;
		/* Then fall through to return set value */

	case WDIOC_GETTIMEOUT:
		ret = put_user(margin, uarg.i);
		break;

	case WDIOC_GETTIMELEFT:
		clk_enable(clk);
		/* Read repeatedly until the value is stable! */
		val = readw(virtbase + U300_WDOG_CR);
		while (val & U300_WDOG_CR_VALID_IND)
			val = readw(virtbase + U300_WDOG_CR);
		val &= U300_WDOG_CR_COUNT_VALUE_MASK;
		clk_disable(clk);
		if (val != 0)
			val /= 100;
		ret = put_user(val, uarg.i);
		break;
	}
	return ret;
}

static const struct file_operations coh901327_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= coh901327_write,
	.unlocked_ioctl	= coh901327_ioctl,
	.open		= coh901327_open,
	.release	= coh901327_release,
};

static struct miscdevice coh901327_miscdev = {
	.minor		= WATCHDOG_MINOR,
	.name		= "watchdog",
	.fops		= &coh901327_fops,
};

static int __exit coh901327_remove(struct platform_device *pdev)
{
	misc_deregister(&coh901327_miscdev);
	coh901327_disable();
	free_irq(irq, pdev);
	clk_put(clk);
	iounmap(virtbase);
	release_mem_region(phybase, physize);
	return 0;
}


static int __init coh901327_probe(struct platform_device *pdev)
{
	int ret;
	u16 val;
	struct resource *res;

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

	parent = &pdev->dev;
	physize = resource_size(res);
	phybase = res->start;

	if (request_mem_region(phybase, physize, DRV_NAME) == NULL) {
		ret = -EBUSY;
		goto out;
	}

	virtbase = ioremap(phybase, physize);
	if (!virtbase) {
		ret = -ENOMEM;
		goto out_no_remap;
	}

	clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(&pdev->dev, "could not get clock\n");
		goto out_no_clk;
	}
	ret = clk_enable(clk);
	if (ret) {
		dev_err(&pdev->dev, "could not enable clock\n");
		goto out_no_clk_enable;
	}

	val = readw(virtbase + U300_WDOG_SR);
	switch (val) {
	case U300_WDOG_SR_STATUS_TIMED_OUT:
		dev_info(&pdev->dev,
			"watchdog timed out since last chip reset!\n");
		boot_status = WDIOF_CARDRESET;
		/* Status will be cleared below */
		break;
	case U300_WDOG_SR_STATUS_NORMAL:
		dev_info(&pdev->dev,
			"in normal status, no timeouts have occurred.\n");
		break;
	default:
		dev_info(&pdev->dev,
			"contains an illegal status code (%08x)\n", val);
		break;
	}

	val = readw(virtbase + U300_WDOG_D2R);
	switch (val) {
	case U300_WDOG_D2R_DISABLE_STATUS_DISABLED:
		dev_info(&pdev->dev, "currently disabled.\n");
		break;
	case U300_WDOG_D2R_DISABLE_STATUS_ENABLED:
		dev_info(&pdev->dev,
			 "currently enabled! (disabling it now)\n");
		coh901327_disable();
		break;
	default:
		dev_err(&pdev->dev,
			"contains an illegal enable/disable code (%08x)\n",
			val);
		break;
	}

	/* Reset the watchdog */
	writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR);

	irq = platform_get_irq(pdev, 0);
	if (request_irq(irq, coh901327_interrupt, IRQF_DISABLED,
			DRV_NAME " Bark", pdev)) {
		ret = -EIO;
		goto out_no_irq;
	}

	clk_disable(clk);

	ret = misc_register(&coh901327_miscdev);
	if (ret == 0)
		dev_info(&pdev->dev,
			 "initialized. timer margin=%d sec\n", margin);
	else
		goto out_no_wdog;

	return 0;

out_no_wdog:
	free_irq(irq, pdev);
out_no_irq:
	clk_disable(clk);
out_no_clk_enable:
	clk_put(clk);
out_no_clk:
	iounmap(virtbase);
out_no_remap:
	release_mem_region(phybase, SZ_4K);
out:
	return ret;
}
Example #5
0
static int coh901327_release(struct inode *inode, struct file *file)
{
	clear_bit(1, &coh901327_users);
	coh901327_disable();
	return 0;
}
static int __init coh901327_probe(struct platform_device *pdev)
{
	int ret;
	u16 val;
	struct resource *res;

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

	parent = &pdev->dev;
	physize = resource_size(res);
	phybase = res->start;

	if (request_mem_region(phybase, physize, DRV_NAME) == NULL) {
		ret = -EBUSY;
		goto out;
	}

	virtbase = ioremap(phybase, physize);
	if (!virtbase) {
		ret = -ENOMEM;
		goto out_no_remap;
	}

	clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(&pdev->dev, "could not get clock\n");
		goto out_no_clk;
	}
	ret = clk_enable(clk);
	if (ret) {
		dev_err(&pdev->dev, "could not enable clock\n");
		goto out_no_clk_enable;
	}

	val = readw(virtbase + U300_WDOG_SR);
	switch (val) {
	case U300_WDOG_SR_STATUS_TIMED_OUT:
		dev_info(&pdev->dev,
			"watchdog timed out since last chip reset!\n");
		coh901327_wdt.bootstatus |= WDIOF_CARDRESET;
		/* Status will be cleared below */
		break;
	case U300_WDOG_SR_STATUS_NORMAL:
		dev_info(&pdev->dev,
			"in normal status, no timeouts have occurred.\n");
		break;
	default:
		dev_info(&pdev->dev,
			"contains an illegal status code (%08x)\n", val);
		break;
	}

	val = readw(virtbase + U300_WDOG_D2R);
	switch (val) {
	case U300_WDOG_D2R_DISABLE_STATUS_DISABLED:
		dev_info(&pdev->dev, "currently disabled.\n");
		break;
	case U300_WDOG_D2R_DISABLE_STATUS_ENABLED:
		dev_info(&pdev->dev,
			 "currently enabled! (disabling it now)\n");
		coh901327_disable();
		break;
	default:
		dev_err(&pdev->dev,
			"contains an illegal enable/disable code (%08x)\n",
			val);
		break;
	}

	/* Reset the watchdog */
	writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR);

	irq = platform_get_irq(pdev, 0);
	if (request_irq(irq, coh901327_interrupt, 0,
			DRV_NAME " Bark", pdev)) {
		ret = -EIO;
		goto out_no_irq;
	}

	clk_disable(clk);

	if (margin < 1 || margin > 327)
		margin = 60;
	coh901327_wdt.timeout = margin;

	ret = watchdog_register_device(&coh901327_wdt);
	if (ret == 0)
		dev_info(&pdev->dev,
			 "initialized. timer margin=%d sec\n", margin);
	else
		goto out_no_wdog;

	return 0;

out_no_wdog:
	free_irq(irq, pdev);
out_no_irq:
	clk_disable(clk);
out_no_clk_enable:
	clk_put(clk);
out_no_clk:
	iounmap(virtbase);
out_no_remap:
	release_mem_region(phybase, SZ_4K);
out:
	return ret;
}
static int coh901327_stop(struct watchdog_device *wdt_dev)
{
	coh901327_disable();
	return 0;
}
Example #8
0
static int __init coh901327_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret;
	u16 val;
	struct resource *res;

	parent = dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	virtbase = devm_ioremap_resource(dev, res);
	if (IS_ERR(virtbase))
		return PTR_ERR(virtbase);

	clk = clk_get(dev, NULL);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(dev, "could not get clock\n");
		return ret;
	}
	ret = clk_prepare_enable(clk);
	if (ret) {
		dev_err(dev, "could not prepare and enable clock\n");
		goto out_no_clk_enable;
	}

	val = readw(virtbase + U300_WDOG_SR);
	switch (val) {
	case U300_WDOG_SR_STATUS_TIMED_OUT:
		dev_info(dev, "watchdog timed out since last chip reset!\n");
		coh901327_wdt.bootstatus |= WDIOF_CARDRESET;
		/* Status will be cleared below */
		break;
	case U300_WDOG_SR_STATUS_NORMAL:
		dev_info(dev, "in normal status, no timeouts have occurred.\n");
		break;
	default:
		dev_info(dev, "contains an illegal status code (%08x)\n", val);
		break;
	}

	val = readw(virtbase + U300_WDOG_D2R);
	switch (val) {
	case U300_WDOG_D2R_DISABLE_STATUS_DISABLED:
		dev_info(dev, "currently disabled.\n");
		break;
	case U300_WDOG_D2R_DISABLE_STATUS_ENABLED:
		dev_info(dev, "currently enabled! (disabling it now)\n");
		coh901327_disable();
		break;
	default:
		dev_err(dev, "contains an illegal enable/disable code (%08x)\n",
			val);
		break;
	}

	/* Reset the watchdog */
	writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR);

	irq = platform_get_irq(pdev, 0);
	if (request_irq(irq, coh901327_interrupt, 0,
			DRV_NAME " Bark", pdev)) {
		ret = -EIO;
		goto out_no_irq;
	}

	watchdog_init_timeout(&coh901327_wdt, margin, dev);

	coh901327_wdt.parent = dev;
	ret = watchdog_register_device(&coh901327_wdt);
	if (ret)
		goto out_no_wdog;

	dev_info(dev, "initialized. (timeout=%d sec)\n",
			coh901327_wdt.timeout);
	return 0;

out_no_wdog:
	free_irq(irq, pdev);
out_no_irq:
	clk_disable_unprepare(clk);
out_no_clk_enable:
	clk_put(clk);
	return ret;
}