diff options
| author | Jeff Garzik <jeff@garzik.org> | 2006-04-12 16:54:43 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-04-12 16:54:43 -0400 |
| commit | a890b15c0990cc8d686edcc85f5fccde71ad5ce9 (patch) | |
| tree | 73162355b58283a2531f13fbbf663809f95c1483 /drivers/rtc | |
| parent | 79fa1b677be3a985cc66b9218a4dd09818f1051b (diff) | |
| parent | 26ec634c31a11a003040e10b4d650495158632fd (diff) | |
Merge branch 'upstream'
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 | ||
