Esempio n. 1
0
static int __init bfin_wdt_init(void)
{
	int ret;

	stampit();

	/* Check that the timeout value is within range */
	if (bfin_wdt_set_timeout(timeout))
		return -EINVAL;

	/* Since this is an on-chip device and needs no board-specific
	 * resources, we'll handle all the platform device stuff here.
	 */
	ret = platform_driver_register(&bfin_wdt_driver);
	if (ret) {
		pr_init(KERN_ERR PFX "unable to register driver\n");
		return ret;
	}

	bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME,
								-1, NULL, 0);
	if (IS_ERR(bfin_wdt_device)) {
		pr_init(KERN_ERR PFX "unable to register device\n");
		platform_driver_unregister(&bfin_wdt_driver);
		return PTR_ERR(bfin_wdt_device);
	}

	return 0;
}
Esempio n. 2
0
static void
update_timestamp(in_addr_t host)
{
	int	i;

	if (dt_table == NULL) {
		return;
	}

	for (i = 0 ; i < dt_table->size ; ++i) {
		if (dt_table->entry[i].host == 0) {
			/*
			 * at the last entry. this host was not found.
			 */
			break;
		}

		if (dt_table->entry[i].host == host) {
			dt_table->entry[i].timestamp = stampit();
			break;
		}
	}

	return;
}
Esempio n. 3
0
static int __init bfin_wdt_init(void)
{
	int ret;

	stampit();

	/*                                              */
	if (bfin_wdt_set_timeout(timeout))
		return -EINVAL;

	/*                                                            
                                                               
  */
	ret = platform_driver_register(&bfin_wdt_driver);
	if (ret) {
		pr_err("unable to register driver\n");
		return ret;
	}

	bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME,
								-1, NULL, 0);
	if (IS_ERR(bfin_wdt_device)) {
		pr_err("unable to register device\n");
		platform_driver_unregister(&bfin_wdt_driver);
		return PTR_ERR(bfin_wdt_device);
	}

	return 0;
}
Esempio n. 4
0
static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
						size_t len, loff_t *ppos)
{
	stampit();

	if (len) {
		if (!nowayout) {
			size_t i;

			/* In case it was set long ago */
			expect_close = 0;

			for (i = 0; i != len; i++) {
				char c;
				if (get_user(c, data + i))
					return -EFAULT;
				if (c == 'V')
					expect_close = 42;
			}
		}
		bfin_wdt_keepalive();
	}

	return len;
}
Esempio n. 5
0
static int bfin_wdt_set_timeout(unsigned long t)
{
	u32 cnt;
	unsigned long flags;

	stampit();

	cnt = t * get_sclk();
	if (cnt < get_sclk()) {
		printk(KERN_WARNING PFX "timeout value is too large\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&bfin_wdt_spinlock, flags);
	{
		int run = bfin_wdt_running();
		bfin_wdt_stop();
		bfin_write_WDOG_CNT(cnt);
		if (run)
			bfin_wdt_start();
	}
	spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);

	timeout = t;

	return 0;
}
Esempio n. 6
0
static int bfin_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
	stampit();

	state_before_suspend = bfin_wdt_running();
	bfin_wdt_stop();

	return 0;
}
Esempio n. 7
0
static int bfin_wdt_resume(struct platform_device *pdev)
{
	stampit();

	if (state_before_suspend) {
		bfin_wdt_set_timeout(timeout);
		bfin_wdt_start();
	}

	return 0;
}
Esempio n. 8
0
static long bfin_wdt_ioctl(struct file *file,
				unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;

	stampit();

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
			return -EFAULT;
		else
			return 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
	case WDIOC_SETOPTIONS: {
		unsigned long flags;
		int options, ret = -EINVAL;

		if (get_user(options, p))
			return -EFAULT;

		spin_lock_irqsave(&bfin_wdt_spinlock, flags);
		if (options & WDIOS_DISABLECARD) {
			bfin_wdt_stop();
			ret = 0;
		}
		if (options & WDIOS_ENABLECARD) {
			bfin_wdt_start();
			ret = 0;
		}
		spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
		return ret;
	}
	case WDIOC_KEEPALIVE:
		bfin_wdt_keepalive();
		return 0;
	case WDIOC_SETTIMEOUT: {
		int new_timeout;

		if (get_user(new_timeout, p))
			return -EFAULT;
		if (bfin_wdt_set_timeout(new_timeout))
			return -EINVAL;
	}
	/* Fall */
	case WDIOC_GETTIMEOUT:
		return put_user(timeout, p);
	default:
		return -ENOTTY;
	}
}
Esempio n. 9
0
/**
 *	bfin_otp_write - write OTP pages
 *
 *	All writes must be in half page chunks (half page == 64 bits).
 */
