diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/class.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1672.c | 72 | ||||
-rw-r--r-- | drivers/rtc/rtc-ep93xx.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-m48t86.c | 9 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8563.c | 11 | ||||
-rw-r--r-- | drivers/rtc/rtc-proc.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-rs5c372.c | 28 | ||||
-rw-r--r-- | drivers/rtc/rtc-sa1100.c | 14 | ||||
-rw-r--r-- | drivers/rtc/rtc-test.c | 3 | ||||
-rw-r--r-- | drivers/rtc/rtc-vr41xx.c | 471 | ||||
-rw-r--r-- | drivers/rtc/rtc-x1205.c | 29 |
13 files changed, 575 insertions, 79 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 929dd8090578..65d090dbef46 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -147,6 +147,16 @@ config RTC_DRV_SA1100 | |||
147 | To compile this driver as a module, choose M here: the | 147 | To compile this driver as a module, choose M here: the |
148 | module will be called rtc-sa1100. | 148 | module will be called rtc-sa1100. |
149 | 149 | ||
150 | config RTC_DRV_VR41XX | ||
151 | tristate "NEC VR41XX" | ||
152 | depends on RTC_CLASS && CPU_VR41XX | ||
153 | help | ||
154 | If you say Y here you will get access to the real time clock | ||
155 | built into your NEC VR41XX CPU. | ||
156 | |||
157 | To compile this driver as a module, choose M here: the | ||
158 | module will be called rtc-vr41xx. | ||
159 | |||
150 | config RTC_DRV_TEST | 160 | config RTC_DRV_TEST |
151 | tristate "Test driver/device" | 161 | tristate "Test driver/device" |
152 | depends on RTC_CLASS | 162 | depends on RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 8d4c7fe88d58..a9ca0f171686 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -19,3 +19,4 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | |||
19 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 19 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
20 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 20 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
21 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 21 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
22 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | ||
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 8533936d50d8..413c7d54ea10 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -96,6 +96,8 @@ exit_idr: | |||
96 | idr_remove(&rtc_idr, id); | 96 | idr_remove(&rtc_idr, id); |
97 | 97 | ||
98 | exit: | 98 | exit: |
99 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", | ||
100 | name, err); | ||
99 | return ERR_PTR(err); | 101 | return ERR_PTR(err); |
100 | } | 102 | } |
101 | EXPORT_SYMBOL_GPL(rtc_device_register); | 103 | EXPORT_SYMBOL_GPL(rtc_device_register); |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 358695a416f3..9be81fd4737c 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * An rtc/i2c driver for the Dallas DS1672 | 2 | * An rtc/i2c driver for the Dallas DS1672 |
3 | * Copyright 2005 Alessandro Zummo | 3 | * Copyright 2005-06 Tower Technologies |
4 | * | ||
5 | * Author: Alessandro Zummo <a.zummo@towertech.it> | ||
4 | * | 6 | * |
5 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,7 +13,7 @@ | |||
11 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
12 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
13 | 15 | ||
14 | #define DRV_VERSION "0.2" | 16 | #define DRV_VERSION "0.3" |
15 | 17 | ||
16 | /* Addresses to scan: none. This chip cannot be detected. */ | 18 | /* Addresses to scan: none. This chip cannot be detected. */ |
17 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | 19 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
@@ -25,6 +27,7 @@ I2C_CLIENT_INSMOD; | |||
25 | #define DS1672_REG_CONTROL 4 | 27 | #define DS1672_REG_CONTROL 4 |
26 | #define DS1672_REG_TRICKLE 5 | 28 | #define DS1672_REG_TRICKLE 5 |
27 | 29 | ||
30 | #define DS1672_REG_CONTROL_EOSC 0x80 | ||
28 | 31 | ||
29 | /* Prototypes */ | 32 | /* Prototypes */ |
30 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); | 33 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); |
@@ -53,8 +56,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
53 | 56 | ||
54 | dev_dbg(&client->dev, | 57 | dev_dbg(&client->dev, |
55 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" | 58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" |
56 | __FUNCTION__, | 59 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); |
57 | buf[0], buf[1], buf[2], buf[3]); | ||
58 | 60 | ||
59 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | 61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
60 | 62 | ||
@@ -62,8 +64,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
62 | 64 | ||
63 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 65 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
64 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 66 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
65 | __FUNCTION__, | 67 | __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, |
66 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
67 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 68 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
68 | 69 | ||
69 | return 0; | 70 | return 0; |
@@ -72,16 +73,17 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
72 | static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) | 73 | static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) |
73 | { | 74 | { |
74 | int xfer; | 75 | int xfer; |
75 | unsigned char buf[5]; | 76 | unsigned char buf[6]; |
76 | 77 | ||
77 | buf[0] = DS1672_REG_CNT_BASE; | 78 | buf[0] = DS1672_REG_CNT_BASE; |
78 | buf[1] = secs & 0x000000FF; | 79 | buf[1] = secs & 0x000000FF; |
79 | buf[2] = (secs & 0x0000FF00) >> 8; | 80 | buf[2] = (secs & 0x0000FF00) >> 8; |
80 | buf[3] = (secs & 0x00FF0000) >> 16; | 81 | buf[3] = (secs & 0x00FF0000) >> 16; |
81 | buf[4] = (secs & 0xFF000000) >> 24; | 82 | buf[4] = (secs & 0xFF000000) >> 24; |
83 | buf[5] = 0; /* set control reg to enable counting */ | ||
82 | 84 | ||
83 | xfer = i2c_master_send(client, buf, 5); | 85 | xfer = i2c_master_send(client, buf, 6); |
84 | if (xfer != 5) { | 86 | if (xfer != 6) { |
85 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); | 87 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); |
86 | return -EIO; | 88 | return -EIO; |
87 | } | 89 | } |
@@ -120,6 +122,40 @@ static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) | |||
120 | return ds1672_set_mmss(to_i2c_client(dev), secs); | 122 | return ds1672_set_mmss(to_i2c_client(dev), secs); |
121 | } | 123 | } |
122 | 124 | ||
125 | static int ds1672_get_control(struct i2c_client *client, u8 *status) | ||
126 | { | ||
127 | unsigned char addr = DS1672_REG_CONTROL; | ||
128 | |||
129 | struct i2c_msg msgs[] = { | ||
130 | { client->addr, 0, 1, &addr }, /* setup read ptr */ | ||
131 | { client->addr, I2C_M_RD, 1, status }, /* read control */ | ||
132 | }; | ||
133 | |||
134 | /* read control register */ | ||
135 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | ||
136 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* following are the sysfs callback functions */ | ||
144 | static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf) | ||
145 | { | ||
146 | struct i2c_client *client = to_i2c_client(dev); | ||
147 | u8 control; | ||
148 | int err; | ||
149 | |||
150 | err = ds1672_get_control(client, &control); | ||
151 | if (err) | ||
152 | return err; | ||
153 | |||
154 | return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) | ||
155 | ? "disabled" : "enabled"); | ||
156 | } | ||
157 | static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); | ||
158 | |||
123 | static struct rtc_class_ops ds1672_rtc_ops = { | 159 | static struct rtc_class_ops ds1672_rtc_ops = { |
124 | .read_time = ds1672_rtc_read_time, | 160 | .read_time = ds1672_rtc_read_time, |
125 | .set_time = ds1672_rtc_set_time, | 161 | .set_time = ds1672_rtc_set_time, |
@@ -128,7 +164,6 @@ static struct rtc_class_ops ds1672_rtc_ops = { | |||
128 | 164 | ||
129 | static int ds1672_attach(struct i2c_adapter *adapter) | 165 | static int ds1672_attach(struct i2c_adapter *adapter) |
130 | { | 166 | { |
131 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
132 | return i2c_probe(adapter, &addr_data, ds1672_probe); | 167 | return i2c_probe(adapter, &addr_data, ds1672_probe); |
133 | } | 168 | } |
134 | 169 | ||
@@ -137,8 +172,6 @@ static int ds1672_detach(struct i2c_client *client) | |||
137 | int err; | 172 | int err; |
138 | struct rtc_device *rtc = i2c_get_clientdata(client); | 173 | struct rtc_device *rtc = i2c_get_clientdata(client); |
139 | 174 | ||
140 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
141 | |||
142 | if (rtc) | 175 | if (rtc) |
143 | rtc_device_unregister(rtc); | 176 | rtc_device_unregister(rtc); |
144 | 177 | ||
@@ -162,6 +195,7 @@ static struct i2c_driver ds1672_driver = { | |||
162 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | 195 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) |
163 | { | 196 | { |
164 | int err = 0; | 197 | int err = 0; |
198 | u8 control; | ||
165 | struct i2c_client *client; | 199 | struct i2c_client *client; |
166 | struct rtc_device *rtc; | 200 | struct rtc_device *rtc; |
167 | 201 | ||
@@ -195,13 +229,23 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | |||
195 | 229 | ||
196 | if (IS_ERR(rtc)) { | 230 | if (IS_ERR(rtc)) { |
197 | err = PTR_ERR(rtc); | 231 | err = PTR_ERR(rtc); |
198 | dev_err(&client->dev, | ||
199 | "unable to register the class device\n"); | ||
200 | goto exit_detach; | 232 | goto exit_detach; |
201 | } | 233 | } |
202 | 234 | ||
203 | i2c_set_clientdata(client, rtc); | 235 | i2c_set_clientdata(client, rtc); |
204 | 236 | ||
237 | /* read control register */ | ||
238 | err = ds1672_get_control(client, &control); | ||
239 | if (err) | ||
240 | goto exit_detach; | ||
241 | |||
242 | if (control & DS1672_REG_CONTROL_EOSC) | ||
243 | dev_warn(&client->dev, "Oscillator not enabled. " | ||
244 | "Set time to enable.\n"); | ||
245 | |||
246 | /* Register sysfs hooks */ | ||
247 | device_create_file(&client->dev, &dev_attr_control); | ||
248 | |||
205 | return 0; | 249 | return 0; |
206 | 250 | ||
207 | exit_detach: | 251 | exit_detach: |
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 0dd80ea686a9..e1a1169e4664 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -67,7 +67,6 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | |||
67 | 67 | ||
68 | ep93xx_get_swcomp(dev, &preload, &delete); | 68 | ep93xx_get_swcomp(dev, &preload, &delete); |
69 | 69 | ||
70 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
71 | seq_printf(seq, "preload\t\t: %d\n", preload); | 70 | seq_printf(seq, "preload\t\t: %d\n", preload); |
72 | seq_printf(seq, "delete\t\t: %d\n", delete); | 71 | seq_printf(seq, "delete\t\t: %d\n", delete); |
73 | 72 | ||
@@ -110,7 +109,6 @@ static int __devinit ep93xx_rtc_probe(struct platform_device *dev) | |||
110 | &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); | 109 | &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); |
111 | 110 | ||
112 | if (IS_ERR(rtc)) { | 111 | if (IS_ERR(rtc)) { |
113 | dev_err(&dev->dev, "unable to register\n"); | ||
114 | return PTR_ERR(rtc); | 112 | return PTR_ERR(rtc); |
115 | } | 113 | } |
116 | 114 | ||
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index db445c872b1b..f6e7ee04f3dc 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define M48T86_REG_SECALRM 0x01 | 23 | #define M48T86_REG_SECALRM 0x01 |
24 | #define M48T86_REG_MIN 0x02 | 24 | #define M48T86_REG_MIN 0x02 |
25 | #define M48T86_REG_MINALRM 0x03 | 25 | #define M48T86_REG_MINALRM 0x03 |
26 | #define M48T86_REG_HOUR 0x04 | 26 | #define M48T86_REG_HOUR 0x04 |
27 | #define M48T86_REG_HOURALRM 0x05 | 27 | #define M48T86_REG_HOURALRM 0x05 |
28 | #define M48T86_REG_DOW 0x06 /* 1 = sunday */ | 28 | #define M48T86_REG_DOW 0x06 /* 1 = sunday */ |
29 | #define M48T86_REG_DOM 0x07 | 29 | #define M48T86_REG_DOM 0x07 |
@@ -127,9 +127,6 @@ static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq) | |||
127 | 127 | ||
128 | reg = ops->readb(M48T86_REG_B); | 128 | reg = ops->readb(M48T86_REG_B); |
129 | 129 | ||
130 | seq_printf(seq, "24hr\t\t: %s\n", | ||
131 | (reg & M48T86_REG_B_H24) ? "yes" : "no"); | ||
132 | |||
133 | seq_printf(seq, "mode\t\t: %s\n", | 130 | seq_printf(seq, "mode\t\t: %s\n", |
134 | (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); | 131 | (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); |
135 | 132 | ||
@@ -154,10 +151,8 @@ static int __devinit m48t86_rtc_probe(struct platform_device *dev) | |||
154 | struct rtc_device *rtc = rtc_device_register("m48t86", | 151 | struct rtc_device *rtc = rtc_device_register("m48t86", |
155 | &dev->dev, &m48t86_rtc_ops, THIS_MODULE); | 152 | &dev->dev, &m48t86_rtc_ops, THIS_MODULE); |
156 | 153 | ||
157 | if (IS_ERR(rtc)) { | 154 | if (IS_ERR(rtc)) |
158 | dev_err(&dev->dev, "unable to register\n"); | ||
159 | return PTR_ERR(rtc); | 155 | return PTR_ERR(rtc); |
160 | } | ||
161 | 156 | ||
162 | platform_set_drvdata(dev, rtc); | 157 | platform_set_drvdata(dev, rtc); |
163 | 158 | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index d857d45bdbe8..ba9a583b7b68 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -227,14 +227,7 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
227 | return pcf8563_set_datetime(to_i2c_client(dev), tm); | 227 | return pcf8563_set_datetime(to_i2c_client(dev), tm); |
228 | } | 228 | } |
229 | 229 | ||
230 | static int pcf8563_rtc_proc(struct device *dev, struct seq_file *seq) | ||
231 | { | ||
232 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct rtc_class_ops pcf8563_rtc_ops = { | 230 | static struct rtc_class_ops pcf8563_rtc_ops = { |
237 | .proc = pcf8563_rtc_proc, | ||
238 | .read_time = pcf8563_rtc_read_time, | 231 | .read_time = pcf8563_rtc_read_time, |
239 | .set_time = pcf8563_rtc_set_time, | 232 | .set_time = pcf8563_rtc_set_time, |
240 | }; | 233 | }; |
@@ -297,8 +290,6 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) | |||
297 | 290 | ||
298 | if (IS_ERR(rtc)) { | 291 | if (IS_ERR(rtc)) { |
299 | err = PTR_ERR(rtc); | 292 | err = PTR_ERR(rtc); |
300 | dev_err(&client->dev, | ||
301 | "unable to register the class device\n"); | ||
302 | goto exit_detach; | 293 | goto exit_detach; |
303 | } | 294 | } |
304 | 295 | ||
@@ -321,8 +312,6 @@ static int pcf8563_detach(struct i2c_client *client) | |||
321 | int err; | 312 | int err; |
322 | struct rtc_device *rtc = i2c_get_clientdata(client); | 313 | struct rtc_device *rtc = i2c_get_clientdata(client); |
323 | 314 | ||
324 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
325 | |||
326 | if (rtc) | 315 | if (rtc) |
327 | rtc_device_unregister(rtc); | 316 | rtc_device_unregister(rtc); |
328 | 317 | ||
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 90b8a97a0919..cef5f5a3bbf9 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -71,6 +71,8 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
71 | alrm.pending ? "yes" : "no"); | 71 | alrm.pending ? "yes" : "no"); |
72 | } | 72 | } |
73 | 73 | ||
74 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
75 | |||
74 | if (ops->proc) | 76 | if (ops->proc) |
75 | ops->proc(class_dev->dev, seq); | 77 | ops->proc(class_dev->dev, seq); |
76 | 78 | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 396c8681f66c..7553d797603f 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -151,9 +151,8 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) | |||
151 | { | 151 | { |
152 | int err, osc, trim; | 152 | int err, osc, trim; |
153 | 153 | ||
154 | seq_printf(seq, "24hr\t\t: yes\n"); | 154 | err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim); |
155 | 155 | if (err == 0) { | |
156 | if ((err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim)) == 0) { | ||
157 | seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); | 156 | seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); |
158 | seq_printf(seq, "trim\t: %d\n", trim); | 157 | seq_printf(seq, "trim\t: %d\n", trim); |
159 | } | 158 | } |
@@ -170,30 +169,31 @@ static struct rtc_class_ops rs5c372_rtc_ops = { | |||
170 | static ssize_t rs5c372_sysfs_show_trim(struct device *dev, | 169 | static ssize_t rs5c372_sysfs_show_trim(struct device *dev, |
171 | struct device_attribute *attr, char *buf) | 170 | struct device_attribute *attr, char *buf) |
172 | { | 171 | { |
173 | int trim; | 172 | int err, trim; |
174 | 173 | ||
175 | if (rs5c372_get_trim(to_i2c_client(dev), NULL, &trim) == 0) | 174 | err = rs5c372_get_trim(to_i2c_client(dev), NULL, &trim); |
176 | return sprintf(buf, "0x%2x\n", trim); | 175 | if (err) |
176 | return err; | ||
177 | 177 | ||
178 | return 0; | 178 | return sprintf(buf, "0x%2x\n", trim); |
179 | } | 179 | } |
180 | static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); | 180 | static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); |
181 | 181 | ||
182 | static ssize_t rs5c372_sysfs_show_osc(struct device *dev, | 182 | static ssize_t rs5c372_sysfs_show_osc(struct device *dev, |
183 | struct device_attribute *attr, char *buf) | 183 | struct device_attribute *attr, char *buf) |
184 | { | 184 | { |
185 | int osc; | 185 | int err, osc; |
186 | 186 | ||
187 | if (rs5c372_get_trim(to_i2c_client(dev), &osc, NULL) == 0) | 187 | err = rs5c372_get_trim(to_i2c_client(dev), &osc, NULL); |
188 | return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); | 188 | if (err) |
189 | return err; | ||
189 | 190 | ||
190 | return 0; | 191 | return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); |
191 | } | 192 | } |
192 | static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); | 193 | static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); |
193 | 194 | ||
194 | static int rs5c372_attach(struct i2c_adapter *adapter) | 195 | static int rs5c372_attach(struct i2c_adapter *adapter) |
195 | { | 196 | { |
196 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
197 | return i2c_probe(adapter, &addr_data, rs5c372_probe); | 197 | return i2c_probe(adapter, &addr_data, rs5c372_probe); |
198 | } | 198 | } |
199 | 199 | ||
@@ -233,8 +233,6 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) | |||
233 | 233 | ||
234 | if (IS_ERR(rtc)) { | 234 | if (IS_ERR(rtc)) { |
235 | err = PTR_ERR(rtc); | 235 | err = PTR_ERR(rtc); |
236 | dev_err(&client->dev, | ||
237 | "unable to register the class device\n"); | ||
238 | goto exit_detach; | 236 | goto exit_detach; |
239 | } | 237 | } |
240 | 238 | ||
@@ -260,8 +258,6 @@ static int rs5c372_detach(struct i2c_client *client) | |||
260 | int err; | 258 | int err; |
261 | struct rtc_device *rtc = i2c_get_clientdata(client); | 259 | struct rtc_device *rtc = i2c_get_clientdata(client); |
262 | 260 | ||
263 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
264 | |||
265 | if (rtc) | 261 | if (rtc) |
266 | rtc_device_unregister(rtc); | 262 | rtc_device_unregister(rtc); |
267 | 263 | ||
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 83b2bb480a16..a23ec54989f6 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -160,19 +160,19 @@ static int sa1100_rtc_open(struct device *dev) | |||
160 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, | 160 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, |
161 | "rtc 1Hz", dev); | 161 | "rtc 1Hz", dev); |
162 | if (ret) { | 162 | if (ret) { |
163 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz); | 163 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
164 | goto fail_ui; | 164 | goto fail_ui; |
165 | } | 165 | } |
166 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, | 166 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, |
167 | "rtc Alrm", dev); | 167 | "rtc Alrm", dev); |
168 | if (ret) { | 168 | if (ret) { |
169 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm); | 169 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
170 | goto fail_ai; | 170 | goto fail_ai; |
171 | } | 171 | } |
172 | ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, | 172 | ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, |
173 | "rtc timer", dev); | 173 | "rtc timer", dev); |
174 | if (ret) { | 174 | if (ret) { |
175 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1); | 175 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); |
176 | goto fail_pi; | 176 | goto fail_pi; |
177 | } | 177 | } |
178 | return 0; | 178 | return 0; |
@@ -332,7 +332,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
332 | */ | 332 | */ |
333 | if (RTTR == 0) { | 333 | if (RTTR == 0) { |
334 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 334 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
335 | printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n"); | 335 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); |
336 | /* The current RTC value probably doesn't make sense either */ | 336 | /* The current RTC value probably doesn't make sense either */ |
337 | RCNR = 0; | 337 | RCNR = 0; |
338 | } | 338 | } |
@@ -340,15 +340,11 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
340 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 340 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
341 | THIS_MODULE); | 341 | THIS_MODULE); |
342 | 342 | ||
343 | if (IS_ERR(rtc)) { | 343 | if (IS_ERR(rtc)) |
344 | dev_err(&pdev->dev, "Unable to register the RTC device\n"); | ||
345 | return PTR_ERR(rtc); | 344 | return PTR_ERR(rtc); |
346 | } | ||
347 | 345 | ||
348 | platform_set_drvdata(pdev, rtc); | 346 | platform_set_drvdata(pdev, rtc); |
349 | 347 | ||
350 | dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n"); | ||
351 | |||
352 | return 0; | 348 | return 0; |
353 | } | 349 | } |
354 | 350 | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 43d107487820..e1f7e8e86daf 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -49,7 +49,6 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq) | |||
49 | { | 49 | { |
50 | struct platform_device *plat_dev = to_platform_device(dev); | 50 | struct platform_device *plat_dev = to_platform_device(dev); |
51 | 51 | ||
52 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
53 | seq_printf(seq, "test\t\t: yes\n"); | 52 | seq_printf(seq, "test\t\t: yes\n"); |
54 | seq_printf(seq, "id\t\t: %d\n", plat_dev->id); | 53 | seq_printf(seq, "id\t\t: %d\n", plat_dev->id); |
55 | 54 | ||
@@ -120,8 +119,6 @@ static int test_probe(struct platform_device *plat_dev) | |||
120 | &test_rtc_ops, THIS_MODULE); | 119 | &test_rtc_ops, THIS_MODULE); |
121 | if (IS_ERR(rtc)) { | 120 | if (IS_ERR(rtc)) { |
122 | err = PTR_ERR(rtc); | 121 | err = PTR_ERR(rtc); |
123 | dev_err(&plat_dev->dev, | ||
124 | "unable to register the class device\n"); | ||
125 | return err; | 122 | return err; |
126 | } | 123 | } |
127 | device_create_file(&plat_dev->dev, &dev_attr_irq); | 124 | device_create_file(&plat_dev->dev, &dev_attr_irq); |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c new file mode 100644 index 000000000000..4d49fd501198 --- /dev/null +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -0,0 +1,471 @@ | |||
1 | /* | ||
2 | * Driver for NEC VR4100 series Real Time Clock unit. | ||
3 | * | ||
4 | * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/rtc.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/types.h> | ||
29 | |||
30 | #include <asm/div64.h> | ||
31 | #include <asm/io.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | #include <asm/vr41xx/vr41xx.h> | ||
34 | |||
35 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | ||
36 | MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); | ||
37 | MODULE_LICENSE("GPL"); | ||
38 | |||
39 | #define RTC1_TYPE1_START 0x0b0000c0UL | ||
40 | #define RTC1_TYPE1_END 0x0b0000dfUL | ||
41 | #define RTC2_TYPE1_START 0x0b0001c0UL | ||
42 | #define RTC2_TYPE1_END 0x0b0001dfUL | ||
43 | |||
44 | #define RTC1_TYPE2_START 0x0f000100UL | ||
45 | #define RTC1_TYPE2_END 0x0f00011fUL | ||
46 | #define RTC2_TYPE2_START 0x0f000120UL | ||
47 | #define RTC2_TYPE2_END 0x0f00013fUL | ||
48 | |||
49 | #define RTC1_SIZE 0x20 | ||
50 | #define RTC2_SIZE 0x20 | ||
51 | |||
52 | /* RTC 1 registers */ | ||
53 | #define ETIMELREG 0x00 | ||
54 | #define ETIMEMREG 0x02 | ||
55 | #define ETIMEHREG 0x04 | ||
56 | /* RFU */ | ||
57 | #define ECMPLREG 0x08 | ||
58 | #define ECMPMREG 0x0a | ||
59 | #define ECMPHREG 0x0c | ||
60 | /* RFU */ | ||
61 | #define RTCL1LREG 0x10 | ||
62 | #define RTCL1HREG 0x12 | ||
63 | #define RTCL1CNTLREG 0x14 | ||
64 | #define RTCL1CNTHREG 0x16 | ||
65 | #define RTCL2LREG 0x18 | ||
66 | #define RTCL2HREG 0x1a | ||
67 | #define RTCL2CNTLREG 0x1c | ||
68 | #define RTCL2CNTHREG 0x1e | ||
69 | |||
70 | /* RTC 2 registers */ | ||
71 | #define TCLKLREG 0x00 | ||
72 | #define TCLKHREG 0x02 | ||
73 | #define TCLKCNTLREG 0x04 | ||
74 | #define TCLKCNTHREG 0x06 | ||
75 | /* RFU */ | ||
76 | #define RTCINTREG 0x1e | ||
77 | #define TCLOCK_INT 0x08 | ||
78 | #define RTCLONG2_INT 0x04 | ||
79 | #define RTCLONG1_INT 0x02 | ||
80 | #define ELAPSEDTIME_INT 0x01 | ||
81 | |||
82 | #define RTC_FREQUENCY 32768 | ||
83 | #define MAX_PERIODIC_RATE 6553 | ||
84 | #define MAX_USER_PERIODIC_RATE 64 | ||
85 | |||
86 | static void __iomem *rtc1_base; | ||
87 | static void __iomem *rtc2_base; | ||
88 | |||
89 | #define rtc1_read(offset) readw(rtc1_base + (offset)) | ||
90 | #define rtc1_write(offset, value) writew((value), rtc1_base + (offset)) | ||
91 | |||
92 | #define rtc2_read(offset) readw(rtc2_base + (offset)) | ||
93 | #define rtc2_write(offset, value) writew((value), rtc2_base + (offset)) | ||
94 | |||
95 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ | ||
96 | |||
97 | static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; | ||
98 | static char rtc_name[] = "RTC"; | ||
99 | static unsigned long periodic_frequency; | ||
100 | static unsigned long periodic_count; | ||
101 | |||
102 | struct resource rtc_resource[2] = { | ||
103 | { .name = rtc_name, | ||
104 | .flags = IORESOURCE_MEM, }, | ||
105 | { .name = rtc_name, | ||
106 | .flags = IORESOURCE_MEM, }, | ||
107 | }; | ||
108 | |||
109 | static inline unsigned long read_elapsed_second(void) | ||
110 | { | ||
111 | |||
112 | unsigned long first_low, first_mid, first_high; | ||
113 | |||
114 | unsigned long second_low, second_mid, second_high; | ||
115 | |||
116 | do { | ||
117 | first_low = rtc1_read(ETIMELREG); | ||
118 | first_mid = rtc1_read(ETIMEMREG); | ||
119 | first_high = rtc1_read(ETIMEHREG); | ||
120 | second_low = rtc1_read(ETIMELREG); | ||
121 | second_mid = rtc1_read(ETIMEMREG); | ||
122 | second_high = rtc1_read(ETIMEHREG); | ||
123 | } while (first_low != second_low || first_mid != second_mid || | ||
124 | first_high != second_high); | ||
125 | |||
126 | return (first_high << 17) | (first_mid << 1) | (first_low >> 15); | ||
127 | } | ||
128 | |||
129 | static inline void write_elapsed_second(unsigned long sec) | ||
130 | { | ||
131 | spin_lock_irq(&rtc_lock); | ||
132 | |||
133 | rtc1_write(ETIMELREG, (uint16_t)(sec << 15)); | ||
134 | rtc1_write(ETIMEMREG, (uint16_t)(sec >> 1)); | ||
135 | rtc1_write(ETIMEHREG, (uint16_t)(sec >> 17)); | ||
136 | |||
137 | spin_unlock_irq(&rtc_lock); | ||
138 | } | ||
139 | |||
140 | static void vr41xx_rtc_release(struct device *dev) | ||
141 | { | ||
142 | |||
143 | spin_lock_irq(&rtc_lock); | ||
144 | |||
145 | rtc1_write(ECMPLREG, 0); | ||
146 | rtc1_write(ECMPMREG, 0); | ||
147 | rtc1_write(ECMPHREG, 0); | ||
148 | rtc1_write(RTCL1LREG, 0); | ||
149 | rtc1_write(RTCL1HREG, 0); | ||
150 | |||
151 | spin_unlock_irq(&rtc_lock); | ||
152 | |||
153 | disable_irq(ELAPSEDTIME_IRQ); | ||
154 | disable_irq(RTCLONG1_IRQ); | ||
155 | } | ||
156 | |||
157 | static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time) | ||
158 | { | ||
159 | unsigned long epoch_sec, elapsed_sec; | ||
160 | |||
161 | epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); | ||
162 | elapsed_sec = read_elapsed_second(); | ||
163 | |||
164 | rtc_time_to_tm(epoch_sec + elapsed_sec, time); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time) | ||
170 | { | ||
171 | unsigned long epoch_sec, current_sec; | ||
172 | |||
173 | epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); | ||
174 | current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, | ||
175 | time->tm_hour, time->tm_min, time->tm_sec); | ||
176 | |||
177 | write_elapsed_second(current_sec - epoch_sec); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | ||
183 | { | ||
184 | unsigned long low, mid, high; | ||
185 | struct rtc_time *time = &wkalrm->time; | ||
186 | |||
187 | spin_lock_irq(&rtc_lock); | ||
188 | |||
189 | low = rtc1_read(ECMPLREG); | ||
190 | mid = rtc1_read(ECMPMREG); | ||
191 | high = rtc1_read(ECMPHREG); | ||
192 | |||
193 | spin_unlock_irq(&rtc_lock); | ||
194 | |||
195 | rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | ||
201 | { | ||
202 | unsigned long alarm_sec; | ||
203 | struct rtc_time *time = &wkalrm->time; | ||
204 | |||
205 | alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, | ||
206 | time->tm_hour, time->tm_min, time->tm_sec); | ||
207 | |||
208 | spin_lock_irq(&rtc_lock); | ||
209 | |||
210 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); | ||
211 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); | ||
212 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); | ||
213 | |||
214 | spin_unlock_irq(&rtc_lock); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
220 | { | ||
221 | unsigned long count; | ||
222 | |||
223 | switch (cmd) { | ||
224 | case RTC_AIE_ON: | ||
225 | enable_irq(ELAPSEDTIME_IRQ); | ||
226 | break; | ||
227 | case RTC_AIE_OFF: | ||
228 | disable_irq(ELAPSEDTIME_IRQ); | ||
229 | break; | ||
230 | case RTC_PIE_ON: | ||
231 | enable_irq(RTCLONG1_IRQ); | ||
232 | break; | ||
233 | case RTC_PIE_OFF: | ||
234 | disable_irq(RTCLONG1_IRQ); | ||
235 | break; | ||
236 | case RTC_IRQP_READ: | ||
237 | return put_user(periodic_frequency, (unsigned long __user *)arg); | ||
238 | break; | ||
239 | case RTC_IRQP_SET: | ||
240 | if (arg > MAX_PERIODIC_RATE) | ||
241 | return -EINVAL; | ||
242 | |||
243 | if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0) | ||
244 | return -EACCES; | ||
245 | |||
246 | periodic_frequency = arg; | ||
247 | |||
248 | count = RTC_FREQUENCY; | ||
249 | do_div(count, arg); | ||
250 | |||
251 | periodic_count = count; | ||
252 | |||
253 | spin_lock_irq(&rtc_lock); | ||
254 | |||
255 | rtc1_write(RTCL1LREG, count); | ||
256 | rtc1_write(RTCL1HREG, count >> 16); | ||
257 | |||
258 | spin_unlock_irq(&rtc_lock); | ||
259 | break; | ||
260 | case RTC_EPOCH_READ: | ||
261 | return put_user(epoch, (unsigned long __user *)arg); | ||
262 | case RTC_EPOCH_SET: | ||
263 | /* Doesn't support before 1900 */ | ||
264 | if (arg < 1900) | ||
265 | return -EINVAL; | ||
266 | |||
267 | if (capable(CAP_SYS_TIME) == 0) | ||
268 | return -EACCES; | ||
269 | |||
270 | epoch = arg; | ||
271 | break; | ||
272 | default: | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
280 | { | ||
281 | struct platform_device *pdev = (struct platform_device *)dev_id; | ||
282 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
283 | |||
284 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); | ||
285 | |||
286 | rtc_update_irq(&rtc->class_dev, 1, RTC_AF); | ||
287 | |||
288 | return IRQ_HANDLED; | ||
289 | } | ||
290 | |||
291 | static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
292 | { | ||
293 | struct platform_device *pdev = (struct platform_device *)dev_id; | ||
294 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
295 | unsigned long count = periodic_count; | ||
296 | |||
297 | rtc2_write(RTCINTREG, RTCLONG1_INT); | ||
298 | |||
299 | rtc1_write(RTCL1LREG, count); | ||
300 | rtc1_write(RTCL1HREG, count >> 16); | ||
301 | |||
302 | rtc_update_irq(&rtc->class_dev, 1, RTC_PF); | ||
303 | |||
304 | return IRQ_HANDLED; | ||
305 | } | ||
306 | |||
307 | static struct rtc_class_ops vr41xx_rtc_ops = { | ||
308 | .release = vr41xx_rtc_release, | ||
309 | .ioctl = vr41xx_rtc_ioctl, | ||
310 | .read_time = vr41xx_rtc_read_time, | ||
311 | .set_time = vr41xx_rtc_set_time, | ||
312 | .read_alarm = vr41xx_rtc_read_alarm, | ||
313 | .set_alarm = vr41xx_rtc_set_alarm, | ||
314 | }; | ||
315 | |||
316 | static int __devinit rtc_probe(struct platform_device *pdev) | ||
317 | { | ||
318 | struct rtc_device *rtc; | ||
319 | unsigned int irq; | ||
320 | int retval; | ||
321 | |||
322 | if (pdev->num_resources != 2) | ||
323 | return -EBUSY; | ||
324 | |||
325 | rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE); | ||
326 | if (rtc1_base == NULL) | ||
327 | return -EBUSY; | ||
328 | |||
329 | rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE); | ||
330 | if (rtc2_base == NULL) { | ||
331 | iounmap(rtc1_base); | ||
332 | rtc1_base = NULL; | ||
333 | return -EBUSY; | ||
334 | } | ||
335 | |||
336 | rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE); | ||
337 | if (IS_ERR(rtc)) { | ||
338 | iounmap(rtc1_base); | ||
339 | iounmap(rtc2_base); | ||
340 | rtc1_base = NULL; | ||
341 | rtc2_base = NULL; | ||
342 | return PTR_ERR(rtc); | ||
343 | } | ||
344 | |||
345 | spin_lock_irq(&rtc_lock); | ||
346 | |||
347 | rtc1_write(ECMPLREG, 0); | ||
348 | rtc1_write(ECMPMREG, 0); | ||
349 | rtc1_write(ECMPHREG, 0); | ||
350 | rtc1_write(RTCL1LREG, 0); | ||
351 | rtc1_write(RTCL1HREG, 0); | ||
352 | |||
353 | spin_unlock_irq(&rtc_lock); | ||
354 | |||
355 | irq = ELAPSEDTIME_IRQ; | ||
356 | retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT, | ||
357 | "elapsed_time", pdev); | ||
358 | if (retval == 0) { | ||
359 | irq = RTCLONG1_IRQ; | ||
360 | retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT, | ||
361 | "rtclong1", pdev); | ||
362 | } | ||
363 | |||
364 | if (retval < 0) { | ||
365 | printk(KERN_ERR "rtc: IRQ%d is busy\n", irq); | ||
366 | rtc_device_unregister(rtc); | ||
367 | if (irq == RTCLONG1_IRQ) | ||
368 | free_irq(ELAPSEDTIME_IRQ, NULL); | ||
369 | iounmap(rtc1_base); | ||
370 | iounmap(rtc2_base); | ||
371 | rtc1_base = NULL; | ||
372 | rtc2_base = NULL; | ||
373 | return retval; | ||
374 | } | ||
375 | |||
376 | platform_set_drvdata(pdev, rtc); | ||
377 | |||
378 | disable_irq(ELAPSEDTIME_IRQ); | ||
379 | disable_irq(RTCLONG1_IRQ); | ||
380 | |||
381 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static int __devexit rtc_remove(struct platform_device *pdev) | ||
387 | { | ||
388 | struct rtc_device *rtc; | ||
389 | |||
390 | rtc = platform_get_drvdata(pdev); | ||
391 | if (rtc != NULL) | ||
392 | rtc_device_unregister(rtc); | ||
393 | |||
394 | platform_set_drvdata(pdev, NULL); | ||
395 | |||
396 | free_irq(ELAPSEDTIME_IRQ, NULL); | ||
397 | free_irq(RTCLONG1_IRQ, NULL); | ||
398 | if (rtc1_base != NULL) | ||
399 | iounmap(rtc1_base); | ||
400 | if (rtc2_base != NULL) | ||
401 | iounmap(rtc2_base); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static struct platform_device *rtc_platform_device; | ||
407 | |||
408 | static struct platform_driver rtc_platform_driver = { | ||
409 | .probe = rtc_probe, | ||
410 | .remove = __devexit_p(rtc_remove), | ||
411 | .driver = { | ||
412 | .name = rtc_name, | ||
413 | .owner = THIS_MODULE, | ||
414 | }, | ||
415 | }; | ||
416 | |||
417 | static int __init vr41xx_rtc_init(void) | ||
418 | { | ||
419 | int retval; | ||
420 | |||
421 | switch (current_cpu_data.cputype) { | ||
422 | case CPU_VR4111: | ||
423 | case CPU_VR4121: | ||
424 | rtc_resource[0].start = RTC1_TYPE1_START; | ||
425 | rtc_resource[0].end = RTC1_TYPE1_END; | ||
426 | rtc_resource[1].start = RTC2_TYPE1_START; | ||
427 | rtc_resource[1].end = RTC2_TYPE1_END; | ||
428 | break; | ||
429 | case CPU_VR4122: | ||
430 | case CPU_VR4131: | ||
431 | case CPU_VR4133: | ||
432 | rtc_resource[0].start = RTC1_TYPE2_START; | ||
433 | rtc_resource[0].end = RTC1_TYPE2_END; | ||
434 | rtc_resource[1].start = RTC2_TYPE2_START; | ||
435 | rtc_resource[1].end = RTC2_TYPE2_END; | ||
436 | break; | ||
437 | default: | ||
438 | return -ENODEV; | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | rtc_platform_device = platform_device_alloc("RTC", -1); | ||
443 | if (rtc_platform_device == NULL) | ||
444 | return -ENOMEM; | ||
445 | |||
446 | retval = platform_device_add_resources(rtc_platform_device, | ||
447 | rtc_resource, ARRAY_SIZE(rtc_resource)); | ||
448 | |||
449 | if (retval == 0) | ||
450 | retval = platform_device_add(rtc_platform_device); | ||
451 | |||
452 | if (retval < 0) { | ||
453 | platform_device_put(rtc_platform_device); | ||
454 | return retval; | ||
455 | } | ||
456 | |||
457 | retval = platform_driver_register(&rtc_platform_driver); | ||
458 | if (retval < 0) | ||
459 | platform_device_unregister(rtc_platform_device); | ||
460 | |||
461 | return retval; | ||
462 | } | ||
463 | |||
464 | static void __exit vr41xx_rtc_exit(void) | ||
465 | { | ||
466 | platform_driver_unregister(&rtc_platform_driver); | ||
467 | platform_device_unregister(rtc_platform_device); | ||
468 | } | ||
469 | |||
470 | module_init(vr41xx_rtc_init); | ||
471 | module_exit(vr41xx_rtc_exit); | ||
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 621d17afc0d9..788b6d1f8f2f 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | 21 | ||
22 | #define DRV_VERSION "1.0.6" | 22 | #define DRV_VERSION "1.0.7" |
23 | 23 | ||
24 | /* Addresses to scan: none. This chip is located at | 24 | /* Addresses to scan: none. This chip is located at |
25 | * 0x6f and uses a two bytes register addressing. | 25 | * 0x6f and uses a two bytes register addressing. |
@@ -451,8 +451,6 @@ static int x1205_rtc_proc(struct device *dev, struct seq_file *seq) | |||
451 | { | 451 | { |
452 | int err, dtrim, atrim; | 452 | int err, dtrim, atrim; |
453 | 453 | ||
454 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
455 | |||
456 | if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) | 454 | if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) |
457 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); | 455 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); |
458 | 456 | ||
@@ -473,30 +471,31 @@ static struct rtc_class_ops x1205_rtc_ops = { | |||
473 | static ssize_t x1205_sysfs_show_atrim(struct device *dev, | 471 | static ssize_t x1205_sysfs_show_atrim(struct device *dev, |
474 | struct device_attribute *attr, char *buf) | 472 | struct device_attribute *attr, char *buf) |
475 | { | 473 | { |
476 | int atrim; | 474 | int err, atrim; |
477 | 475 | ||
478 | if (x1205_get_atrim(to_i2c_client(dev), &atrim) == 0) | 476 | err = x1205_get_atrim(to_i2c_client(dev), &atrim); |
479 | return sprintf(buf, "%d.%02d pF\n", | 477 | if (err) |
480 | atrim / 1000, atrim % 1000); | 478 | return err; |
481 | return 0; | 479 | |
480 | return sprintf(buf, "%d.%02d pF\n", atrim / 1000, atrim % 1000); | ||
482 | } | 481 | } |
483 | static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); | 482 | static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); |
484 | 483 | ||
485 | static ssize_t x1205_sysfs_show_dtrim(struct device *dev, | 484 | static ssize_t x1205_sysfs_show_dtrim(struct device *dev, |
486 | struct device_attribute *attr, char *buf) | 485 | struct device_attribute *attr, char *buf) |
487 | { | 486 | { |
488 | int dtrim; | 487 | int err, dtrim; |
489 | 488 | ||
490 | if (x1205_get_dtrim(to_i2c_client(dev), &dtrim) == 0) | 489 | err = x1205_get_dtrim(to_i2c_client(dev), &dtrim); |
491 | return sprintf(buf, "%d ppm\n", dtrim); | 490 | if (err) |
491 | return err; | ||
492 | 492 | ||
493 | return 0; | 493 | return sprintf(buf, "%d ppm\n", dtrim); |
494 | } | 494 | } |
495 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); | 495 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); |
496 | 496 | ||
497 | static int x1205_attach(struct i2c_adapter *adapter) | 497 | static int x1205_attach(struct i2c_adapter *adapter) |
498 | { | 498 | { |
499 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
500 | return i2c_probe(adapter, &addr_data, x1205_probe); | 499 | return i2c_probe(adapter, &addr_data, x1205_probe); |
501 | } | 500 | } |
502 | 501 | ||
@@ -545,8 +544,6 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | |||
545 | 544 | ||
546 | if (IS_ERR(rtc)) { | 545 | if (IS_ERR(rtc)) { |
547 | err = PTR_ERR(rtc); | 546 | err = PTR_ERR(rtc); |
548 | dev_err(&client->dev, | ||
549 | "unable to register the class device\n"); | ||
550 | goto exit_detach; | 547 | goto exit_detach; |
551 | } | 548 | } |
552 | 549 | ||
@@ -585,8 +582,6 @@ static int x1205_detach(struct i2c_client *client) | |||
585 | int err; | 582 | int err; |
586 | struct rtc_device *rtc = i2c_get_clientdata(client); | 583 | struct rtc_device *rtc = i2c_get_clientdata(client); |
587 | 584 | ||
588 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
589 | |||
590 | if (rtc) | 585 | if (rtc) |
591 | rtc_device_unregister(rtc); | 586 | rtc_device_unregister(rtc); |
592 | 587 | ||