diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/rtc/rtc-m41t80.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/rtc/rtc-m41t80.c')
-rw-r--r-- | drivers/rtc/rtc-m41t80.c | 49 |
1 files changed, 19 insertions, 30 deletions
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index d60557cae8ef..eda128fc1d38 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/rtc.h> | 21 | #include <linux/rtc.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/smp_lock.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #ifdef CONFIG_RTC_DRV_M41T80_WDT | 25 | #ifdef CONFIG_RTC_DRV_M41T80_WDT |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
@@ -68,6 +68,7 @@ | |||
68 | 68 | ||
69 | #define DRV_VERSION "0.05" | 69 | #define DRV_VERSION "0.05" |
70 | 70 | ||
71 | static DEFINE_MUTEX(m41t80_rtc_mutex); | ||
71 | static const struct i2c_device_id m41t80_id[] = { | 72 | static const struct i2c_device_id m41t80_id[] = { |
72 | { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT }, | 73 | { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT }, |
73 | { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, | 74 | { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, |
@@ -212,41 +213,27 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
212 | return m41t80_set_datetime(to_i2c_client(dev), tm); | 213 | return m41t80_set_datetime(to_i2c_client(dev), tm); |
213 | } | 214 | } |
214 | 215 | ||
215 | #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) | 216 | static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
216 | static int | ||
217 | m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
218 | { | 217 | { |
219 | struct i2c_client *client = to_i2c_client(dev); | 218 | struct i2c_client *client = to_i2c_client(dev); |
220 | int rc; | 219 | int rc; |
221 | 220 | ||
222 | switch (cmd) { | ||
223 | case RTC_AIE_OFF: | ||
224 | case RTC_AIE_ON: | ||
225 | break; | ||
226 | default: | ||
227 | return -ENOIOCTLCMD; | ||
228 | } | ||
229 | |||
230 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); | 221 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); |
231 | if (rc < 0) | 222 | if (rc < 0) |
232 | goto err; | 223 | goto err; |
233 | switch (cmd) { | 224 | |
234 | case RTC_AIE_OFF: | 225 | if (enabled) |
235 | rc &= ~M41T80_ALMON_AFE; | ||
236 | break; | ||
237 | case RTC_AIE_ON: | ||
238 | rc |= M41T80_ALMON_AFE; | 226 | rc |= M41T80_ALMON_AFE; |
239 | break; | 227 | else |
240 | } | 228 | rc &= ~M41T80_ALMON_AFE; |
229 | |||
241 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) | 230 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) |
242 | goto err; | 231 | goto err; |
232 | |||
243 | return 0; | 233 | return 0; |
244 | err: | 234 | err: |
245 | return -EIO; | 235 | return -EIO; |
246 | } | 236 | } |
247 | #else | ||
248 | #define m41t80_rtc_ioctl NULL | ||
249 | #endif | ||
250 | 237 | ||
251 | static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 238 | static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
252 | { | 239 | { |
@@ -373,7 +360,7 @@ static struct rtc_class_ops m41t80_rtc_ops = { | |||
373 | .read_alarm = m41t80_rtc_read_alarm, | 360 | .read_alarm = m41t80_rtc_read_alarm, |
374 | .set_alarm = m41t80_rtc_set_alarm, | 361 | .set_alarm = m41t80_rtc_set_alarm, |
375 | .proc = m41t80_rtc_proc, | 362 | .proc = m41t80_rtc_proc, |
376 | .ioctl = m41t80_rtc_ioctl, | 363 | .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, |
377 | }; | 364 | }; |
378 | 365 | ||
379 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) | 366 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) |
@@ -677,9 +664,9 @@ static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, | |||
677 | { | 664 | { |
678 | int ret; | 665 | int ret; |
679 | 666 | ||
680 | lock_kernel(); | 667 | mutex_lock(&m41t80_rtc_mutex); |
681 | ret = wdt_ioctl(file, cmd, arg); | 668 | ret = wdt_ioctl(file, cmd, arg); |
682 | unlock_kernel(); | 669 | mutex_unlock(&m41t80_rtc_mutex); |
683 | 670 | ||
684 | return ret; | 671 | return ret; |
685 | } | 672 | } |
@@ -693,16 +680,16 @@ static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, | |||
693 | static int wdt_open(struct inode *inode, struct file *file) | 680 | static int wdt_open(struct inode *inode, struct file *file) |
694 | { | 681 | { |
695 | if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { | 682 | if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { |
696 | lock_kernel(); | 683 | mutex_lock(&m41t80_rtc_mutex); |
697 | if (test_and_set_bit(0, &wdt_is_open)) { | 684 | if (test_and_set_bit(0, &wdt_is_open)) { |
698 | unlock_kernel(); | 685 | mutex_unlock(&m41t80_rtc_mutex); |
699 | return -EBUSY; | 686 | return -EBUSY; |
700 | } | 687 | } |
701 | /* | 688 | /* |
702 | * Activate | 689 | * Activate |
703 | */ | 690 | */ |
704 | wdt_is_open = 1; | 691 | wdt_is_open = 1; |
705 | unlock_kernel(); | 692 | mutex_unlock(&m41t80_rtc_mutex); |
706 | return nonseekable_open(inode, file); | 693 | return nonseekable_open(inode, file); |
707 | } | 694 | } |
708 | return -ENODEV; | 695 | return -ENODEV; |
@@ -748,6 +735,7 @@ static const struct file_operations wdt_fops = { | |||
748 | .write = wdt_write, | 735 | .write = wdt_write, |
749 | .open = wdt_open, | 736 | .open = wdt_open, |
750 | .release = wdt_release, | 737 | .release = wdt_release, |
738 | .llseek = no_llseek, | ||
751 | }; | 739 | }; |
752 | 740 | ||
753 | static struct miscdevice wdt_dev = { | 741 | static struct miscdevice wdt_dev = { |
@@ -795,6 +783,9 @@ static int m41t80_probe(struct i2c_client *client, | |||
795 | goto exit; | 783 | goto exit; |
796 | } | 784 | } |
797 | 785 | ||
786 | clientdata->features = id->driver_data; | ||
787 | i2c_set_clientdata(client, clientdata); | ||
788 | |||
798 | rtc = rtc_device_register(client->name, &client->dev, | 789 | rtc = rtc_device_register(client->name, &client->dev, |
799 | &m41t80_rtc_ops, THIS_MODULE); | 790 | &m41t80_rtc_ops, THIS_MODULE); |
800 | if (IS_ERR(rtc)) { | 791 | if (IS_ERR(rtc)) { |
@@ -804,8 +795,6 @@ static int m41t80_probe(struct i2c_client *client, | |||
804 | } | 795 | } |
805 | 796 | ||
806 | clientdata->rtc = rtc; | 797 | clientdata->rtc = rtc; |
807 | clientdata->features = id->driver_data; | ||
808 | i2c_set_clientdata(client, clientdata); | ||
809 | 798 | ||
810 | /* Make sure HT (Halt Update) bit is cleared */ | 799 | /* Make sure HT (Halt Update) bit is cleared */ |
811 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); | 800 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); |