static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos)
{
	ssize_t bytes_done;
	u32 timing, page, base_flags, flags, ret;
	u64 content;

	if (!allow_writes)
		return -EACCES;

	if (count % sizeof(u64))
		return -EMSGSIZE;

	if (mutex_lock_interruptible(&bfin_otp_lock))
		return -ERESTARTSYS;

	stampit();

	timing = bfin_otp_init_timing();
	if (timing == 0) {
		mutex_unlock(&bfin_otp_lock);
		return -EIO;
	}

	base_flags = OTP_CHECK_FOR_PREV_WRITE;

	bytes_done = 0;
	page = *pos / (sizeof(u64) * 2);
	while (bytes_done < count) {
		flags = base_flags | (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
		stamp("processing page %i (0x%x:%s) from %p", page, flags,
			(flags & OTP_UPPER_HALF ? "upper" : "lower"), buff + bytes_done);
		if (copy_from_user(&content, buff + bytes_done, sizeof(content))) {
			bytes_done = -EFAULT;
			break;
		}
		ret = bfrom_OtpWrite(page, flags, &content);
		if (ret & OTP_MASTER_ERROR) {
			stamp("error from otp: 0x%x", ret);
			bytes_done = -EIO;
			break;
		}
		if (flags & OTP_UPPER_HALF)
			++page;
		bytes_done += sizeof(content);
		*pos += sizeof(content);
	}

	bfin_otp_deinit_timing(timing);

	mutex_unlock(&bfin_otp_lock);

	return bytes_done;
}
Esempio n. 10
0
static int bfin_wdt_release(struct inode *inode, struct file *file)
{
	stampit();

	if (expect_close == 42)
		bfin_wdt_stop();
	else {
		pr_crit("Unexpected close, not stopping watchdog!\n");
		bfin_wdt_keepalive();
	}
	expect_close = 0;
	clear_bit(0, &open_check);
	return 0;
}
Esempio n. 11
0
static int bfin_wdt_open(struct inode *inode, struct file *file)
{
	stampit();

	if (test_and_set_bit(0, &open_check))
		return -EBUSY;

	if (nowayout)
		__module_get(THIS_MODULE);

	bfin_wdt_keepalive();
	bfin_wdt_start();

	return nonseekable_open(inode, file);
}
Esempio n. 12
0
/**
 *	bfin_otp_init - Initialize module
 *
 *	Registers the device and notifier handler. Actual device
 *	initialization is handled by bfin_otp_open().
 */
static int __init bfin_otp_init(void)
{
	int ret;

	stampit();

	ret = misc_register(&bfin_otp_misc_device);
	if (ret) {
		pr_init(KERN_ERR PFX "unable to register a misc device\n");
		return ret;
	}

	pr_init(KERN_INFO PFX "initialized\n");

	return 0;
}
Esempio n. 13
0
/**
 *	bfin_otp_write - Write OTP pages
 *
 *	All writes must be in half page chunks (half page == 64 bits).
 */
static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos)
{
	stampit();

	if (count % sizeof(u64))
		return -EMSGSIZE;

	if (mutex_lock_interruptible(&bfin_otp_lock))
		return -ERESTARTSYS;

	/* need otp_init() documentation before this can be implemented */

	mutex_unlock(&bfin_otp_lock);

	return -EINVAL;
}
Esempio n. 14
0
static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
{
	stampit();

	switch (cmd) {
	case OTPLOCK: {
		u32 timing;
		int ret = -EIO;

		if (!allow_writes)
			return -EACCES;

		if (mutex_lock_interruptible(&bfin_otp_lock))
			return -ERESTARTSYS;

		timing = bfin_otp_init_timing();
		if (timing) {
			u32 otp_result = bfrom_OtpWrite(arg, OTP_LOCK, NULL);
			stamp("locking page %lu resulted in 0x%x", arg, otp_result);
			if (!(otp_result & OTP_MASTER_ERROR))
				ret = 0;

			bfin_otp_deinit_timing(timing);
		}

		mutex_unlock(&bfin_otp_lock);

		return ret;
	}

	case MEMLOCK:
		allow_writes = false;
		return 0;

	case MEMUNLOCK:
		allow_writes = true;
		return 0;
	}

	return -EINVAL;
}
Esempio n. 15
0
/**
 *	bfin_otp_read - Read OTP pages
 *
 *	All reads must be in half page chunks (half page == 64 bits).
 */
static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, loff_t *pos)
{
	ssize_t bytes_done;
	u32 page, flags, ret;
	u64 content;

	stampit();

	if (count % sizeof(u64))
		return -EMSGSIZE;

	if (mutex_lock_interruptible(&bfin_otp_lock))
		return -ERESTARTSYS;

	bytes_done = 0;
	page = *pos / (sizeof(u64) * 2);
	while (bytes_done < count) {
		flags = (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
		stamp("processing page %i (0x%x:%s)", page, flags,
			(flags & OTP_UPPER_HALF ? "upper" : "lower"));
		ret = bfrom_OtpRead(page, flags, &content);
		if (ret & OTP_MASTER_ERROR) {
			stamp("error from otp: 0x%x", ret);
			bytes_done = -EIO;
			break;
		}
		if (copy_to_user(buff + bytes_done, &content, sizeof(content))) {
			bytes_done = -EFAULT;
			break;
		}
		if (flags & OTP_UPPER_HALF)
			++page;
		bytes_done += sizeof(content);
		*pos += sizeof(content);
	}

	mutex_unlock(&bfin_otp_lock);

	return bytes_done;
}
Esempio n. 16
0
static int bfin_wdt_keepalive(void)
{
	stampit();
	bfin_write_WDOG_STAT(0);
	return 0;
}
Esempio n. 17
0
/**
 *	bfin_otp_exit - Deinitialize module
 *
 *	Unregisters the device and notifier handler. Actual device
 *	deinitialization is handled by bfin_otp_close().
 */
static void __exit bfin_otp_exit(void)
{
	stampit();

	misc_deregister(&bfin_otp_misc_device);
}
Esempio n. 18
0
static void bfin_wdt_shutdown(struct platform_device *pdev)
{
	stampit();

	bfin_wdt_stop();
}
Esempio n. 19
0
static int bfin_wdt_stop(void)
{
	stampit();
	bfin_write_WDOG_CTL(WDEN_DISABLE);
	return 0;
}
Esempio n. 20
0
static int bfin_wdt_start(void)
{
	stampit();
	bfin_write_WDOG_CTL(WDEN_ENABLE | ICTL_RESET);
	return 0;
}
Esempio n. 21
0
static int bfin_wdt_running(void)
{
	stampit();
	return ((bfin_read_WDOG_CTL() & WDEN_MASK) != WDEN_DISABLE);
}