Merge branch 'akpm' (patches from Andrew Morton)
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Jun 2014 22:34:55 +0000 (15:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Jun 2014 22:34:55 +0000 (15:34 -0700)
Merge leftovers from Andrew Morton:
 "A few leftovers: ocfs2, gcov, RTC"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  rtc: s5m: consolidate two device type switch statements
  rtc: s5m: add support for S2MPS14 RTC
  rtc: s5m: support different register layout
  rtc: s5m: use shorter time of register update
  rtc: s5m: remove undocumented time init on first boot
  mfd/rtc: sec/s5m: rename SEC* symbols to S5M
  gcov: add support for GCC 4.9
  ocfs2/o2net: incorrect to terminate accepting connections loop upon rejecting an invalid one

drivers/rtc/Kconfig
drivers/rtc/rtc-s5m.c
fs/ocfs2/cluster/tcp.c
include/linux/mfd/samsung/rtc.h
kernel/gcov/base.c
kernel/gcov/gcc_4_7.c

index 71988b69eca610d584e4411a8db6a66d5abaf81d..0754f5c7cb3b9c9683555fc0275537700d1c03bc 100644 (file)
@@ -530,11 +530,11 @@ config RTC_DRV_RV3029C2
          will be called rtc-rv3029c2.
 
 config RTC_DRV_S5M
-       tristate "Samsung S5M series"
+       tristate "Samsung S2M/S5M series"
        depends on MFD_SEC_CORE
        help
          If you say yes here you will get support for the
-         RTC of Samsung S5M PMIC series.
+         RTC of Samsung S2MPS14 and S5M PMIC series.
 
          This driver can also be built as a module. If so, the module
          will be called rtc-s5m.
index 8ec2d6a1dbe1a8aedc326750399db6be1b5a7d15..8f06250a0389cbeffd0a6a0aaf4789ca581c342f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd
+ * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd
  *     http://www.samsung.com
  *
  *  Copyright (C) 2013 Google, Inc
 
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/slab.h>
 #include <linux/bcd.h>
-#include <linux/bitops.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
-#include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/rtc.h>
+#include <linux/mfd/samsung/s2mps14.h>
 
 /*
  * Maximum number of retries for checking changes in UDR field
- * of SEC_RTC_UDR_CON register (to limit possible endless loop).
+ * of S5M_RTC_UDR_CON register (to limit possible endless loop).
  *
  * After writing to RTC registers (setting time or alarm) read the UDR field
- * in SEC_RTC_UDR_CON register. UDR is auto-cleared when data have
+ * in S5M_RTC_UDR_CON register. UDR is auto-cleared when data have
  * been transferred.
  */
 #define UDR_READ_RETRY_CNT     5
 
+/* Registers used by the driver which are different between chipsets. */
+struct s5m_rtc_reg_config {
+       /* Number of registers used for setting time/alarm0/alarm1 */
+       unsigned int regs_count;
+       /* First register for time, seconds */
+       unsigned int time;
+       /* RTC control register */
+       unsigned int ctrl;
+       /* First register for alarm 0, seconds */
+       unsigned int alarm0;
+       /* First register for alarm 1, seconds */
+       unsigned int alarm1;
+       /* SMPL/WTSR register */
+       unsigned int smpl_wtsr;
+       /*
+        * Register for update flag (UDR). Typically setting UDR field to 1
+        * will enable update of time or alarm register. Then it will be
+        * auto-cleared after successful update.
+        */
+       unsigned int rtc_udr_update;
+       /* Mask for UDR field in 'rtc_udr_update' register */
+       unsigned int rtc_udr_mask;
+};
+
+/* Register map for S5M8763 and S5M8767 */
+static const struct s5m_rtc_reg_config s5m_rtc_regs = {
+       .regs_count             = 8,
+       .time                   = S5M_RTC_SEC,
+       .ctrl                   = S5M_ALARM1_CONF,
+       .alarm0                 = S5M_ALARM0_SEC,
+       .alarm1                 = S5M_ALARM1_SEC,
+       .smpl_wtsr              = S5M_WTSR_SMPL_CNTL,
+       .rtc_udr_update         = S5M_RTC_UDR_CON,
+       .rtc_udr_mask           = S5M_RTC_UDR_MASK,
+};
+
+/*
+ * Register map for S2MPS14.
+ * It may be also suitable for S2MPS11 but this was not tested.
+ */
+static const struct s5m_rtc_reg_config s2mps_rtc_regs = {
+       .regs_count             = 7,
+       .time                   = S2MPS_RTC_SEC,
+       .ctrl                   = S2MPS_RTC_CTRL,
+       .alarm0                 = S2MPS_ALARM0_SEC,
+       .alarm1                 = S2MPS_ALARM1_SEC,
+       .smpl_wtsr              = S2MPS_WTSR_SMPL_CNTL,
+       .rtc_udr_update         = S2MPS_RTC_UDR_CON,
+       .rtc_udr_mask           = S2MPS_RTC_WUDR_MASK,
+};
+
 struct s5m_rtc_info {
        struct device *dev;
        struct i2c_client *i2c;
@@ -48,13 +97,14 @@ struct s5m_rtc_info {
        int device_type;
        int rtc_24hr_mode;
        bool wtsr_smpl;
+       const struct s5m_rtc_reg_config *regs;
 };
 
 static const struct regmap_config s5m_rtc_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
-       .max_register = SEC_RTC_REG_MAX,
+       .max_register = S5M_RTC_REG_MAX,
 };
 
 static const struct regmap_config s2mps14_rtc_regmap_config = {
@@ -119,8 +169,9 @@ static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
        unsigned int data;
 
        do {
-               ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &data);
-       } while (--retry && (data & RTC_UDR_MASK) && !ret);
+               ret = regmap_read(info->regmap, info->regs->rtc_udr_update,
+                               &data);
+       } while (--retry && (data & info->regs->rtc_udr_mask) && !ret);
 
        if (!retry)
                dev_err(info->dev, "waiting for UDR update, reached max number of retries\n");
