aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds1302.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-18 12:43:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-18 12:43:09 -0400
commit515b696b282f856c3ad1679ccd658120faa387d0 (patch)
treed9d7c1185c396617f128ca23463062308d11393b /drivers/rtc/rtc-ds1302.c
parentfa877c71e2136bd682b45022c96d5e073ced9f58 (diff)
parent064a16dc41be879d12bd5de5d2f9d38d890e0ee7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (262 commits) sh: mach-ecovec24: Add user debug switch support sh: Kill off unused se_skipped in alignment trap notification code. sh: Wire up HAVE_SYSCALL_TRACEPOINTS. video: sh_mobile_lcdcfb: use both register sets for display panning video: sh_mobile_lcdcfb: implement display panning sh: Fix up sh7705 flush_dcache_page() build. sh: kfr2r09: document the PLL/FLL <-> RF relationship. sh: mach-ecovec24: need asm/clock.h. sh: mach-ecovec24: deassert usb irq on boot. sh: Add KEYSC support for EcoVec24 sh: add kycr2_delay for sh_keysc sh: cpufreq: Include CPU id in info messages. sh: multi-evt support for SH-X3 proto CPU. sh: clkfwk: remove bogus set_bus_parent() from SH7709. sh: Fix the indication point of the liquid crystal of AP-325RXA(AP3300) sh: Add EcoVec24 romImage defconfig sh: USB disable process is needed if romImage boot for EcoVec24 sh: EcoVec24: add HIZA setting for LED sh: EcoVec24: write MAC address in boot sh: Add romImage support for EcoVec24 ...
Diffstat (limited to 'drivers/rtc/rtc-ds1302.c')
-rw-r--r--drivers/rtc/rtc-ds1302.c69
1 files changed, 15 insertions, 54 deletions
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 184556620778..d490628b64da 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;
@@ -103,10 +97,6 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val)
103 97
104static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) 98static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
105{ 99{
106 struct ds1302_rtc *rtc = dev_get_drvdata(dev);
107
108 spin_lock_irq(&rtc->lock);
109
110 tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC)); 100 tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
111 tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN)); 101 tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
112 tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR)); 102 tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
@@ -118,26 +108,17 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
118 if (tm->tm_year < 70) 108 if (tm->tm_year < 70)
119 tm->tm_year += 100; 109 tm->tm_year += 100;
120 110
121 spin_unlock_irq(&rtc->lock);
122
123 dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " 111 dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
124 "mday=%d, mon=%d, year=%d, wday=%d\n", 112 "mday=%d, mon=%d, year=%d, wday=%d\n",
125 __func__, 113 __func__,
126 tm->tm_sec, tm->tm_min, tm->tm_hour, 114 tm->tm_sec, tm->tm_min, tm->tm_hour,
127 tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); 115 tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
128 116
129 if (rtc_valid_tm(tm) < 0) 117 return rtc_valid_tm(tm);
130 dev_err(dev, "invalid date\n");
131
132 return 0;
133} 118}
134 119
135static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) 120static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
136{ 121{
137 struct ds1302_rtc *rtc = dev_get_drvdata(dev);
138
139 spin_lock_irq(&rtc->lock);
140
141 /* Stop RTC */ 122 /* Stop RTC */
142 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); 123 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
143 124
@@ -152,8 +133,6 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
152 /* Start RTC */ 133 /* Start RTC */
153 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); 134 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
154 135
155 spin_unlock_irq(&rtc->lock);
156
157 return 0; 136 return 0;
158} 137}
159 138
@@ -170,9 +149,7 @@ static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
170 if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int))) 149 if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
171 return -EFAULT; 150 return -EFAULT;
172 151
173 spin_lock_irq(&rtc->lock);
174 ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf)); 152 ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
175 spin_unlock_irq(&rtc->lock);
176 return 0; 153 return 0;
177 } 154 }
178#endif 155#endif
@@ -187,10 +164,9 @@ static struct rtc_class_ops ds1302_rtc_ops = {
187 .ioctl = ds1302_rtc_ioctl, 164 .ioctl = ds1302_rtc_ioctl,
188}; 165};
189 166
190static int __devinit ds1302_rtc_probe(struct platform_device *pdev) 167static int __init ds1302_rtc_probe(struct platform_device *pdev)
191{ 168{
192 struct ds1302_rtc *rtc; 169 struct rtc_device *rtc;
193 int ret;
194 170
195 /* Reset */ 171 /* Reset */
196 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); 172 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
@@ -200,37 +176,23 @@ static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
200 if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) 176 if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
201 return -ENODEV; 177 return -ENODEV;
202 178
203 rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL); 179 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); 180 &ds1302_rtc_ops, THIS_MODULE);
210 if (IS_ERR(rtc->rtc_dev)) { 181 if (IS_ERR(rtc))
211 ret = PTR_ERR(rtc->rtc_dev); 182 return PTR_ERR(rtc);
212 goto out;
213 }
214 183
215 platform_set_drvdata(pdev, rtc); 184 platform_set_drvdata(pdev, rtc);
216 185
217 return 0; 186 return 0;
218out:
219 kfree(rtc);
220 return ret;
221} 187}
222 188
223static int __devexit ds1302_rtc_remove(struct platform_device *pdev) 189static int __devexit ds1302_rtc_remove(struct platform_device *pdev)
224{ 190{
225 struct ds1302_rtc *rtc = platform_get_drvdata(pdev); 191 struct rtc_device *rtc = platform_get_drvdata(pdev);
226
227 if (likely(rtc->rtc_dev))
228 rtc_device_unregister(rtc->rtc_dev);
229 192
193 rtc_device_unregister(rtc);
230 platform_set_drvdata(pdev, NULL); 194 platform_set_drvdata(pdev, NULL);
231 195
232 kfree(rtc);
233
234 return 0; 196 return 0;
235} 197}
236 198
@@ -239,13 +201,12 @@ static struct platform_driver ds1302_platform_driver = {
239 .name = DRV_NAME, 201 .name = DRV_NAME,
240 .owner = THIS_MODULE, 202 .owner = THIS_MODULE,
241 }, 203 },
242 .probe = ds1302_rtc_probe, 204 .remove = __exit_p(ds1302_rtc_remove),
243 .remove = __devexit_p(ds1302_rtc_remove),
244}; 205};
245 206
246static int __init ds1302_rtc_init(void) 207static int __init ds1302_rtc_init(void)
247{ 208{
248 return platform_driver_register(&ds1302_platform_driver); 209 return platform_driver_probe(&ds1302_platform_driver, ds1302_rtc_probe);
249} 210}
250 211
251static void __exit ds1302_rtc_exit(void) 212static void __exit ds1302_rtc_exit(void)