Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cad4431 authored by Yoichi Yuasa's avatar Yoichi Yuasa Committed by Linus Torvalds
Browse files

rtc-vr41xx: add irq_set_freq() and irq_set_state()



Implement the ioctls RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET and
RTC_IRQP_READ in the standard RTC way.

Thanks Dave for noticing it.

Signed-off-by: default avatarYoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Cc: David Brownell <david-b@pacbell.net>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7e2a31da
Loading
Loading
Loading
Loading
+34 −31
Original line number Diff line number Diff line
/*
 *  Driver for NEC VR4100 series Real Time Clock unit.
 *
 *  Copyright (C) 2003-2006  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
 *  Copyright (C) 2003-2008  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@

MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");

/* RTC 1 registers */
#define ETIMELREG		0x00
@@ -82,7 +82,6 @@ static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */

static DEFINE_SPINLOCK(rtc_lock);
static char rtc_name[] = "RTC";
static unsigned long periodic_frequency;
static unsigned long periodic_count;
static unsigned int alarm_enabled;
static int aie_irq = -1;
@@ -207,10 +206,37 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
	return 0;
}

static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq)
{
	unsigned long count;

	count = RTC_FREQUENCY;
	do_div(count, freq);

	periodic_count = count;

	spin_lock_irq(&rtc_lock);

	rtc1_write(RTCL1LREG, count);
	rtc1_write(RTCL1HREG, count >> 16);

	spin_unlock_irq(&rtc_lock);

	return 0;
}

static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled)
{
	if (enabled)
		enable_irq(pie_irq);
	else
		disable_irq(pie_irq);

	return 0;
}

static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case RTC_AIE_ON:
		spin_lock_irq(&rtc_lock);
@@ -230,33 +256,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
			alarm_enabled = 0;
		}

		spin_unlock_irq(&rtc_lock);
		break;
	case RTC_PIE_ON:
		enable_irq(pie_irq);
		break;
	case RTC_PIE_OFF:
		disable_irq(pie_irq);
		break;
	case RTC_IRQP_READ:
		return put_user(periodic_frequency, (unsigned long __user *)arg);
		break;
	case RTC_IRQP_SET:
		if (arg > MAX_PERIODIC_RATE)
			return -EINVAL;

		periodic_frequency = arg;

		count = RTC_FREQUENCY;
		do_div(count, arg);

		periodic_count = count;

		spin_lock_irq(&rtc_lock);

		rtc1_write(RTCL1LREG, count);
		rtc1_write(RTCL1HREG, count >> 16);

		spin_unlock_irq(&rtc_lock);
		break;
	case RTC_EPOCH_READ:
@@ -309,6 +308,8 @@ static const struct rtc_class_ops vr41xx_rtc_ops = {
	.set_time	= vr41xx_rtc_set_time,
	.read_alarm	= vr41xx_rtc_read_alarm,
	.set_alarm	= vr41xx_rtc_set_alarm,
	.irq_set_freq	= vr41xx_rtc_irq_set_freq,
	.irq_set_state	= vr41xx_rtc_irq_set_state,
};

static int __devinit rtc_probe(struct platform_device *pdev)
@@ -346,6 +347,8 @@ static int __devinit rtc_probe(struct platform_device *pdev)
		goto err_iounmap_all;
	}

	rtc->max_user_freq = MAX_PERIODIC_RATE;

	spin_lock_irq(&rtc_lock);

	rtc1_write(ECMPLREG, 0);