@@ -128,21 +179,53 @@ static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
        return ret;
 }
 
+static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
+               struct rtc_wkalrm *alarm)
+{
+       int ret;
+       unsigned int val;
+
+       switch (info->device_type) {
+       case S5M8767X:
+       case S5M8763X:
+               ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
+               val &= S5M_ALARM0_STATUS;
+               break;
+       case S2MPS14X:
+               ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2,
+                               &val);
+               val &= S2MPS_ALARM0_STATUS;
+               break;
+       default:
+               return -EINVAL;
+       }
+       if (ret < 0)
+               return ret;
+
+       if (val)
+               alarm->pending = 1;
+       else
+               alarm->pending = 0;
+
+       return 0;
+}
+
 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
 {
        int ret;
        unsigned int data;
 
-       ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &data);
+       ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
        if (ret < 0) {
                dev_err(info->dev, "failed to read update reg(%d)\n", ret);
                return ret;
        }
 
-       data |= RTC_TIME_EN_MASK;
-       data |= RTC_UDR_MASK;
+       data |= info->regs->rtc_udr_mask;
+       if (info->device_type == S5M8763X || info->device_type == S5M8767X)
+               data |= S5M_RTC_TIME_EN_MASK;
 
-       ret = regmap_write(info->regmap, SEC_RTC_UDR_CON, data);
+       ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
        if (ret < 0) {
                dev_err(info->dev, "failed to write update reg(%d)\n", ret);
                return ret;
@@ -158,17 +241,27 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
        int ret;
        unsigned int data;
 
-       ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &data);
+       ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to read update reg(%d)\n",
                        __func__, ret);
                return ret;
        }
 
-       data &= ~RTC_TIME_EN_MASK;
-       data |= RTC_UDR_MASK;
+       data |= info->regs->rtc_udr_mask;
+       switch (info->device_type) {
+       case S5M8763X:
+       case S5M8767X:
+               data &= ~S5M_RTC_TIME_EN_MASK;
+               break;
+       case S2MPS14X:
+               data |= S2MPS_RTC_RUDR_MASK;
+               break;
+       default:
+               return -EINVAL;
+       }
 
-       ret = regmap_write(info->regmap, SEC_RTC_UDR_CON, data);
+       ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to write update reg(%d)\n",
                        __func__, ret);
@@ -215,10 +308,22 @@ static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
 static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct s5m_rtc_info *info = dev_get_drvdata(dev);
-       u8 data[8];
+       u8 data[info->regs->regs_count];
        int ret;
 
