aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-m41t80.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/rtc/rtc-m41t80.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (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.c49
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
71static DEFINE_MUTEX(m41t80_rtc_mutex);
71static const struct i2c_device_id m41t80_id[] = { 72static 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) 216static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
216static int
217m41t80_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;
244err: 234err:
245 return -EIO; 235 return -EIO;
246} 236}
247#else
248#define m41t80_rtc_ioctl NULL
249#endif
250 237
251static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) 238static 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,
693static int wdt_open(struct inode *inode, struct file *file) 680static 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
753static struct miscdevice wdt_dev = { 741static 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);