aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/rtc-ds1302.c66
1 files changed, 15 insertions, 51 deletions
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 184556620778..c64e2d7871b2 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -1,26 +1,25 @@
1/* 1/*
2 * Dallas DS1302 RTC Support 2 * Dallas DS1302 RTC Support
3 * 3 *
4 * Copyright (C) 2002 David McCullough 4 * Copyright (C) 2002 David McCullough
5 * Copyright (C) 2003 - 2007 Paul Mundt 5 * Copyright (C) 2003 - 2007 Paul Mundt
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License version 2. See the file "COPYING" in the main directory of 8 * License version 2. See the file "COPYING" in the main directory of
9 * this archive for more details. 9 * this archive for more details.
10 */ 10 */
11
11#include <linux/init.h> 12#include <linux/init.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/time.h>
16#include <linux/rtc.h> 16#include <linux/rtc.h>
17#include <linux/spinlock.h>
18#include <linux/io.h> 17#include <linux/io.h>
19#include <linux/bcd.h> 18#include <linux/bcd.h>
20#include <asm/rtc.h> 19#include <asm/rtc.h>
21 20
22#define DRV_NAME "rtc-ds1302" 21#define DRV_NAME "rtc-ds1302"
23#define DRV_VERSION "0.1.0" 22#define DRV_VERSION "0.1.1"
24 23
25#define RTC_CMD_READ 0x81 /* Read command */ 24#define RTC_CMD_READ 0x81 /* Read command */
26#define RTC_CMD_WRITE 0x80 /* Write command */ 25#define RTC_CMD_WRITE 0x80 /* Write command */
@@ -47,11 +46,6 @@
47#error "Add support for your platform" 46#error "Add support for your platform"
48#endif 47#endif
49 48
50struct ds1302_rtc {
51 struct rtc_device *rtc_dev;
52 spinlock_t lock;
53};
54
55static void ds1302_sendbits(unsigned int val) 49static void ds1302_sendbits(unsigned int val)
56{ 50{
57 int i; 51 int i;
@@ -105,8 +99,6 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
105{ 99{
106 struct ds1302_rtc *rtc = dev_get_drvdata(dev); 100 struct ds1302_rtc *rtc = dev_get_drvdata(dev);
107 101
108 spin_lock_irq(&rtc->lock);
109
110 tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC)); 102 tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
111 tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN)); 103 tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
112 tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR)); 104 tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
@@ -118,26 +110,17 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
118 if (tm->tm_year < 70) 110 if (tm->tm_year < 70)
119 tm->tm_year += 100; 111 tm->tm_year += 100;
120 112
121 spin_unlock_irq(&rtc->lock);
122
123 dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " 113 dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
124 "mday=%d, mon=%d, year=%d, wday=%d\n", 114 "mday=%d, mon=%d, year=%d, wday=%d\n",
125 __func__, 115 __func__,
126 tm->tm_sec, tm->tm_min, tm->tm_hour, 116 tm->tm_sec, tm->tm_min, tm->tm_hour,
127 tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); 117 tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
128 118
129 if (rtc_valid_tm(tm) < 0) 119 return rtc_valid_tm(tm);
130 dev_err(dev, "invalid date\n");
131
132 return 0;
133} 120}
134 121
135static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) 122static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
136{ 123{
137 struct ds1302_rtc *rtc = dev_get_drvdata(dev);
138
139 spin_lock_irq(&rtc->lock);
140
141 /* Stop RTC */ 124 /* Stop RTC */
142 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); 125 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
143 126
@@ -152,8 +135,6 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
152 /* Start RTC */ 135 /* Start RTC */
153 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); 136 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
154 137
155 spin_unlock_irq(&rtc->lock);
156
157 return 0; 138 return 0;
158} 139}
159 140
@@ -170,9 +151,7 @@ static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
170 if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int))) 151 if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
171 return -EFAULT; 152 return -EFAULT;
172 153
173 spin_lock_irq(&rtc->lock);
174 ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf)); 154 ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
175 spin_unlock_irq(&rtc->lock);
176 return 0; 155 return 0;
177 } 156 }
178#endif 157#endif
@@ -187,9 +166,9 @@ static struct rtc_class_ops ds1302_rtc_ops = {
187 .ioctl = ds1302_rtc_ioctl, 166 .ioctl = ds1302_rtc_ioctl,
188}; 167};
189 168
190static int __devinit ds1302_rtc_probe(struct platform_device *pdev) 169static int __init ds1302_rtc_probe(struct platform_device *pdev)
191{ 170{
192 struct ds1302_rtc *rtc; 171 struct rtc_device *rtc;
193 int ret; 172 int ret;
194 173
195 /* Reset */ 174 /* Reset */
@@ -200,37 +179,23 @@ static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
200 if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) 179 if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
201 return -ENODEV; 180 return -ENODEV;
202 181
203 rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL); 182 rtc = rtc_device_register("ds1302", &pdev->dev,
204 if (unlikely(!rtc))
205 return -ENOMEM;
206
207 spin_lock_init(&rtc->lock);
208 rtc->rtc_dev = rtc_device_register("ds1302", &pdev->dev,
209 &ds1302_rtc_ops, THIS_MODULE); 183 &ds1302_rtc_ops, THIS_MODULE);
210 if (IS_ERR(rtc->rtc_dev)) { 184 if (IS_ERR(rtc))
211 ret = PTR_ERR(rtc->rtc_dev); 185 return PTR_ERR(rtc);
212 goto out;
213 }
214 186
215 platform_set_drvdata(pdev, rtc); 187 platform_set_drvdata(pdev, rtc);
216 188
217 return 0; 189 return 0;
218out:
219 kfree(rtc);
220 return ret;
221} 190}
222 191
223static int __devexit ds1302_rtc_remove(struct platform_device *pdev) 192static int __devexit ds1302_rtc_remove(struct platform_device *pdev)
224{ 193{
225 struct ds1302_rtc *rtc = platform_get_drvdata(pdev); 194 struct rtc_device *rtc = platform_get_drvdata(pdev);
226
227 if (likely(rtc->rtc_dev))
228 rtc_device_unregister(rtc->rtc_dev);
229 195
196 rtc_device_unregister(rtc);
230 platform_set_drvdata(pdev, NULL); 197 platform_set_drvdata(pdev, NULL);
231 198
232 kfree(rtc);
233
234 return 0; 199 return 0;
235} 200}
236 201
@@ -239,13 +204,12 @@ static struct platform_driver ds1302_platform_driver = {
239 .name = DRV_NAME, 204 .name = DRV_NAME,
240 .owner = THIS_MODULE, 205 .owner = THIS_MODULE,
241 }, 206 },
242 .probe = ds1302_rtc_probe, 207 .remove = __exit_p(ds1302_rtc_remove),
243 .remove = __devexit_p(ds1302_rtc_remove),
244}; 208};
245 209
246static int __init ds1302_rtc_init(void) 210static int __init ds1302_rtc_init(void)
247{ 211{
248 return platform_driver_register(&ds1302_platform_driver); 212 return platform_driver_probe(&ds1302_platform_driver, ds1302_rtc_probe);
249} 213}
250 214
251static void __exit ds1302_rtc_exit(void) 215static void __exit ds1302_rtc_exit(void)