-       ret = regmap_bulk_read(info->regmap, SEC_RTC_SEC, data, 8);
+       if (info->device_type == S2MPS14X) {
+               ret = regmap_update_bits(info->regmap,
+                               info->regs->rtc_udr_update,
+                               S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to prepare registers for time reading: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+       ret = regmap_bulk_read(info->regmap, info->regs->time, data,
+                       info->regs->regs_count);
        if (ret < 0)
                return ret;
 
@@ -228,6 +333,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
                break;
 
        case S5M8767X:
+       case S2MPS14X:
                s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
                break;
 
@@ -245,7 +351,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct s5m_rtc_info *info = dev_get_drvdata(dev);
-       u8 data[8];
+       u8 data[info->regs->regs_count];
        int ret = 0;
 
        switch (info->device_type) {
@@ -253,6 +359,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
                s5m8763_tm_to_data(tm, data);
                break;
        case S5M8767X:
+       case S2MPS14X:
                ret = s5m8767_tm_to_data(tm, data);
                break;
        default:
@@ -266,7 +373,8 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
                1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
                tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
 
-       ret = regmap_raw_write(info->regmap, SEC_RTC_SEC, data, 8);
+       ret = regmap_raw_write(info->regmap, info->regs->time, data,
+                       info->regs->regs_count);
        if (ret < 0)
                return ret;
 
@@ -278,70 +386,60 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        struct s5m_rtc_info *info = dev_get_drvdata(dev);
-       u8 data[8];
+       u8 data[info->regs->regs_count];
        unsigned int val;
        int ret, i;
 
-       ret = regmap_bulk_read(info->regmap, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
+                       info->regs->regs_count);
        if (ret < 0)
                return ret;
 
        switch (info->device_type) {
        case S5M8763X:
                s5m8763_data_to_tm(data, &alrm->time);
-               ret = regmap_read(info->regmap, SEC_ALARM0_CONF, &val);
+               ret = regmap_read(info->regmap, S5M_ALARM0_CONF, &val);
                if (ret < 0)
                        return ret;
 
                alrm->enabled = !!val;
-
-               ret = regmap_read(info->regmap, SEC_RTC_STATUS, &val);
-               if (ret < 0)
-                       return ret;
-
                break;
 
        case S5M8767X:
+       case S2MPS14X:
                s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
-               dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
-                       1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
-                       alrm->time.tm_mday, alrm->time.tm_hour,
-                       alrm->time.tm_min, alrm->time.tm_sec,
-                       alrm->time.tm_wday);
-
                alrm->enabled = 0;
-               for (i = 0; i < 7; i++) {
+               for (i = 0; i < info->regs->regs_count; i++) {
                        if (data[i] & ALARM_ENABLE_MASK) {
                                alrm->enabled = 1;
                                break;
                        }
                }
-
-               alrm->pending = 0;
-               ret = regmap_read(info->regmap, SEC_RTC_STATUS, &val);
-               if (ret < 0)
-                       return ret;
                break;
 
        default:
                return -EINVAL;
        }
 
-       if (val & ALARM0_STATUS)
-               alrm->pending = 1;
-       else
-               alrm->pending = 0;
+       dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
+               1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
+               alrm->time.tm_mday, alrm->time.tm_hour,
+               alrm->time.tm_min, alrm->time.tm_sec,
+               alrm->time.tm_wday);
+
+       ret = s5m_check_peding_alarm_interrupt(info, alrm);
 
        return 0;
 }
 
 static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
 {
-       u8 data[8];
+       u8 data[info->regs->regs_count];
        int ret, i;
        struct rtc_time tm;
 
-       ret = regmap_bulk_read(info->regmap, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
+                       info->regs->regs_count);
        if (ret < 0)
                return ret;
 
@@ -352,14 +450,16 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
 
        switch (info->device_type) {
        case S5M8763X:
-               ret = regmap_write(info->regmap, SEC_ALARM0_CONF, 0);
+               ret = regmap_write(info->regmap, S5M_ALARM0_CONF, 0);
                break;
 
        case S5M8767X:
-               for (i = 0; i < 7; i++)
+       case S2MPS14X:
+               for (i = 0; i < info->regs->regs_count; i++)
                        data[i] &= ~ALARM_ENABLE_MASK;
 
-               ret = regmap_raw_write(info->regmap, SEC_ALARM0_SEC, data, 8);
+               ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
+                               info->regs->regs_count);
                if (ret < 0)
                        return ret;
 
@@ -377,11 +477,12 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
 static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
 {
        int ret;
-       u8 data[8];
+       u8 data[info->regs->regs_count];
        u8 alarm0_conf;
        struct rtc_time tm;
 
-       ret = regmap_bulk_read(info->regmap, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
+                       info->regs->regs_count);
        if (ret < 0)
                return ret;
 
@@ -393,10 +494,11 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
        switch (info->device_type) {
        case S5M8763X:
                alarm0_conf = 0x77;
-               ret = regmap_write(info->regmap, SEC_ALARM0_CONF, alarm0_conf);
+               ret = regmap_write(info->regmap, S5M_ALARM0_CONF, alarm0_conf);
                break;
 
        case S5M8767X:
+       case S2MPS14X:
                data[RTC_SEC] |= ALARM_ENABLE_MASK;
                data[RTC_MIN] |= ALARM_ENABLE_MASK;
                data[RTC_HOUR] |= ALARM_ENABLE_MASK;
@@ -408,7 +510,8 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
                if (data[RTC_YEAR1] & 0x7f)
                        data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
 
-               ret = regmap_raw_write(info->regmap, SEC_ALARM0_SEC, data, 8);
+               ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
+                               info->regs->regs_count);
                if (ret < 0)
                        return ret;
                ret = s5m8767_rtc_set_alarm_reg(info);
@@ -425,7 +528,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
 static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        struct s5m_rtc_info *info = dev_get_drvdata(dev);
-       u8 data[8];
+       u8 data[info->regs->regs_count];
        int ret;
 
        switch (info->device_type) {
@@ -434,6 +537,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
                break;
 
        case S5M8767X:
+       case S2MPS14X:
                s5m8767_tm_to_data(&alrm->time, data);
                break;
 
@@ -450,7 +554,8 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        if (ret < 0)
                return ret;
 
-       ret = regmap_raw_write(info->regmap, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
+                       info->regs->regs_count);
        if (ret < 0)
                return ret;
 
@@ -495,7 +600,7 @@ static const struct rtc_class_ops s5m_rtc_ops = {
 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
 {
        int ret;
-       ret = regmap_update_bits(info->regmap, SEC_WTSR_SMPL_CNTL,
+       ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
                                 WTSR_ENABLE_MASK,
                                 enable ? WTSR_ENABLE_MASK : 0);
        if (ret < 0)
@@ -506,7 +611,7 @@ static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
 static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
 {
        int ret;
-       ret = regmap_update_bits(info->regmap, SEC_WTSR_SMPL_CNTL,
+       ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
                                 SMPL_ENABLE_MASK,
                                 enable ? SMPL_ENABLE_MASK : 0);
        if (ret < 0)
@@ -517,50 +622,41 @@ static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
 static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
 {
        u8 data[2];
-       unsigned int tp_read;
        int ret;
-       struct rtc_time tm;
 
-       ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &tp_read);
-       if (ret < 0) {
-               dev_err(info->dev, "%s: fail to read control reg(%d)\n",
-                       __func__, ret);
-               return ret;
-       }
+       switch (info->device_type) {
+       case S5M8763X:
+       case S5M8767X:
+               /* UDR update time. Default of 7.32 ms is too long. */
+               ret = regmap_update_bits(info->regmap, S5M_RTC_UDR_CON,
+                               S5M_RTC_UDR_T_MASK, S5M_RTC_UDR_T_450_US);
+               if (ret < 0)
+                       dev_err(info->dev, "%s: fail to change UDR time: %d\n",
+                                       __func__, ret);
 
-       /* Set RTC control register : Binary mode, 24hour mode */
-       data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
-       data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
+               /* Set RTC control register : Binary mode, 24hour mode */
+               data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
+               data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
+
+               ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2);
+               break;
+
+       case S2MPS14X:
+               data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
+               ret = regmap_write(info->regmap, info->regs->ctrl, data[0]);
+               break;
+
+       default:
+               return -EINVAL;
+       }
 
        info->rtc_24hr_mode = 1;
-       ret = regmap_raw_write(info->regmap, SEC_ALARM0_CONF, data, 2);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
                        __func__, ret);
                return ret;
        }
 
-       /* In first boot time, Set rtc time to 1/1/2012 00:00:00(SUN) */
-       if ((tp_read & RTC_TCON_MASK) == 0) {
-               dev_dbg(info->dev, "rtc init\n");
-               tm.tm_sec = 0;
-               tm.tm_min = 0;
-               tm.tm_hour = 0;
-               tm.tm_wday = 0;
-               tm.tm_mday = 1;
-               tm.tm_mon = 0;
-               tm.tm_year = 112;
-               tm.tm_yday = 0;
-               tm.tm_isdst = 0;
-               ret = s5m_rtc_set_time(info->dev, &tm);
-       }
-
-       ret = regmap_update_bits(info->regmap, SEC_RTC_UDR_CON,
-                                RTC_TCON_MASK, tp_read | RTC_TCON_MASK);
-       if (ret < 0)
-               dev_err(info->dev, "%s: fail to update TCON reg(%d)\n",
-                       __func__, ret);
-
        return ret;
 }
 
@@ -570,7 +666,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
        struct sec_platform_data *pdata = s5m87xx->pdata;
        struct s5m_rtc_info *info;
        const struct regmap_config *regmap_cfg;
-       int ret;
+       int ret, alarm_irq;
 
        if (!pdata) {
                dev_err(pdev->dev.parent, "Platform data not supplied\n");
@@ -584,12 +680,18 @@ static int s5m_rtc_probe(struct platform_device *pdev)
        switch (pdata->device_type) {
        case S2MPS14X:
                regmap_cfg = &s2mps14_rtc_regmap_config;
+               info->regs = &s2mps_rtc_regs;
+               alarm_irq = S2MPS14_IRQ_RTCA0;
                break;
        case S5M8763X:
                regmap_cfg = &s5m_rtc_regmap_config;
+               info->regs = &s5m_rtc_regs;
+               alarm_irq = S5M8763_IRQ_ALARM0;
                break;
        case S5M8767X:
                regmap_cfg = &s5m_rtc_regmap_config;
+               info->regs = &s5m_rtc_regs;
+               alarm_irq = S5M8767_IRQ_RTCA1;
                break;
        default:
                dev_err(&pdev->dev, "Device type is not supported by RTC driver\n");
@@ -615,20 +717,11 @@ static int s5m_rtc_probe(struct platform_device *pdev)
        info->device_type = s5m87xx->device_type;
        info->wtsr_smpl = s5m87xx->wtsr_smpl;
 
-       switch (pdata->device_type) {
-       case S5M8763X:
-               info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
-                               S5M8763_IRQ_ALARM0);
-               break;
-
-       case S5M8767X:
-               info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
-                               S5M8767_IRQ_RTCA1);
-               break;
-
-       default:
+       info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
+       if (info->irq <= 0) {
                ret = -EINVAL;
-               dev_err(&pdev->dev, "Unsupported device type: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n",
+                               alarm_irq);
                goto err;
        }
 
@@ -676,7 +769,7 @@ static void s5m_rtc_shutdown(struct platform_device *pdev)
        if (info->wtsr_smpl) {
                for (i = 0; i < 3; i++) {
                        s5m_rtc_enable_wtsr(info, false);
-                       regmap_read(info->regmap, SEC_WTSR_SMPL_CNTL, &val);
+                       regmap_read(info->regmap, info->regs->smpl_wtsr, &val);
                        pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
                        if (val & WTSR_ENABLE_MASK)
                                pr_emerg("%s: fail to disable WTSR\n",
@@ -730,7 +823,8 @@ static int s5m_rtc_suspend(struct device *dev)
 static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
 
 static const struct platform_device_id s5m_rtc_id[] = {
-       { "s5m-rtc", 0 },
+       { "s5m-rtc",            S5M8767X },
+       { "s2mps14-rtc",        S2MPS14X },
 };
 
 static struct platform_driver s5m_rtc_driver = {
@@ -749,6 +843,6 @@ module_platform_driver(s5m_rtc_driver);
 
 /* Module information */
 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
-MODULE_DESCRIPTION("Samsung S5M RTC driver");
+MODULE_DESCRIPTION("Samsung S5M/S2MPS14 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s5m-rtc");
index a68e07a9bd46240cbb9a398eb626a4c2e92427d7..681691bc233a1d8991ba4ec5ad1512524afd1b8d 100644 (file)
@@ -1799,7 +1799,7 @@ int o2net_register_hb_callbacks(void)
 
 /* ------------------------------------------------------------ */
 
-static int o2net_accept_one(struct socket *sock)
+static int o2net_accept_one(struct socket *sock, int *more)
 {
        int ret, slen;
        struct sockaddr_in sin;
@@ -1810,6 +1810,7 @@ static int o2net_accept_one(struct socket *sock)
        struct o2net_node *nn;
 
        BUG_ON(sock == NULL);
+       *more = 0;
        ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
                               sock->sk->sk_protocol, &new_sock);
        if (ret)
@@ -1821,6 +1822,7 @@ static int o2net_accept_one(struct socket *sock)
        if (ret < 0)
                goto out;
 
+       *more = 1;
        new_sock->sk->sk_allocation = GFP_ATOMIC;
 
        ret = o2net_set_nodelay(new_sock);
@@ -1919,11 +1921,36 @@ out:
        return ret;
 }
 
+/*
+ * This function is invoked in response to one or more
+ * pending accepts at softIRQ level. We must drain the
+ * entire que before returning.
+ */
+
 static void o2net_accept_many(struct work_struct *work)
 {
        struct socket *sock = o2net_listen_sock;
-       while (o2net_accept_one(sock) == 0)
+       int     more;
+       int     err;
+
+       /*
+        * It is critical to note that due to interrupt moderation
+        * at the network driver level, we can't assume to get a
+        * softIRQ for every single conn since tcp SYN packets
+        * can arrive back-to-back, and therefore many pending
+        * accepts may result in just 1 softIRQ. If we terminate
+        * the o2net_accept_one() loop upon seeing an err, what happens
+        * to the rest of the conns in the queue? If no new SYN
+        * arrives for hours, no softIRQ  will be delivered,
+        * and the connections will just sit in the queue.
+        */
+
+       for (;;) {
+               err = o2net_accept_one(sock, &more);
+               if (!more)
+                       break;
                cond_resched();
+       }
 }
 
 static void o2net_listen_data_ready(struct sock *sk)
index 3e02b768d53704968a76e27af9cece0f455de6bc..b6401e7661c75856055a3ee84adf8a242e704b26 100644 (file)
 #ifndef __LINUX_MFD_SEC_RTC_H
 #define __LINUX_MFD_SEC_RTC_H
 
-enum sec_rtc_reg {
-       SEC_RTC_SEC,
-       SEC_RTC_MIN,
-       SEC_RTC_HOUR,
-       SEC_RTC_WEEKDAY,
-       SEC_RTC_DATE,
-       SEC_RTC_MONTH,
-       SEC_RTC_YEAR1,
-       SEC_RTC_YEAR2,
-       SEC_ALARM0_SEC,
-       SEC_ALARM0_MIN,
-       SEC_ALARM0_HOUR,
-       SEC_ALARM0_WEEKDAY,
-       SEC_ALARM0_DATE,
-       SEC_ALARM0_MONTH,
-       SEC_ALARM0_YEAR1,
-       SEC_ALARM0_YEAR2,
-       SEC_ALARM1_SEC,
-       SEC_ALARM1_MIN,
-       SEC_ALARM1_HOUR,
-       SEC_ALARM1_WEEKDAY,
-       SEC_ALARM1_DATE,
-       SEC_ALARM1_MONTH,
-       SEC_ALARM1_YEAR1,
-       SEC_ALARM1_YEAR2,
-       SEC_ALARM0_CONF,
-       SEC_ALARM1_CONF,
-       SEC_RTC_STATUS,
-       SEC_WTSR_SMPL_CNTL,
-       SEC_RTC_UDR_CON,
+enum s5m_rtc_reg {
+       S5M_RTC_SEC,
+       S5M_RTC_MIN,
+       S5M_RTC_HOUR,
+       S5M_RTC_WEEKDAY,
+       S5M_RTC_DATE,
+       S5M_RTC_MONTH,
+       S5M_RTC_YEAR1,
+       S5M_RTC_YEAR2,
+       S5M_ALARM0_SEC,
+       S5M_ALARM0_MIN,
+       S5M_ALARM0_HOUR,
+       S5M_ALARM0_WEEKDAY,
+       S5M_ALARM0_DATE,
+       S5M_ALARM0_MONTH,
+       S5M_ALARM0_YEAR1,
+       S5M_ALARM0_YEAR2,
+       S5M_ALARM1_SEC,
+       S5M_ALARM1_MIN,
+       S5M_ALARM1_HOUR,
+       S5M_ALARM1_WEEKDAY,
+       S5M_ALARM1_DATE,
+       S5M_ALARM1_MONTH,
+       S5M_ALARM1_YEAR1,
+       S5M_ALARM1_YEAR2,
+       S5M_ALARM0_CONF,
+       S5M_ALARM1_CONF,
+       S5M_RTC_STATUS,
+       S5M_WTSR_SMPL_CNTL,
+       S5M_RTC_UDR_CON,
 
-       SEC_RTC_REG_MAX,
+       S5M_RTC_REG_MAX,
 };
 
 enum s2mps_rtc_reg {
@@ -88,9 +88,9 @@ enum s2mps_rtc_reg {
 #define HOUR_12                        (1 << 7)
 #define HOUR_AMPM              (1 << 6)
 #define HOUR_PM                        (1 << 5)
-#define ALARM0_STATUS          (1 << 1)
-#define ALARM1_STATUS          (1 << 2)
-#define UPDATE_AD              (1 << 0)
+#define S5M_ALARM0_STATUS      (1 << 1)
+#define S5M_ALARM1_STATUS      (1 << 2)
+#define S5M_UPDATE_AD          (1 << 0)
 
 #define S2MPS_ALARM0_STATUS    (1 << 2)
 #define S2MPS_ALARM1_STATUS    (1 << 1)
@@ -101,16 +101,26 @@ enum s2mps_rtc_reg {
 #define MODEL24_SHIFT          1
 #define MODEL24_MASK           (1 << MODEL24_SHIFT)
 /* RTC Update Register1 */
-#define RTC_UDR_SHIFT          0
-#define RTC_UDR_MASK           (1 << RTC_UDR_SHIFT)
+#define S5M_RTC_UDR_SHIFT      0
+#define S5M_RTC_UDR_MASK       (1 << S5M_RTC_UDR_SHIFT)
 #define S2MPS_RTC_WUDR_SHIFT   4
 #define S2MPS_RTC_WUDR_MASK    (1 << S2MPS_RTC_WUDR_SHIFT)
 #define S2MPS_RTC_RUDR_SHIFT   0
 #define S2MPS_RTC_RUDR_MASK    (1 << S2MPS_RTC_RUDR_SHIFT)
 #define RTC_TCON_SHIFT         1
 #define RTC_TCON_MASK          (1 << RTC_TCON_SHIFT)
-#define RTC_TIME_EN_SHIFT      3
-#define RTC_TIME_EN_MASK       (1 << RTC_TIME_EN_SHIFT)
+#define S5M_RTC_TIME_EN_SHIFT  3
+#define S5M_RTC_TIME_EN_MASK   (1 << S5M_RTC_TIME_EN_SHIFT)
+/*
+ * UDR_T field in S5M_RTC_UDR_CON register determines the time needed
+ * for updating alarm and time registers. Default is 7.32 ms.
+ */
+#define S5M_RTC_UDR_T_SHIFT    6
+#define S5M_RTC_UDR_T_MASK     (0x3 << S5M_RTC_UDR_T_SHIFT)
+#define S5M_RTC_UDR_T_7320_US  (0x0 << S5M_RTC_UDR_T_SHIFT)
+#define S5M_RTC_UDR_T_1830_US  (0x1 << S5M_RTC_UDR_T_SHIFT)
+#define S5M_RTC_UDR_T_3660_US  (0x2 << S5M_RTC_UDR_T_SHIFT)
+#define S5M_RTC_UDR_T_450_US   (0x3 << S5M_RTC_UDR_T_SHIFT)
 
 /* RTC Hour register */
 #define HOUR_PM_SHIFT          6
index f45b75b713c0eeff3564cfacb4f0881037bbfc75..b358a802fd184391ae4926bc02b2983511bc8077 100644 (file)
@@ -85,6 +85,12 @@ void __gcov_merge_ior(gcov_type *counters, unsigned int n_counters)
 }
 EXPORT_SYMBOL(__gcov_merge_ior);
 
+void __gcov_merge_time_profile(gcov_type *counters, unsigned int n_counters)
+{
+       /* Unused. */
+}
+EXPORT_SYMBOL(__gcov_merge_time_profile);
+
 /**
  * gcov_enable_events - enable event reporting through gcov_event()
  *
index 2c6e4631c814e19714f0e635ed1b4173dc49ec48..826ba9fb5e3277292d38ef4c95ba9713378b4543 100644 (file)
 #include <linux/vmalloc.h>
 #include "gcov.h"
 
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 9
+#define GCOV_COUNTERS                  9
+#else
 #define GCOV_COUNTERS                  8
+#endif
+
 #define GCOV_TAG_FUNCTION_LENGTH       3
 
 static struct gcov_info *gcov_info_head;