* [PATCH 01/10] RTC subsystem, DS1672 oscillator handling
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 02/10] RTC subsystem, DS1672 cleanup Alessandro Zummo
` (9 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Kumar Gala
[-- Attachment #1: rtc-subsys-ds1672-fix-osc.patch --]
[-- Type: text/plain, Size: 3706 bytes --]
From: Kumar Gala <galak@kernel.crashing.org>
* Always enable the oscillator when we set the time
* If the oscillator is disable when we probe the RTC report back a warning
to the user
* Added sysfs attribute to represent the state of the oscillator
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
---
commit 3acc1a4629e70bce7493b5463f3c785379ae8b6b
tree 34463406603ac788697d8d228a2caf2c0ea40b3a
parent 329b10bb0feacb7fb9a41389313ff0a51ae56f2a
author Kumar Gala <galak@kernel.crashing.org> Tue, 28 Mar 2006 16:53:43 -0600
committer Kumar Gala <galak@kernel.crashing.org> Tue, 28 Mar 2006 16:53:43 -0600
drivers/rtc/rtc-ds1672.c | 61 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-ds1672.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-ds1672.c 2006-03-29 02:16:01.000000000 +0200
@@ -23,6 +23,7 @@ I2C_CLIENT_INSMOD;
#define DS1672_REG_CNT_BASE 0
#define DS1672_REG_CONTROL 4
+#define DS1672_REG_CONTROL_EOSC 0x80
#define DS1672_REG_TRICKLE 5
@@ -72,16 +73,17 @@ static int ds1672_get_datetime(struct i2
static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
{
int xfer;
- unsigned char buf[5];
+ unsigned char buf[6];
buf[0] = DS1672_REG_CNT_BASE;
buf[1] = secs & 0x000000FF;
buf[2] = (secs & 0x0000FF00) >> 8;
buf[3] = (secs & 0x00FF0000) >> 16;
buf[4] = (secs & 0xFF000000) >> 24;
+ buf[5] = 0; /* set control reg to enable counting */
- xfer = i2c_master_send(client, buf, 5);
- if (xfer != 5) {
+ xfer = i2c_master_send(client, buf, 6);
+ if (xfer != 6) {
dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer);
return -EIO;
}
@@ -120,6 +122,44 @@ static int ds1672_rtc_set_mmss(struct de
return ds1672_set_mmss(to_i2c_client(dev), secs);
}
+static int ds1672_get_control(struct i2c_client *client, u8 *status)
+{
+ unsigned char addr = DS1672_REG_CONTROL;
+
+ struct i2c_msg msgs[] = {
+ { client->addr, 0, 1, &addr }, /* setup read ptr */
+ { client->addr, I2C_M_RD, 1, status }, /* read control */
+ };
+
+ /* read control register */
+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/* following are the sysfs callback functions */
+static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ char *state = "enabled";
+ u8 control;
+ int err;
+
+ err = ds1672_get_control(client, &control);
+ if (err)
+ return err;
+
+ if (control & DS1672_REG_CONTROL_EOSC)
+ state = "disabled";
+
+ return sprintf(buf, "%s\n", state);
+}
+
+static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
+
static struct rtc_class_ops ds1672_rtc_ops = {
.read_time = ds1672_rtc_read_time,
.set_time = ds1672_rtc_set_time,
@@ -162,6 +202,7 @@ static struct i2c_driver ds1672_driver =
static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
{
int err = 0;
+ u8 control;
struct i2c_client *client;
struct rtc_device *rtc;
@@ -202,6 +243,20 @@ static int ds1672_probe(struct i2c_adapt
i2c_set_clientdata(client, rtc);
+ /* read control register */
+ err = ds1672_get_control(client, &control);
+ if (err) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ goto exit_detach;
+ }
+
+ if (control & DS1672_REG_CONTROL_EOSC)
+ dev_warn(&client->dev, "Oscillator not enabled. "
+ "Set time to enable.\n");
+
+ /* Register sysfs hooks */
+ device_create_file(&client->dev, &dev_attr_control);
+
return 0;
exit_detach:
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 02/10] RTC subsystem, DS1672 cleanup
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
2006-03-31 10:04 ` [PATCH 01/10] RTC subsystem, DS1672 oscillator handling Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 03/10] RTC subsystem, X1205 sysfs cleanup Alessandro Zummo
` (8 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Kumar Gala
[-- Attachment #1: rtc-subsys-ds1672-tidy.patch --]
[-- Type: text/plain, Size: 3561 bytes --]
- removed a duplicate error message
- bumped driver version
- removed some debugging messages in excess
- refined the formatting
- adjusted copyright notice
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Kumar Gala <galak@kernel.crashing.org>
---
drivers/rtc/rtc-ds1672.c | 29 ++++++++++-------------------
1 file changed, 10 insertions(+), 19 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-ds1672.c 2006-03-29 02:16:01.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-ds1672.c 2006-03-29 02:29:43.000000000 +0200
@@ -1,6 +1,8 @@
/*
* An rtc/i2c driver for the Dallas DS1672
- * Copyright 2005 Alessandro Zummo
+ * Copyright 2005-06 Tower Technologies
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,7 +13,7 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
/* Addresses to scan: none. This chip cannot be detected. */
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
@@ -23,9 +25,9 @@ I2C_CLIENT_INSMOD;
#define DS1672_REG_CNT_BASE 0
#define DS1672_REG_CONTROL 4
-#define DS1672_REG_CONTROL_EOSC 0x80
#define DS1672_REG_TRICKLE 5
+#define DS1672_REG_CONTROL_EOSC 0x80
/* Prototypes */
static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind);
@@ -54,8 +56,7 @@ static int ds1672_get_datetime(struct i2
dev_dbg(&client->dev,
"%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
- __FUNCTION__,
- buf[0], buf[1], buf[2], buf[3]);
+ __FUNCTION__, buf[0], buf[1], buf[2], buf[3]);
time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
@@ -63,8 +64,7 @@ static int ds1672_get_datetime(struct i2
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
- __FUNCTION__,
- tm->tm_sec, tm->tm_min, tm->tm_hour,
+ __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
return 0;
@@ -144,7 +144,6 @@ static int ds1672_get_control(struct i2c
static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
- char *state = "enabled";
u8 control;
int err;
@@ -152,12 +151,9 @@ static ssize_t show_control(struct devic
if (err)
return err;
- if (control & DS1672_REG_CONTROL_EOSC)
- state = "disabled";
-
- return sprintf(buf, "%s\n", state);
+ return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC)
+ ? "disabled" : "enabled");
}
-
static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
static struct rtc_class_ops ds1672_rtc_ops = {
@@ -168,7 +164,6 @@ static struct rtc_class_ops ds1672_rtc_o
static int ds1672_attach(struct i2c_adapter *adapter)
{
- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
return i2c_probe(adapter, &addr_data, ds1672_probe);
}
@@ -177,8 +172,6 @@ static int ds1672_detach(struct i2c_clie
int err;
struct rtc_device *rtc = i2c_get_clientdata(client);
- dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-
if (rtc)
rtc_device_unregister(rtc);
@@ -245,10 +238,8 @@ static int ds1672_probe(struct i2c_adapt
/* read control register */
err = ds1672_get_control(client, &control);
- if (err) {
- dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ if (err)
goto exit_detach;
- }
if (control & DS1672_REG_CONTROL_EOSC)
dev_warn(&client->dev, "Oscillator not enabled. "
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 03/10] RTC subsystem, X1205 sysfs cleanup
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
2006-03-31 10:04 ` [PATCH 01/10] RTC subsystem, DS1672 oscillator handling Alessandro Zummo
2006-03-31 10:04 ` [PATCH 02/10] RTC subsystem, DS1672 cleanup Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 04/10] RTC subsystem, whitespaces and error messages cleanup Alessandro Zummo
` (7 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm
[-- Attachment #1: rtc-subsys-x1205-fix-sysfs.patch --]
[-- Type: text/plain, Size: 1604 bytes --]
fixed sysfs show() return code
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
---
drivers/rtc/rtc-x1205.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-x1205.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-x1205.c 2006-03-29 02:33:57.000000000 +0200
@@ -19,7 +19,7 @@
#include <linux/rtc.h>
#include <linux/delay.h>
-#define DRV_VERSION "1.0.6"
+#define DRV_VERSION "1.0.7"
/* Addresses to scan: none. This chip is located at
* 0x6f and uses a two bytes register addressing.
@@ -473,24 +473,26 @@ static struct rtc_class_ops x1205_rtc_op
static ssize_t x1205_sysfs_show_atrim(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int atrim;
+ int err, atrim;
- if (x1205_get_atrim(to_i2c_client(dev), &atrim) == 0)
- return sprintf(buf, "%d.%02d pF\n",
- atrim / 1000, atrim % 1000);
- return 0;
+ err = x1205_get_atrim(to_i2c_client(dev), &atrim);
+ if (err)
+ return err;
+
+ return sprintf(buf, "%d.%02d pF\n", atrim / 1000, atrim % 1000);
}
static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL);
static ssize_t x1205_sysfs_show_dtrim(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int dtrim;
+ int err, dtrim;
- if (x1205_get_dtrim(to_i2c_client(dev), &dtrim) == 0)
- return sprintf(buf, "%d ppm\n", dtrim);
+ err = x1205_get_dtrim(to_i2c_client(dev), &dtrim);
+ if (err)
+ return err;
- return 0;
+ return sprintf(buf, "%d ppm\n", dtrim);
}
static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL);
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 04/10] RTC subsystem, whitespaces and error messages cleanup
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (2 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 03/10] RTC subsystem, X1205 sysfs cleanup Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 05/10] RTC subsystem, fix proc output Alessandro Zummo
` (6 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm
[-- Attachment #1: rtc-subsys-tidy.patch --]
[-- Type: text/plain, Size: 2355 bytes --]
- fixed whitespaces
- removed some debugging in excess
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
---
drivers/rtc/rtc-m48t86.c | 2 +-
drivers/rtc/rtc-pcf8563.c | 2 --
drivers/rtc/rtc-rs5c372.c | 3 ---
drivers/rtc/rtc-x1205.c | 3 ---
4 files changed, 1 insertion(+), 9 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-x1205.c 2006-03-29 02:33:58.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-x1205.c 2006-03-29 03:12:07.000000000 +0200
@@ -498,7 +498,6 @@ static DEVICE_ATTR(dtrim, S_IRUGO, x1205
static int x1205_attach(struct i2c_adapter *adapter)
{
- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
return i2c_probe(adapter, &addr_data, x1205_probe);
}
@@ -587,8 +586,6 @@ static int x1205_detach(struct i2c_clien
int err;
struct rtc_device *rtc = i2c_get_clientdata(client);
- dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-
if (rtc)
rtc_device_unregister(rtc);
--- linux-rtc.orig/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:47:17.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-rs5c372.c 2006-03-29 03:12:07.000000000 +0200
@@ -193,7 +193,6 @@ static DEVICE_ATTR(osc, S_IRUGO, rs5c372
static int rs5c372_attach(struct i2c_adapter *adapter)
{
- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
return i2c_probe(adapter, &addr_data, rs5c372_probe);
}
@@ -260,8 +259,6 @@ static int rs5c372_detach(struct i2c_cli
int err;
struct rtc_device *rtc = i2c_get_clientdata(client);
- dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-
if (rtc)
rtc_device_unregister(rtc);
--- linux-rtc.orig/drivers/rtc/rtc-pcf8563.c 2006-03-29 02:47:17.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-pcf8563.c 2006-03-29 03:12:07.000000000 +0200
@@ -321,8 +321,6 @@ static int pcf8563_detach(struct i2c_cli
int err;
struct rtc_device *rtc = i2c_get_clientdata(client);
- dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-
if (rtc)
rtc_device_unregister(rtc);
--- linux-rtc.orig/drivers/rtc/rtc-m48t86.c 2006-03-29 02:47:17.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-m48t86.c 2006-03-29 03:12:07.000000000 +0200
@@ -23,7 +23,7 @@
#define M48T86_REG_SECALRM 0x01
#define M48T86_REG_MIN 0x02
#define M48T86_REG_MINALRM 0x03
-#define M48T86_REG_HOUR 0x04
+#define M48T86_REG_HOUR 0x04
#define M48T86_REG_HOURALRM 0x05
#define M48T86_REG_DOW 0x06 /* 1 = sunday */
#define M48T86_REG_DOM 0x07
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 05/10] RTC subsystem, fix proc output
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (3 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 04/10] RTC subsystem, whitespaces and error messages cleanup Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 06/10] RTC subsystem, RS5C372 sysfs fix Alessandro Zummo
` (5 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Lennert Buytenhek
[-- Attachment #1: rtc-subsys-fix-proc-24hr.patch --]
[-- Type: text/plain, Size: 3690 bytes --]
Moved the "24hr: yes" proc output from drivers to rtc
proc code. This is required because the time value
in the proc output is always in 24hr mode regardless
of the driver.
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
---
drivers/rtc/rtc-ep93xx.c | 1 -
drivers/rtc/rtc-m48t86.c | 3 ---
drivers/rtc/rtc-pcf8563.c | 7 -------
drivers/rtc/rtc-proc.c | 2 ++
drivers/rtc/rtc-rs5c372.c | 5 ++---
drivers/rtc/rtc-test.c | 1 -
drivers/rtc/rtc-x1205.c | 2 --
7 files changed, 4 insertions(+), 17 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-ep93xx.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-ep93xx.c 2006-03-29 02:40:12.000000000 +0200
@@ -67,7 +67,6 @@ static int ep93xx_rtc_proc(struct device
ep93xx_get_swcomp(dev, &preload, &delete);
- seq_printf(seq, "24hr\t\t: yes\n");
seq_printf(seq, "preload\t\t: %d\n", preload);
seq_printf(seq, "delete\t\t: %d\n", delete);
--- linux-rtc.orig/drivers/rtc/rtc-pcf8563.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-pcf8563.c 2006-03-29 02:40:27.000000000 +0200
@@ -227,14 +227,7 @@ static int pcf8563_rtc_set_time(struct d
return pcf8563_set_datetime(to_i2c_client(dev), tm);
}
-static int pcf8563_rtc_proc(struct device *dev, struct seq_file *seq)
-{
- seq_printf(seq, "24hr\t\t: yes\n");
- return 0;
-}
-
static struct rtc_class_ops pcf8563_rtc_ops = {
- .proc = pcf8563_rtc_proc,
.read_time = pcf8563_rtc_read_time,
.set_time = pcf8563_rtc_set_time,
};
--- linux-rtc.orig/drivers/rtc/rtc-proc.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-proc.c 2006-03-29 02:39:56.000000000 +0200
@@ -71,6 +71,8 @@ static int rtc_proc_show(struct seq_file
alrm.pending ? "yes" : "no");
}
+ seq_printf(seq, "24hr\t\t: yes\n");
+
if (ops->proc)
ops->proc(class_dev->dev, seq);
--- linux-rtc.orig/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:46:57.000000000 +0200
@@ -151,9 +151,8 @@ static int rs5c372_rtc_proc(struct devic
{
int err, osc, trim;
- seq_printf(seq, "24hr\t\t: yes\n");
-
- if ((err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim)) == 0) {
+ err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim);
+ if (err == 0) {
seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000);
seq_printf(seq, "trim\t: %d\n", trim);
}
--- linux-rtc.orig/drivers/rtc/rtc-x1205.c 2006-03-29 02:38:39.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-x1205.c 2006-03-29 02:39:46.000000000 +0200
@@ -451,8 +451,6 @@ static int x1205_rtc_proc(struct device
{
int err, dtrim, atrim;
- seq_printf(seq, "24hr\t\t: yes\n");
-
if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0)
seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim);
--- linux-rtc.orig/drivers/rtc/rtc-m48t86.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-m48t86.c 2006-03-29 02:42:37.000000000 +0200
@@ -127,9 +127,6 @@ static int m48t86_rtc_proc(struct device
reg = ops->readb(M48T86_REG_B);
- seq_printf(seq, "24hr\t\t: %s\n",
- (reg & M48T86_REG_B_H24) ? "yes" : "no");
-
seq_printf(seq, "mode\t\t: %s\n",
(reg & M48T86_REG_B_DM) ? "binary" : "bcd");
--- linux-rtc.orig/drivers/rtc/rtc-test.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-test.c 2006-03-29 02:42:54.000000000 +0200
@@ -49,7 +49,6 @@ static int test_rtc_proc(struct device *
{
struct platform_device *plat_dev = to_platform_device(dev);
- seq_printf(seq, "24hr\t\t: yes\n");
seq_printf(seq, "test\t\t: yes\n");
seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 06/10] RTC subsystem, RS5C372 sysfs fix
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (4 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 05/10] RTC subsystem, fix proc output Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 07/10] RTC subsystem, compact error messages Alessandro Zummo
` (4 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm
[-- Attachment #1: rtc-subsys-rs5c372-fix-sysfs.patch --]
[-- Type: text/plain, Size: 1372 bytes --]
fixed sysfs show() return code
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
---
drivers/rtc/rtc-rs5c372.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:41:04.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:46:40.000000000 +0200
@@ -169,24 +169,26 @@ static struct rtc_class_ops rs5c372_rtc_
static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int trim;
+ int err, trim;
- if (rs5c372_get_trim(to_i2c_client(dev), NULL, &trim) == 0)
- return sprintf(buf, "0x%2x\n", trim);
+ err = rs5c372_get_trim(to_i2c_client(dev), NULL, &trim);
+ if (err)
+ return err;
- return 0;
+ return sprintf(buf, "0x%2x\n", trim);
}
static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL);
static ssize_t rs5c372_sysfs_show_osc(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int osc;
+ int err, osc;
- if (rs5c372_get_trim(to_i2c_client(dev), &osc, NULL) == 0)
- return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000);
+ err = rs5c372_get_trim(to_i2c_client(dev), &osc, NULL);
+ if (err)
+ return err;
- return 0;
+ return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000);
}
static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL);
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 07/10] RTC subsystem, compact error messages
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (5 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 06/10] RTC subsystem, RS5C372 sysfs fix Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-03-31 10:04 ` [PATCH 08/10] RTC subsystem, SA1100 cleanup Alessandro Zummo
` (3 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Lennert Buytenhek
[-- Attachment #1: rtc-subsys-compact-err-message.patch --]
[-- Type: text/plain, Size: 3979 bytes --]
- move registration error message from drivers
to core.
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
---
drivers/rtc/class.c | 2 ++
drivers/rtc/rtc-ds1672.c | 2 --
drivers/rtc/rtc-ep93xx.c | 1 -
drivers/rtc/rtc-m48t86.c | 4 +---
drivers/rtc/rtc-pcf8563.c | 2 --
drivers/rtc/rtc-rs5c372.c | 2 --
drivers/rtc/rtc-sa1100.c | 1 -
drivers/rtc/rtc-test.c | 2 --
drivers/rtc/rtc-x1205.c | 2 --
9 files changed, 3 insertions(+), 15 deletions(-)
--- linux-rtc.orig/drivers/rtc/class.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/class.c 2006-03-29 02:55:47.000000000 +0200
@@ -96,6 +96,8 @@ exit_idr:
idr_remove(&rtc_idr, id);
exit:
+ dev_err(dev, "rtc core: unable to register %s, err = %d\n",
+ name, err);
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(rtc_device_register);
--- linux-rtc.orig/drivers/rtc/rtc-x1205.c 2006-03-29 02:50:57.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-x1205.c 2006-03-29 02:53:01.000000000 +0200
@@ -544,8 +544,6 @@ static int x1205_probe(struct i2c_adapte
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
- dev_err(&client->dev,
- "unable to register the class device\n");
goto exit_detach;
}
--- linux-rtc.orig/drivers/rtc/rtc-ds1672.c 2006-03-29 02:29:43.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-ds1672.c 2006-03-29 02:57:10.000000000 +0200
@@ -229,8 +229,6 @@ static int ds1672_probe(struct i2c_adapt
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
- dev_err(&client->dev,
- "unable to register the class device\n");
goto exit_detach;
}
--- linux-rtc.orig/drivers/rtc/rtc-m48t86.c 2006-03-29 02:50:57.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-m48t86.c 2006-03-29 02:56:48.000000000 +0200
@@ -151,10 +151,8 @@ static int __devinit m48t86_rtc_probe(st
struct rtc_device *rtc = rtc_device_register("m48t86",
&dev->dev, &m48t86_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- dev_err(&dev->dev, "unable to register\n");
+ if (IS_ERR(rtc))
return PTR_ERR(rtc);
- }
platform_set_drvdata(dev, rtc);
--- linux-rtc.orig/drivers/rtc/rtc-pcf8563.c 2006-03-29 02:50:57.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-pcf8563.c 2006-03-29 02:57:01.000000000 +0200
@@ -290,8 +290,6 @@ static int pcf8563_probe(struct i2c_adap
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
- dev_err(&client->dev,
- "unable to register the class device\n");
goto exit_detach;
}
--- linux-rtc.orig/drivers/rtc/rtc-test.c 2006-03-29 02:50:57.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-test.c 2006-03-29 02:56:29.000000000 +0200
@@ -119,8 +119,6 @@ static int test_probe(struct platform_de
&test_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
- dev_err(&plat_dev->dev,
- "unable to register the class device\n");
return err;
}
device_create_file(&plat_dev->dev, &dev_attr_irq);
--- linux-rtc.orig/drivers/rtc/rtc-ep93xx.c 2006-03-29 02:50:57.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-ep93xx.c 2006-03-29 02:58:03.000000000 +0200
@@ -109,7 +109,6 @@ static int __devinit ep93xx_rtc_probe(st
&dev->dev, &ep93xx_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
- dev_err(&dev->dev, "unable to register\n");
return PTR_ERR(rtc);
}
--- linux-rtc.orig/drivers/rtc/rtc-sa1100.c 2006-03-29 02:14:50.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-sa1100.c 2006-03-29 02:57:38.000000000 +0200
@@ -341,7 +341,6 @@ static int sa1100_rtc_probe(struct platf
THIS_MODULE);
if (IS_ERR(rtc)) {
- dev_err(&pdev->dev, "Unable to register the RTC device\n");
return PTR_ERR(rtc);
}
--- linux-rtc.orig/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:50:58.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-rs5c372.c 2006-03-29 02:59:15.000000000 +0200
@@ -233,8 +233,6 @@ static int rs5c372_probe(struct i2c_adap
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
- dev_err(&client->dev,
- "unable to register the class device\n");
goto exit_detach;
}
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 08/10] RTC subsystem, SA1100 cleanup
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (6 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 07/10] RTC subsystem, compact error messages Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-04-02 18:43 ` Pavel Machek
2006-03-31 10:04 ` [PATCH 09/10] RTC subsystem, VR41XX driver Alessandro Zummo
` (2 subsequent siblings)
10 siblings, 1 reply; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Richard Purdie
[-- Attachment #1: rtc-subsys-sa1100-tidy.patch --]
[-- Type: text/plain, Size: 1953 bytes --]
- converted printks to dev_xxx
- removed messages in excess
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Richard Purdie <rpurdie@rpsys.net>
---
drivers/rtc/rtc-sa1100.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
--- linux-rtc.orig/drivers/rtc/rtc-sa1100.c 2006-03-29 03:15:58.000000000 +0200
+++ linux-rtc/drivers/rtc/rtc-sa1100.c 2006-03-29 03:15:58.000000000 +0200
@@ -160,19 +160,19 @@ static int sa1100_rtc_open(struct device
ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT,
"rtc 1Hz", dev);
if (ret) {
- printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
+ dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
goto fail_ui;
}
ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT,
"rtc Alrm", dev);
if (ret) {
- printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
+ dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
goto fail_ai;
}
ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT,
"rtc timer", dev);
if (ret) {
- printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1);
+ dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1);
goto fail_pi;
}
return 0;
@@ -332,7 +332,7 @@ static int sa1100_rtc_probe(struct platf
*/
if (RTTR == 0) {
RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
- printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
+ dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n");
/* The current RTC value probably doesn't make sense either */
RCNR = 0;
}
@@ -340,14 +340,11 @@ static int sa1100_rtc_probe(struct platf
rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
THIS_MODULE);
- if (IS_ERR(rtc)) {
+ if (IS_ERR(rtc))
return PTR_ERR(rtc);
- }
platform_set_drvdata(pdev, rtc);
- dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n");
-
return 0;
}
--
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 09/10] RTC subsystem, VR41XX driver
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (7 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 08/10] RTC subsystem, SA1100 cleanup Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
2006-04-01 23:20 ` Andrew Morton
2006-03-31 10:04 ` [PATCH 10/10] RTC subsystem, VR41XX cleanup Alessandro Zummo
[not found] ` <Pine.LNX.4.63.0605030826290.1846@pcgl.dsa-ac.de>
10 siblings, 1 reply; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Yoichi Yuasa
[-- Attachment #1: rtc-subsys-drv-vr41xx.patch --]
[-- Type: text/plain, Size: 31323 bytes --]
From: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Hi,
This patch updates VR4100 series RTC driver.
* This driver supports new RTC subsystem.
* Simple set time/read time test worked fine.
Yoichi
Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
diff -pruN -X dontdiff mm2-orig/drivers/char/Kconfig mm2/drivers/char/Kconfig
--- mm2-orig/drivers/char/Kconfig 2006-03-31 12:54:47.327851500 +0900
+++ mm2/drivers/char/Kconfig 2006-03-29 11:47:27.440976000 +0900
@@ -788,10 +788,6 @@ config S3C2410_RTC
Samsung S3C2410. This can provide periodic interrupt rates
from 1Hz to 64Hz for user programs, and wakeup from Alarm.
-config RTC_VR41XX
- tristate "NEC VR4100 series Real Time Clock Support"
- depends on CPU_VR41XX
-
config COBALT_LCD
bool "Support for Cobalt LCD"
depends on MIPS_COBALT
diff -pruN -X dontdiff mm2-orig/drivers/char/Makefile mm2/drivers/char/Makefile
--- mm2-orig/drivers/char/Makefile 2006-03-31 12:54:47.327851500 +0900
+++ mm2/drivers/char/Makefile 2006-03-29 11:48:15.283966000 +0900
@@ -65,7 +65,6 @@ obj-$(CONFIG_SGI_DS1286) += ds1286.o
obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
obj-$(CONFIG_DS1302) += ds1302.o
obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o
-obj-$(CONFIG_RTC_VR41XX) += vr41xx_rtc.o
ifeq ($(CONFIG_GENERIC_NVRAM),y)
obj-$(CONFIG_NVRAM) += generic_nvram.o
else
diff -pruN -X dontdiff mm2-orig/drivers/char/vr41xx_rtc.c mm2/drivers/char/vr41xx_rtc.c
--- mm2-orig/drivers/char/vr41xx_rtc.c 2006-03-31 12:54:51.296099500 +0900
+++ mm2/drivers/char/vr41xx_rtc.c 1970-01-01 09:00:00.000000000 +0900
@@ -1,717 +0,0 @@
-/*
- * Driver for NEC VR4100 series Real Time Clock unit.
- *
- * Copyright (C) 2003-2005 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/mc146818rtc.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/rtc.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-
-#include <asm/div64.h>
-#include <asm/io.h>
-#include <asm/time.h>
-#include <asm/uaccess.h>
-#include <asm/vr41xx/vr41xx.h>
-
-MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
-MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
-MODULE_LICENSE("GPL");
-
-#define RTC1_TYPE1_START 0x0b0000c0UL
-#define RTC1_TYPE1_END 0x0b0000dfUL
-#define RTC2_TYPE1_START 0x0b0001c0UL
-#define RTC2_TYPE1_END 0x0b0001dfUL
-
-#define RTC1_TYPE2_START 0x0f000100UL
-#define RTC1_TYPE2_END 0x0f00011fUL
-#define RTC2_TYPE2_START 0x0f000120UL
-#define RTC2_TYPE2_END 0x0f00013fUL
-
-#define RTC1_SIZE 0x20
-#define RTC2_SIZE 0x20
-
-/* RTC 1 registers */
-#define ETIMELREG 0x00
-#define ETIMEMREG 0x02
-#define ETIMEHREG 0x04
-/* RFU */
-#define ECMPLREG 0x08
-#define ECMPMREG 0x0a
-#define ECMPHREG 0x0c
-/* RFU */
-#define RTCL1LREG 0x10
-#define RTCL1HREG 0x12
-#define RTCL1CNTLREG 0x14
-#define RTCL1CNTHREG 0x16
-#define RTCL2LREG 0x18
-#define RTCL2HREG 0x1a
-#define RTCL2CNTLREG 0x1c
-#define RTCL2CNTHREG 0x1e
-
-/* RTC 2 registers */
-#define TCLKLREG 0x00
-#define TCLKHREG 0x02
-#define TCLKCNTLREG 0x04
-#define TCLKCNTHREG 0x06
-/* RFU */
-#define RTCINTREG 0x1e
- #define TCLOCK_INT 0x08
- #define RTCLONG2_INT 0x04
- #define RTCLONG1_INT 0x02
- #define ELAPSEDTIME_INT 0x01
-
-#define RTC_FREQUENCY 32768
-#define MAX_PERIODIC_RATE 6553
-#define MAX_USER_PERIODIC_RATE 64
-
-static void __iomem *rtc1_base;
-static void __iomem *rtc2_base;
-
-#define rtc1_read(offset) readw(rtc1_base + (offset))
-#define rtc1_write(offset, value) writew((value), rtc1_base + (offset))
-
-#define rtc2_read(offset) readw(rtc2_base + (offset))
-#define rtc2_write(offset, value) writew((value), rtc2_base + (offset))
-
-static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
-
-static spinlock_t rtc_task_lock;
-static wait_queue_head_t rtc_wait;
-static unsigned long rtc_irq_data;
-static struct fasync_struct *rtc_async_queue;
-static rtc_task_t *rtc_callback;
-static char rtc_name[] = "RTC";
-static unsigned long periodic_frequency;
-static unsigned long periodic_count;
-
-typedef enum {
- RTC_RELEASE,
- RTC_OPEN,
-} rtc_status_t;
-
-static rtc_status_t rtc_status;
-
-typedef enum {
- FUNCTION_RTC_IOCTL,
- FUNCTION_RTC_CONTROL,
-} rtc_callfrom_t;
-
-struct resource rtc_resource[2] = {
- { .name = rtc_name,
- .flags = IORESOURCE_MEM, },
- { .name = rtc_name,
- .flags = IORESOURCE_MEM, },
-};
-
-static inline unsigned long read_elapsed_second(void)
-{
- unsigned long first_low, first_mid, first_high;
- unsigned long second_low, second_mid, second_high;
-
- do {
- first_low = rtc1_read(ETIMELREG);
- first_mid = rtc1_read(ETIMEMREG);
- first_high = rtc1_read(ETIMEHREG);
- second_low = rtc1_read(ETIMELREG);
- second_mid = rtc1_read(ETIMEMREG);
- second_high = rtc1_read(ETIMEHREG);
- } while (first_low != second_low || first_mid != second_mid ||
- first_high != second_high);
-
- return (first_high << 17) | (first_mid << 1) | (first_low >> 15);
-}
-
-static inline void write_elapsed_second(unsigned long sec)
-{
- spin_lock_irq(&rtc_lock);
-
- rtc1_write(ETIMELREG, (uint16_t)(sec << 15));
- rtc1_write(ETIMEMREG, (uint16_t)(sec >> 1));
- rtc1_write(ETIMEHREG, (uint16_t)(sec >> 17));
-
- spin_unlock_irq(&rtc_lock);
-}
-
-static void set_alarm(struct rtc_time *time)
-{
- unsigned long alarm_sec;
-
- alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
- time->tm_hour, time->tm_min, time->tm_sec);
-
- spin_lock_irq(&rtc_lock);
-
- rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
- rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
- rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
-
- spin_unlock_irq(&rtc_lock);
-}
-
-static void read_alarm(struct rtc_time *time)
-{
- unsigned long low, mid, high;
-
- spin_lock_irq(&rtc_lock);
-
- low = rtc1_read(ECMPLREG);
- mid = rtc1_read(ECMPMREG);
- high = rtc1_read(ECMPHREG);
-
- spin_unlock_irq(&rtc_lock);
-
- to_tm((high << 17) | (mid << 1) | (low >> 15), time);
- time->tm_year -= 1900;
-}
-
-static void read_time(struct rtc_time *time)
-{
- unsigned long epoch_sec, elapsed_sec;
-
- epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
- elapsed_sec = read_elapsed_second();
-
- to_tm(epoch_sec + elapsed_sec, time);
- time->tm_year -= 1900;
-}
-
-static void set_time(struct rtc_time *time)
-{
- unsigned long epoch_sec, current_sec;
-
- epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
- current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
- time->tm_hour, time->tm_min, time->tm_sec);
-
- write_elapsed_second(current_sec - epoch_sec);
-}
-
-static ssize_t rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long irq_data;
- int retval = 0;
-
- if (count != sizeof(unsigned int) && count != sizeof(unsigned long))
- return -EINVAL;
-
- add_wait_queue(&rtc_wait, &wait);
-
- do {
- __set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irq(&rtc_lock);
- irq_data = rtc_irq_data;
- rtc_irq_data = 0;
- spin_unlock_irq(&rtc_lock);
-
- if (irq_data != 0)
- break;
-
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- } while (1);
-
- if (retval == 0) {
- if (count == sizeof(unsigned int)) {
- retval = put_user(irq_data, (unsigned int __user *)buf);
- if (retval == 0)
- retval = sizeof(unsigned int);
- } else {
- retval = put_user(irq_data, (unsigned long __user *)buf);
- if (retval == 0)
- retval = sizeof(unsigned long);
- }
-
- }
-
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&rtc_wait, &wait);
-
- return retval;
-}
-
-static unsigned int rtc_poll(struct file *file, struct poll_table_struct *table)
-{
- poll_wait(file, &rtc_wait, table);
-
- if (rtc_irq_data != 0)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from)
-{
- struct rtc_time time;
- unsigned long count;
-
- switch (cmd) {
- case RTC_AIE_ON:
- enable_irq(ELAPSEDTIME_IRQ);
- break;
- case RTC_AIE_OFF:
- disable_irq(ELAPSEDTIME_IRQ);
- break;
- case RTC_PIE_ON:
- enable_irq(RTCLONG1_IRQ);
- break;
- case RTC_PIE_OFF:
- disable_irq(RTCLONG1_IRQ);
- break;
- case RTC_ALM_SET:
- if (copy_from_user(&time, (struct rtc_time __user *)arg,
- sizeof(struct rtc_time)))
- return -EFAULT;
-
- set_alarm(&time);
- break;
- case RTC_ALM_READ:
- memset(&time, 0, sizeof(struct rtc_time));
- read_alarm(&time);
- break;
- case RTC_RD_TIME:
- memset(&time, 0, sizeof(struct rtc_time));
- read_time(&time);
- if (copy_to_user((void __user *)arg, &time, sizeof(struct rtc_time)))
- return -EFAULT;
- break;
- case RTC_SET_TIME:
- if (capable(CAP_SYS_TIME) == 0)
- return -EACCES;
-
- if (copy_from_user(&time, (struct rtc_time __user *)arg,
- sizeof(struct rtc_time)))
- return -EFAULT;
-
- set_time(&time);
- 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;
-
- if (from == FUNCTION_RTC_IOCTL && arg > MAX_USER_PERIODIC_RATE &&
- capable(CAP_SYS_RESOURCE) == 0)
- return -EACCES;
-
- 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:
- return put_user(epoch, (unsigned long __user *)arg);
- case RTC_EPOCH_SET:
- /* Doesn't support before 1900 */
- if (arg < 1900)
- return -EINVAL;
-
- if (capable(CAP_SYS_TIME) == 0)
- return -EACCES;
-
- epoch = arg;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return rtc_do_ioctl(cmd, arg, FUNCTION_RTC_IOCTL);
-}
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
- spin_lock_irq(&rtc_lock);
-
- if (rtc_status == RTC_OPEN) {
- spin_unlock_irq(&rtc_lock);
- return -EBUSY;
- }
-
- rtc_status = RTC_OPEN;
- rtc_irq_data = 0;
-
- spin_unlock_irq(&rtc_lock);
-
- return 0;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
- if (file->f_flags & FASYNC)
- (void)fasync_helper(-1, file, 0, &rtc_async_queue);
-
- spin_lock_irq(&rtc_lock);
-
- rtc1_write(ECMPLREG, 0);
- rtc1_write(ECMPMREG, 0);
- rtc1_write(ECMPHREG, 0);
- rtc1_write(RTCL1LREG, 0);
- rtc1_write(RTCL1HREG, 0);
-
- rtc_status = RTC_RELEASE;
-
- spin_unlock_irq(&rtc_lock);
-
- disable_irq(ELAPSEDTIME_IRQ);
- disable_irq(RTCLONG1_IRQ);
-
- return 0;
-}
-
-static int rtc_fasync(int fd, struct file *file, int on)
-{
- return fasync_helper(fd, file, on, &rtc_async_queue);
-}
-
-static struct file_operations rtc_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = rtc_read,
- .poll = rtc_poll,
- .ioctl = rtc_ioctl,
- .open = rtc_open,
- .release = rtc_release,
- .fasync = rtc_fasync,
-};
-
-static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- spin_lock(&rtc_lock);
- rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
-
- rtc_irq_data += 0x100;
- rtc_irq_data &= ~0xff;
- rtc_irq_data |= RTC_AF;
- spin_unlock(&rtc_lock);
-
- spin_lock(&rtc_lock);
- if (rtc_callback)
- rtc_callback->func(rtc_callback->private_data);
- spin_unlock(&rtc_lock);
-
- wake_up_interruptible(&rtc_wait);
-
- kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- unsigned long count = periodic_count;
-
- spin_lock(&rtc_lock);
- rtc2_write(RTCINTREG, RTCLONG1_INT);
-
- rtc1_write(RTCL1LREG, count);
- rtc1_write(RTCL1HREG, count >> 16);
-
- rtc_irq_data += 0x100;
- rtc_irq_data &= ~0xff;
- rtc_irq_data |= RTC_PF;
- spin_unlock(&rtc_lock);
-
- spin_lock(&rtc_task_lock);
- if (rtc_callback)
- rtc_callback->func(rtc_callback->private_data);
- spin_unlock(&rtc_task_lock);
-
- wake_up_interruptible(&rtc_wait);
-
- kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
-
- return IRQ_HANDLED;
-}
-
-int rtc_register(rtc_task_t *task)
-{
- if (task == NULL || task->func == NULL)
- return -EINVAL;
-
- spin_lock_irq(&rtc_lock);
- if (rtc_status == RTC_OPEN) {
- spin_unlock_irq(&rtc_lock);
- return -EBUSY;
- }
-
- spin_lock(&rtc_task_lock);
- if (rtc_callback != NULL) {
- spin_unlock(&rtc_task_lock);
- spin_unlock_irq(&rtc_task_lock);
- return -EBUSY;
- }
-
- rtc_callback = task;
- spin_unlock(&rtc_task_lock);
-
- rtc_status = RTC_OPEN;
-
- spin_unlock_irq(&rtc_lock);
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(rtc_register);
-
-int rtc_unregister(rtc_task_t *task)
-{
- spin_lock_irq(&rtc_task_lock);
- if (task == NULL || rtc_callback != task) {
- spin_unlock_irq(&rtc_task_lock);
- return -ENXIO;
- }
-
- spin_lock(&rtc_lock);
-
- rtc1_write(ECMPLREG, 0);
- rtc1_write(ECMPMREG, 0);
- rtc1_write(ECMPHREG, 0);
- rtc1_write(RTCL1LREG, 0);
- rtc1_write(RTCL1HREG, 0);
-
- rtc_status = RTC_RELEASE;
-
- spin_unlock(&rtc_lock);
-
- rtc_callback = NULL;
-
- spin_unlock_irq(&rtc_task_lock);
-
- disable_irq(ELAPSEDTIME_IRQ);
- disable_irq(RTCLONG1_IRQ);
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(rtc_unregister);
-
-int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
-{
- int retval = 0;
-
- spin_lock_irq(&rtc_task_lock);
-
- if (rtc_callback != task)
- retval = -ENXIO;
- else
- rtc_do_ioctl(cmd, arg, FUNCTION_RTC_CONTROL);
-
- spin_unlock_irq(&rtc_task_lock);
-
- return retval;
-}
-
-EXPORT_SYMBOL_GPL(rtc_control);
-
-static struct miscdevice rtc_miscdevice = {
- .minor = RTC_MINOR,
- .name = rtc_name,
- .fops = &rtc_fops,
-};
-
-static int __devinit rtc_probe(struct platform_device *pdev)
-{
- unsigned int irq;
- int retval;
-
- if (pdev->num_resources != 2)
- return -EBUSY;
-
- rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE);
- if (rtc1_base == NULL)
- return -EBUSY;
-
- rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE);
- if (rtc2_base == NULL) {
- iounmap(rtc1_base);
- rtc1_base = NULL;
- return -EBUSY;
- }
-
- retval = misc_register(&rtc_miscdevice);
- if (retval < 0) {
- iounmap(rtc1_base);
- iounmap(rtc2_base);
- rtc1_base = NULL;
- rtc2_base = NULL;
- return retval;
- }
-
- spin_lock_irq(&rtc_lock);
-
- rtc1_write(ECMPLREG, 0);
- rtc1_write(ECMPMREG, 0);
- rtc1_write(ECMPHREG, 0);
- rtc1_write(RTCL1LREG, 0);
- rtc1_write(RTCL1HREG, 0);
-
- rtc_status = RTC_RELEASE;
- rtc_irq_data = 0;
-
- spin_unlock_irq(&rtc_lock);
-
- init_waitqueue_head(&rtc_wait);
-
- irq = ELAPSEDTIME_IRQ;
- retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT,
- "elapsed_time", NULL);
- if (retval == 0) {
- irq = RTCLONG1_IRQ;
- retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT,
- "rtclong1", NULL);
- }
-
- if (retval < 0) {
- printk(KERN_ERR "rtc: IRQ%d is busy\n", irq);
- if (irq == RTCLONG1_IRQ)
- free_irq(ELAPSEDTIME_IRQ, NULL);
- iounmap(rtc1_base);
- iounmap(rtc2_base);
- rtc1_base = NULL;
- rtc2_base = NULL;
- return retval;
- }
-
- disable_irq(ELAPSEDTIME_IRQ);
- disable_irq(RTCLONG1_IRQ);
-
- spin_lock_init(&rtc_task_lock);
-
- printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n");
-
- return 0;
-}
-
-static int __devexit rtc_remove(struct platform_device *dev)
-{
- int retval;
-
- retval = misc_deregister(&rtc_miscdevice);
- if (retval < 0)
- return retval;
-
- free_irq(ELAPSEDTIME_IRQ, NULL);
- free_irq(RTCLONG1_IRQ, NULL);
- if (rtc1_base != NULL)
- iounmap(rtc1_base);
- if (rtc2_base != NULL)
- iounmap(rtc2_base);
-
- return 0;
-}
-
-static struct platform_device *rtc_platform_device;
-
-static struct platform_driver rtc_device_driver = {
- .probe = rtc_probe,
- .remove = __devexit_p(rtc_remove),
- .driver = {
- .name = rtc_name,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init vr41xx_rtc_init(void)
-{
- int retval;
-
- switch (current_cpu_data.cputype) {
- case CPU_VR4111:
- case CPU_VR4121:
- rtc_resource[0].start = RTC1_TYPE1_START;
- rtc_resource[0].end = RTC1_TYPE1_END;
- rtc_resource[1].start = RTC2_TYPE1_START;
- rtc_resource[1].end = RTC2_TYPE1_END;
- break;
- case CPU_VR4122:
- case CPU_VR4131:
- case CPU_VR4133:
- rtc_resource[0].start = RTC1_TYPE2_START;
- rtc_resource[0].end = RTC1_TYPE2_END;
- rtc_resource[1].start = RTC2_TYPE2_START;
- rtc_resource[1].end = RTC2_TYPE2_END;
- break;
- default:
- return -ENODEV;
- break;
- }
-
- rtc_platform_device = platform_device_alloc("RTC", -1);
- if (!rtc_platform_device)
- return -ENOMEM;
-
- retval = platform_device_add_resources(rtc_platform_device,
- rtc_resource, ARRAY_SIZE(rtc_resource));
-
- if (retval == 0)
- retval = platform_device_add(rtc_platform_device);
-
- if (retval < 0) {
- platform_device_put(rtc_platform_device);
- return retval;
- }
-
- retval = platform_driver_register(&rtc_device_driver);
- if (retval < 0)
- platform_device_unregister(rtc_platform_device);
-
- return retval;
-}
-
-static void __exit vr41xx_rtc_exit(void)
-{
- platform_driver_unregister(&rtc_device_driver);
- platform_device_unregister(rtc_platform_device);
-}
-
-module_init(vr41xx_rtc_init);
-module_exit(vr41xx_rtc_exit);
diff -pruN -X dontdiff mm2-orig/drivers/rtc/Kconfig mm2/drivers/rtc/Kconfig
--- mm2-orig/drivers/rtc/Kconfig 2006-03-31 12:55:36.858947000 +0900
+++ mm2/drivers/rtc/Kconfig 2006-03-29 11:52:56.725555000 +0900
@@ -147,6 +147,10 @@ config RTC_DRV_SA1100
To compile this driver as a module, choose M here: the
module will be called rtc-sa1100.
+config RTC_DRV_VR41XX
+ tristate "NEC VR4100 series RTC"
+ depends on RTC_CLASS && CPU_VR41XX
+
config RTC_DRV_TEST
tristate "Test driver/device"
depends on RTC_CLASS
diff -pruN -X dontdiff mm2-orig/drivers/rtc/Makefile mm2/drivers/rtc/Makefile
--- mm2-orig/drivers/rtc/Makefile 2006-03-31 12:55:36.858947000 +0900
+++ mm2/drivers/rtc/Makefile 2006-03-29 11:49:17.499854250 +0900
@@ -19,3 +19,4 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
+obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
diff -pruN -X dontdiff mm2-orig/drivers/rtc/rtc-vr41xx.c mm2/drivers/rtc/rtc-vr41xx.c
--- mm2-orig/drivers/rtc/rtc-vr41xx.c 1970-01-01 09:00:00.000000000 +0900
+++ mm2/drivers/rtc/rtc-vr41xx.c 2006-03-31 15:35:06.909395500 +0900
@@ -0,0 +1,471 @@
+/*
+ * Driver for NEC VR4100 series Real Time Clock unit.
+ *
+ * Copyright (C) 2003-2006 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/div64.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/vr41xx/vr41xx.h>
+
+MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
+MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
+MODULE_LICENSE("GPL");
+
+#define RTC1_TYPE1_START 0x0b0000c0UL
+#define RTC1_TYPE1_END 0x0b0000dfUL
+#define RTC2_TYPE1_START 0x0b0001c0UL
+#define RTC2_TYPE1_END 0x0b0001dfUL
+
+#define RTC1_TYPE2_START 0x0f000100UL
+#define RTC1_TYPE2_END 0x0f00011fUL
+#define RTC2_TYPE2_START 0x0f000120UL
+#define RTC2_TYPE2_END 0x0f00013fUL
+
+#define RTC1_SIZE 0x20
+#define RTC2_SIZE 0x20
+
+/* RTC 1 registers */
+#define ETIMELREG 0x00
+#define ETIMEMREG 0x02
+#define ETIMEHREG 0x04
+/* RFU */
+#define ECMPLREG 0x08
+#define ECMPMREG 0x0a
+#define ECMPHREG 0x0c
+/* RFU */
+#define RTCL1LREG 0x10
+#define RTCL1HREG 0x12
+#define RTCL1CNTLREG 0x14
+#define RTCL1CNTHREG 0x16
+#define RTCL2LREG 0x18
+#define RTCL2HREG 0x1a
+#define RTCL2CNTLREG 0x1c
+#define RTCL2CNTHREG 0x1e
+
+/* RTC 2 registers */
+#define TCLKLREG 0x00
+#define TCLKHREG 0x02
+#define TCLKCNTLREG 0x04
+#define TCLKCNTHREG 0x06
+/* RFU */
+#define RTCINTREG 0x1e
+ #define TCLOCK_INT 0x08
+ #define RTCLONG2_INT 0x04
+ #define RTCLONG1_INT 0x02
+ #define ELAPSEDTIME_INT 0x01
+
+#define RTC_FREQUENCY 32768
+#define MAX_PERIODIC_RATE 6553
+#define MAX_USER_PERIODIC_RATE 64
+
+static void __iomem *rtc1_base;
+static void __iomem *rtc2_base;
+
+#define rtc1_read(offset) readw(rtc1_base + (offset))
+#define rtc1_write(offset, value) writew((value), rtc1_base + (offset))
+
+#define rtc2_read(offset) readw(rtc2_base + (offset))
+#define rtc2_write(offset, value) writew((value), rtc2_base + (offset))
+
+static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
+
+static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+static char rtc_name[] = "RTC";
+static unsigned long periodic_frequency;
+static unsigned long periodic_count;
+
+struct resource rtc_resource[2] = {
+ { .name = rtc_name,
+ .flags = IORESOURCE_MEM, },
+ { .name = rtc_name,
+ .flags = IORESOURCE_MEM, },
+};
+
+static inline unsigned long read_elapsed_second(void)
+{
+
+ unsigned long first_low, first_mid, first_high;
+
+ unsigned long second_low, second_mid, second_high;
+
+ do {
+ first_low = rtc1_read(ETIMELREG);
+ first_mid = rtc1_read(ETIMEMREG);
+ first_high = rtc1_read(ETIMEHREG);
+ second_low = rtc1_read(ETIMELREG);
+ second_mid = rtc1_read(ETIMEMREG);
+ second_high = rtc1_read(ETIMEHREG);
+ } while (first_low != second_low || first_mid != second_mid ||
+ first_high != second_high);
+
+ return (first_high << 17) | (first_mid << 1) | (first_low >> 15);
+}
+
+static inline void write_elapsed_second(unsigned long sec)
+{
+ spin_lock_irq(&rtc_lock);
+
+ rtc1_write(ETIMELREG, (uint16_t)(sec << 15));
+ rtc1_write(ETIMEMREG, (uint16_t)(sec >> 1));
+ rtc1_write(ETIMEHREG, (uint16_t)(sec >> 17));
+
+ spin_unlock_irq(&rtc_lock);
+}
+
+static void vr41xx_rtc_release(struct device *dev)
+{
+
+ spin_lock_irq(&rtc_lock);
+
+ rtc1_write(ECMPLREG, 0);
+ rtc1_write(ECMPMREG, 0);
+ rtc1_write(ECMPHREG, 0);
+ rtc1_write(RTCL1LREG, 0);
+ rtc1_write(RTCL1HREG, 0);
+
+ spin_unlock_irq(&rtc_lock);
+
+ disable_irq(ELAPSEDTIME_IRQ);
+ disable_irq(RTCLONG1_IRQ);
+}
+
+static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
+{
+ unsigned long epoch_sec, elapsed_sec;
+
+ epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
+ elapsed_sec = read_elapsed_second();
+
+ rtc_time_to_tm(epoch_sec + elapsed_sec, time);
+
+ return 0;
+}
+
+static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
+{
+ unsigned long epoch_sec, current_sec;
+
+ epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
+ current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
+ time->tm_hour, time->tm_min, time->tm_sec);
+
+ write_elapsed_second(current_sec - epoch_sec);
+
+ return 0;
+}
+
+static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+ unsigned long low, mid, high;
+ struct rtc_time *time = &wkalrm->time;
+
+ spin_lock_irq(&rtc_lock);
+
+ low = rtc1_read(ECMPLREG);
+ mid = rtc1_read(ECMPMREG);
+ high = rtc1_read(ECMPHREG);
+
+ spin_unlock_irq(&rtc_lock);
+
+ rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
+
+ return 0;
+}
+
+static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+ unsigned long alarm_sec;
+ struct rtc_time *time = &wkalrm->time;
+
+ alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
+ time->tm_hour, time->tm_min, time->tm_sec);
+
+ spin_lock_irq(&rtc_lock);
+
+ rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
+ rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
+ rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
+
+ spin_unlock_irq(&rtc_lock);
+
+ return 0;
+}
+
+static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ unsigned long count;
+
+ switch (cmd) {
+ case RTC_AIE_ON:
+ enable_irq(ELAPSEDTIME_IRQ);
+ break;
+ case RTC_AIE_OFF:
+ disable_irq(ELAPSEDTIME_IRQ);
+ break;
+ case RTC_PIE_ON:
+ enable_irq(RTCLONG1_IRQ);
+ break;
+ case RTC_PIE_OFF:
+ disable_irq(RTCLONG1_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;
+
+ if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0)
+ return -EACCES;
+
+ 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:
+ return put_user(epoch, (unsigned long __user *)arg);
+ case RTC_EPOCH_SET:
+ /* Doesn't support before 1900 */
+ if (arg < 1900)
+ return -EINVAL;
+
+ if (capable(CAP_SYS_TIME) == 0)
+ return -EACCES;
+
+ epoch = arg;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct platform_device *pdev = (struct platform_device *)dev_id;
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
+
+ rtc_update_irq(&rtc->class_dev, 1, RTC_AF);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct platform_device *pdev = (struct platform_device *)dev_id;
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+ unsigned long count = periodic_count;
+
+ rtc2_write(RTCINTREG, RTCLONG1_INT);
+
+ rtc1_write(RTCL1LREG, count);
+ rtc1_write(RTCL1HREG, count >> 16);
+
+ rtc_update_irq(&rtc->class_dev, 1, RTC_PF);
+
+ return IRQ_HANDLED;
+}
+
+static struct rtc_class_ops vr41xx_rtc_ops = {
+ .release = vr41xx_rtc_release,
+ .ioctl = vr41xx_rtc_ioctl,
+ .read_time = vr41xx_rtc_read_time,
+ .set_time = vr41xx_rtc_set_time,
+ .read_alarm = vr41xx_rtc_read_alarm,
+ .set_alarm = vr41xx_rtc_set_alarm,
+};
+
+static int __devinit rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc;
+ unsigned int irq;
+ int retval;
+
+ if (pdev->num_resources != 2)
+ return -EBUSY;
+
+ rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE);
+ if (rtc1_base == NULL)
+ return -EBUSY;
+
+ rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE);
+ if (rtc2_base == NULL) {
+ iounmap(rtc1_base);
+ rtc1_base = NULL;
+ return -EBUSY;
+ }
+
+ rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ iounmap(rtc1_base);
+ iounmap(rtc2_base);
+ rtc1_base = NULL;
+ rtc2_base = NULL;
+ return PTR_ERR(rtc);
+ }
+
+ spin_lock_irq(&rtc_lock);
+
+ rtc1_write(ECMPLREG, 0);
+ rtc1_write(ECMPMREG, 0);
+ rtc1_write(ECMPHREG, 0);
+ rtc1_write(RTCL1LREG, 0);
+ rtc1_write(RTCL1HREG, 0);
+
+ spin_unlock_irq(&rtc_lock);
+
+ irq = ELAPSEDTIME_IRQ;
+ retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT,
+ "elapsed_time", pdev);
+ if (retval == 0) {
+ irq = RTCLONG1_IRQ;
+ retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT,
+ "rtclong1", pdev);
+ }
+
+ if (retval < 0) {
+ printk(KERN_ERR "rtc: IRQ%d is busy\n", irq);
+ rtc_device_unregister(rtc);
+ if (irq == RTCLONG1_IRQ)
+ free_irq(ELAPSEDTIME_IRQ, NULL);
+ iounmap(rtc1_base);
+ iounmap(rtc2_base);
+ rtc1_base = NULL;
+ rtc2_base = NULL;
+ return retval;
+ }
+
+ platform_set_drvdata(pdev, rtc);
+
+ disable_irq(ELAPSEDTIME_IRQ);
+ disable_irq(RTCLONG1_IRQ);
+
+ printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n");
+
+ return 0;
+}
+
+static int __devexit rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc;
+
+ rtc = platform_get_drvdata(pdev);
+ if (rtc != NULL)
+ rtc_device_unregister(rtc);
+
+ platform_set_drvdata(pdev, NULL);
+
+ free_irq(ELAPSEDTIME_IRQ, NULL);
+ free_irq(RTCLONG1_IRQ, NULL);
+ if (rtc1_base != NULL)
+ iounmap(rtc1_base);
+ if (rtc2_base != NULL)
+ iounmap(rtc2_base);
+
+ return 0;
+}
+
+static struct platform_device *rtc_platform_device;
+
+static struct platform_driver rtc_platform_driver = {
+ .probe = rtc_probe,
+ .remove = __devexit_p(rtc_remove),
+ .driver = {
+ .name = rtc_name,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init vr41xx_rtc_init(void)
+{
+ int retval;
+
+ switch (current_cpu_data.cputype) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ rtc_resource[0].start = RTC1_TYPE1_START;
+ rtc_resource[0].end = RTC1_TYPE1_END;
+ rtc_resource[1].start = RTC2_TYPE1_START;
+ rtc_resource[1].end = RTC2_TYPE1_END;
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ rtc_resource[0].start = RTC1_TYPE2_START;
+ rtc_resource[0].end = RTC1_TYPE2_END;
+ rtc_resource[1].start = RTC2_TYPE2_START;
+ rtc_resource[1].end = RTC2_TYPE2_END;
+ break;
+ default:
+ return -ENODEV;
+ break;
+ }
+
+ rtc_platform_device = platform_device_alloc("RTC", -1);
+ if (rtc_platform_device == NULL)
+ return -ENOMEM;
+
+ retval = platform_device_add_resources(rtc_platform_device,
+ rtc_resource, ARRAY_SIZE(rtc_resource));
+
+ if (retval == 0)
+ retval = platform_device_add(rtc_platform_device);
+
+ if (retval < 0) {
+ platform_device_put(rtc_platform_device);
+ return retval;
+ }
+
+ retval = platform_driver_register(&rtc_platform_driver);
+ if (retval < 0)
+ platform_device_unregister(rtc_platform_device);
+
+ return retval;
+}
+
+static void __exit vr41xx_rtc_exit(void)
+{
+ platform_driver_unregister(&rtc_platform_driver);
+ platform_device_unregister(rtc_platform_device);
+}
+
+module_init(vr41xx_rtc_init);
+module_exit(vr41xx_rtc_exit);
--
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 09/10] RTC subsystem, VR41XX driver
2006-03-31 10:04 ` [PATCH 09/10] RTC subsystem, VR41XX driver Alessandro Zummo
@ 2006-04-01 23:20 ` Andrew Morton
0 siblings, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2006-04-01 23:20 UTC (permalink / raw)
To: Alessandro Zummo; +Cc: linux-kernel, akpm, yoichi_yuasa
Alessandro Zummo <a.zummo@towertech.it> wrote:
>
> This patch updates VR4100 series RTC driver.
It also renames the driver's .c file. This makes it quite hard for
reviewers to see what was changed.
When you have patches which move large amounts of code around, please make
sure that the patch does *only* that. Functional changes should happen in
later patches.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 10/10] RTC subsystem, VR41XX cleanup
2006-03-31 10:04 [PATCH 00/10] RTC subsystem Alessandro Zummo
` (8 preceding siblings ...)
2006-03-31 10:04 ` [PATCH 09/10] RTC subsystem, VR41XX driver Alessandro Zummo
@ 2006-03-31 10:04 ` Alessandro Zummo
[not found] ` <Pine.LNX.4.63.0605030826290.1846@pcgl.dsa-ac.de>
10 siblings, 0 replies; 14+ messages in thread
From: Alessandro Zummo @ 2006-03-31 10:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, akpm, Yoichi Yuasa
[-- Attachment #1: rtc-subsys-drv-vr41xx-kconfig.patch --]
[-- Type: text/plain, Size: 852 bytes --]
Cleaned up kconfig entry for the rtc-vr41xx.
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
CC: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
---
drivers/rtc/Kconfig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- linux-rtc.orig/drivers/rtc/Kconfig 2006-03-31 11:39:15.000000000 +0200
+++ linux-rtc/drivers/rtc/Kconfig 2006-03-31 11:49:09.000000000 +0200
@@ -148,8 +148,14 @@ config RTC_DRV_SA1100
module will be called rtc-sa1100.
config RTC_DRV_VR41XX
- tristate "NEC VR4100 series RTC"
+ tristate "NEC VR41XX"
depends on RTC_CLASS && CPU_VR41XX
+ help
+ If you say Y here you will get access to the real time clock
+ built into your NEC VR41XX CPU.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rtc-vr41xx.
config RTC_DRV_TEST
tristate "Test driver/device"
--
^ permalink raw reply [flat|nested] 14+ messages in thread[parent not found: <Pine.LNX.4.63.0605030826290.1846@pcgl.dsa-ac.de>]