diff options
Diffstat (limited to 'arch/cris/arch-v10/drivers/pcf8563.c')
-rw-r--r-- | arch/cris/arch-v10/drivers/pcf8563.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c index b3dfdf7b8fc5..201f4c90d961 100644 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ b/arch/cris/arch-v10/drivers/pcf8563.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * | 15 | * |
16 | * Author: Tobias Anderberg <tobiasa@axis.com>. | 16 | * Author: Tobias Anderberg <tobiasa@axis.com>. |
17 | * | 17 | * |
18 | * $Id: pcf8563.c,v 1.8 2004/08/24 06:42:51 starvik Exp $ | 18 | * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $ |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
@@ -40,7 +40,7 @@ | |||
40 | #define PCF8563_MAJOR 121 /* Local major number. */ | 40 | #define PCF8563_MAJOR 121 /* Local major number. */ |
41 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ | 41 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ |
42 | #define PCF8563_NAME "PCF8563" | 42 | #define PCF8563_NAME "PCF8563" |
43 | #define DRIVER_VERSION "$Revision: 1.8 $" | 43 | #define DRIVER_VERSION "$Revision: 1.11 $" |
44 | 44 | ||
45 | /* I2C bus slave registers. */ | 45 | /* I2C bus slave registers. */ |
46 | #define RTC_I2C_READ 0xa3 | 46 | #define RTC_I2C_READ 0xa3 |
@@ -49,6 +49,8 @@ | |||
49 | /* Two simple wrapper macros, saves a few keystrokes. */ | 49 | /* Two simple wrapper macros, saves a few keystrokes. */ |
50 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) | 50 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) |
51 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) | 51 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) |
52 | |||
53 | static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */ | ||
52 | 54 | ||
53 | static const unsigned char days_in_month[] = | 55 | static const unsigned char days_in_month[] = |
54 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | 56 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
@@ -125,9 +127,12 @@ get_rtc_time(struct rtc_time *tm) | |||
125 | int __init | 127 | int __init |
126 | pcf8563_init(void) | 128 | pcf8563_init(void) |
127 | { | 129 | { |
128 | unsigned char ret; | 130 | int ret; |
129 | 131 | ||
130 | i2c_init(); | 132 | if ((ret = i2c_init())) { |
133 | printk(KERN_CRIT "pcf8563_init: failed to init i2c\n"); | ||
134 | return ret; | ||
135 | } | ||
131 | 136 | ||
132 | /* | 137 | /* |
133 | * First of all we need to reset the chip. This is done by | 138 | * First of all we need to reset the chip. This is done by |
@@ -200,12 +205,15 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
200 | { | 205 | { |
201 | struct rtc_time tm; | 206 | struct rtc_time tm; |
202 | 207 | ||
208 | spin_lock(&rtc_lock); | ||
203 | get_rtc_time(&tm); | 209 | get_rtc_time(&tm); |
204 | 210 | ||
205 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { | 211 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { |
212 | spin_unlock(&rtc_lock); | ||
206 | return -EFAULT; | 213 | return -EFAULT; |
207 | } | 214 | } |
208 | 215 | ||
216 | spin_unlock(&rtc_lock); | ||
209 | return 0; | 217 | return 0; |
210 | } | 218 | } |
211 | break; | 219 | break; |
@@ -250,6 +258,8 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
250 | BIN_TO_BCD(tm.tm_min); | 258 | BIN_TO_BCD(tm.tm_min); |
251 | BIN_TO_BCD(tm.tm_sec); | 259 | BIN_TO_BCD(tm.tm_sec); |
252 | tm.tm_mon |= century; | 260 | tm.tm_mon |= century; |
261 | |||
262 | spin_lock(&rtc_lock); | ||
253 | 263 | ||
254 | rtc_write(RTC_YEAR, tm.tm_year); | 264 | rtc_write(RTC_YEAR, tm.tm_year); |
255 | rtc_write(RTC_MONTH, tm.tm_mon); | 265 | rtc_write(RTC_MONTH, tm.tm_mon); |
@@ -258,6 +268,8 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
258 | rtc_write(RTC_MINUTES, tm.tm_min); | 268 | rtc_write(RTC_MINUTES, tm.tm_min); |
259 | rtc_write(RTC_SECONDS, tm.tm_sec); | 269 | rtc_write(RTC_SECONDS, tm.tm_sec); |
260 | 270 | ||
271 | spin_unlock(&rtc_lock); | ||
272 | |||
261 | return 0; | 273 | return 0; |
262 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ | 274 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ |
263 | } | 275 | } |