Commit 6c84239d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'rtc-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "RTC for 4.8

  Cleanups:
   - huge cleanup of rtc-generic and char/genrtc this allowed to cleanup
     rtc-cmos, rtc-sh, rtc-m68k, rtc-powerpc and rtc-parisc
   - move mn10300 to rtc-cmos

  Subsystem:
   - fix wakealarms after hibernate
   - multiples fixes for rctest
   - simplify implementations of .read_alarm

  New drivers:
   - Maxim MAX6916

  Drivers:
   - ds1307: fix weekday
   - m41t80: add wakeup support
   - pcf85063: add support for PCF85063A variant
   - rv8803: extend i2c fix and other fixes
   - s35390a: fix alarm reading, this fixes instant reboot after
     shutdown for QNAP TS-41x
   - s3c: clock fixes"

* tag 'rtc-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (65 commits)
  rtc: rv8803: Clear V1F when setting the time
  rtc: rv8803: Stop the clock while setting the time
  rtc: rv8803: Always apply the I²C workaround
  rtc: rv8803: Fix read day of week
  rtc: rv8803: Remove the check for valid time
  rtc: rv8803: Kconfig: Indicate rx8900 support
  rtc: asm9260: remove .owner field for driver
  rtc: at91sam9: Fix missing spin_lock_init()
  rtc: m41t80: add suspend handlers for alarm IRQ
  rtc: m41t80: make it a real error message
  rtc: pcf85063: Add support for the PCF85063A device
  rtc: pcf85063: fix year range
  rtc: hym8563: in .read_alarm set .tm_sec to 0 to signal minute accuracy
  rtc: explicitly set tm_sec = 0 for drivers with minute accurancy
  rtc: s3c: Add s3c_rtc_{enable/disable}_clk in s3c_rtc_setfreq()
  rtc: s3c: Remove unnecessary call to disable already disabled clock
  rtc: abx80x: use devm_add_action_or_reset()
  rtc: m41t80: use devm_add_action_or_reset()
  rtc: fix a typo and reduce three empty lines to one
  rtc: s35390a: improve two comments in .set_alarm
  ...
parents d4c06c70 6f367788
...@@ -8,6 +8,7 @@ obj-$(CONFIG_RTC_LIB) += rtc-lib.o ...@@ -8,6 +8,7 @@ obj-$(CONFIG_RTC_LIB) += rtc-lib.o
obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
obj-$(CONFIG_RTC_SYSTOHC) += systohc.o obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
obj-$(CONFIG_RTC_CLASS) += rtc-core.o obj-$(CONFIG_RTC_CLASS) += rtc-core.o
obj-$(CONFIG_RTC_MC146818_LIB) += rtc-mc146818-lib.o
rtc-core-y := class.o interface.o rtc-core-y := class.o interface.o
ifdef CONFIG_RTC_DRV_EFI ifdef CONFIG_RTC_DRV_EFI
...@@ -85,6 +86,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o ...@@ -85,6 +86,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_MAX6916) += rtc-max6916.o
obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o
obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o
obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
......
...@@ -104,7 +104,17 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al ...@@ -104,7 +104,17 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al
else if (!rtc->ops->read_alarm) else if (!rtc->ops->read_alarm)
err = -EINVAL; err = -EINVAL;
else { else {
memset(alarm, 0, sizeof(struct rtc_wkalrm)); alarm->enabled = 0;
alarm->pending = 0;
alarm->time.tm_sec = -1;
alarm->time.tm_min = -1;
alarm->time.tm_hour = -1;
alarm->time.tm_mday = -1;
alarm->time.tm_mon = -1;
alarm->time.tm_year = -1;
alarm->time.tm_wday = -1;
alarm->time.tm_yday = -1;
alarm->time.tm_isdst = -1;
err = rtc->ops->read_alarm(rtc->dev.parent, alarm); err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
} }
...@@ -383,7 +393,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ...@@ -383,7 +393,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
rtc->aie_timer.period = ktime_set(0, 0); rtc->aie_timer.period = ktime_set(0, 0);
/* Alarm has to be enabled & in the futrure for us to enqueue it */ /* Alarm has to be enabled & in the future for us to enqueue it */
if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 <
rtc->aie_timer.node.expires.tv64)) { rtc->aie_timer.node.expires.tv64)) {
...@@ -395,8 +405,6 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ...@@ -395,8 +405,6 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
} }
EXPORT_SYMBOL_GPL(rtc_initialize_alarm); EXPORT_SYMBOL_GPL(rtc_initialize_alarm);
int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
{ {
int err = mutex_lock_interruptible(&rtc->ops_lock); int err = mutex_lock_interruptible(&rtc->ops_lock);
...@@ -748,9 +756,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq); ...@@ -748,9 +756,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
*/ */
static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
{ {
struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
struct rtc_time tm;
ktime_t now;
timer->enabled = 1; timer->enabled = 1;
__rtc_read_time(rtc, &tm);
now = rtc_tm_to_ktime(tm);
/* Skip over expired timers */
while (next) {
if (next->expires.tv64 >= now.tv64)
break;
next = timerqueue_iterate_next(next);
}
timerqueue_add(&rtc->timerqueue, &timer->node); timerqueue_add(&rtc->timerqueue, &timer->node);
if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { if (!next) {
struct rtc_wkalrm alarm; struct rtc_wkalrm alarm;
int err; int err;
alarm.time = rtc_ktime_to_tm(timer->node.expires); alarm.time = rtc_ktime_to_tm(timer->node.expires);
......
...@@ -643,17 +643,15 @@ static int abx80x_probe(struct i2c_client *client, ...@@ -643,17 +643,15 @@ static int abx80x_probe(struct i2c_client *client,
return err; return err;
} }
err = devm_add_action(&client->dev, rtc_calib_remove_sysfs_group, err = devm_add_action_or_reset(&client->dev,
&client->dev); rtc_calib_remove_sysfs_group,
if (err) { &client->dev);
rtc_calib_remove_sysfs_group(&client->dev); if (err)
dev_err(&client->dev, dev_err(&client->dev,
"Failed to add sysfs cleanup action: %d\n", "Failed to add sysfs cleanup action: %d\n",
err); err);
return err;
}
return 0; return err;
} }
static int abx80x_remove(struct i2c_client *client) static int abx80x_remove(struct i2c_client *client)
......
...@@ -343,7 +343,6 @@ static struct platform_driver asm9260_rtc_driver = { ...@@ -343,7 +343,6 @@ static struct platform_driver asm9260_rtc_driver = {
.remove = asm9260_rtc_remove, .remove = asm9260_rtc_remove,
.driver = { .driver = {
.name = "asm9260-rtc", .name = "asm9260-rtc",
.owner = THIS_MODULE,
.of_match_table = asm9260_dt_ids, .of_match_table = asm9260_dt_ids,
}, },
}; };
......
...@@ -375,6 +375,7 @@ static int at91_rtc_probe(struct platform_device *pdev) ...@@ -375,6 +375,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
if (!rtc) if (!rtc)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&rtc->lock);
rtc->irq = irq; rtc->irq = irq;
/* platform setup code should have handled this; sigh */ /* platform setup code should have handled this; sigh */
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#include <asm-generic/rtc.h> #include <linux/mc146818rtc.h>
struct cmos_rtc { struct cmos_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
...@@ -190,10 +190,10 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr) ...@@ -190,10 +190,10 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
static int cmos_read_time(struct device *dev, struct rtc_time *t) static int cmos_read_time(struct device *dev, struct rtc_time *t)
{ {
/* REVISIT: if the clock has a "century" register, use /* REVISIT: if the clock has a "century" register, use
* that instead of the heuristic in get_rtc_time(). * that instead of the heuristic in mc146818_get_time().
* That'll make Y3K compatility (year > 2070) easy! * That'll make Y3K compatility (year > 2070) easy!
*/ */
get_rtc_time(t); mc146818_get_time(t);
return 0; return 0;
} }
...@@ -205,7 +205,7 @@ static int cmos_set_time(struct device *dev, struct rtc_time *t) ...@@ -205,7 +205,7 @@ static int cmos_set_time(struct device *dev, struct rtc_time *t)
* takes effect exactly 500ms after we write the register. * takes effect exactly 500ms after we write the register.
* (Also queueing and other delays before we get this far.) * (Also queueing and other delays before we get this far.)
*/ */
return set_rtc_time(t); return mc146818_set_time(t);
} }
static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
...@@ -220,8 +220,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -220,8 +220,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
* Some also support day and month, for alarms up to a year in * Some also support day and month, for alarms up to a year in
* the future. * the future.
*/ */
t->time.tm_mday = -1;
t->time.tm_mon = -1;
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM); t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
...@@ -272,7 +270,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -272,7 +270,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
} }
} }
} }
t->time.tm_year = -1;
t->enabled = !!(rtc_control & RTC_AIE); t->enabled = !!(rtc_control & RTC_AIE);
t->pending = 0; t->pending = 0;
...@@ -630,7 +627,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -630,7 +627,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
address_space = 64; address_space = 64;
#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \
|| defined(__sparc__) || defined(__mips__) \ || defined(__sparc__) || defined(__mips__) \
|| defined(__powerpc__) || defined(__powerpc__) || defined(CONFIG_MN10300)
address_space = 128; address_space = 128;
#else #else
#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
...@@ -1142,14 +1139,14 @@ static __init void cmos_of_init(struct platform_device *pdev) ...@@ -1142,14 +1139,14 @@ static __init void cmos_of_init(struct platform_device *pdev)
if (val) if (val)
CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT);
get_rtc_time(&time); cmos_read_time(&pdev->dev, &time);
ret = rtc_valid_tm(&time); ret = rtc_valid_tm(&time);
if (ret) { if (ret) {
struct rtc_time def_time = { struct rtc_time def_time = {
.tm_year = 1, .tm_year = 1,
.tm_mday = 1, .tm_mday = 1,
}; };
set_rtc_time(&def_time); cmos_set_time(&pdev->dev, &def_time);
} }
} }
#else #else
......
...@@ -85,6 +85,7 @@ static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) ...@@ -85,6 +85,7 @@ static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY;
rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR;
rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN;
rtc_tm->tm_sec = 0;
ret = rtc_valid_tm(rtc_tm); ret = rtc_valid_tm(rtc_tm);
return ret; return ret;
......
...@@ -74,6 +74,7 @@ static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) ...@@ -74,6 +74,7 @@ static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY;
rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR;
rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN;
rtc_tm->tm_sec = 0;
return rtc_valid_tm(rtc_tm); return rtc_valid_tm(rtc_tm);
} }
......
...@@ -388,6 +388,8 @@ static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -388,6 +388,8 @@ static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
u8 day0, day1; u8 day0, day1;
unsigned long flags; unsigned long flags;
alm->time.tm_sec = 0;
spin_lock_irqsave(&davinci_rtc_lock, flags); spin_lock_irqsave(&davinci_rtc_lock, flags);
davinci_rtcss_calendar_wait(davinci_rtc); davinci_rtcss_calendar_wait(davinci_rtc);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/ds1286.h> #include <linux/rtc/ds1286.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -313,13 +313,6 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -313,13 +313,6 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]);
alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); alm->time.tm_min = bcd2bin(buf[DS1305_MIN]);
alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]);
alm->time.tm_mday = -1;
alm->time.tm_mon = -1;
alm->time.tm_year = -1;
/* next three fields are unused by Linux */
alm->time.tm_wday = -1;
alm->time.tm_mday = -1;
alm->time.tm_isdst = -1;
return 0; return 0;
} }
......
...@@ -482,11 +482,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -482,11 +482,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
t->time.tm_mon = -1;
t->time.tm_year = -1;
t->time.tm_wday = -1;
t->time.tm_yday = -1;
t->time.tm_isdst = -1;
/* ... and status */ /* ... and status */
t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
...@@ -602,6 +597,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { ...@@ -602,6 +597,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
* Alarm support for mcp794xx devices. * Alarm support for mcp794xx devices.
*/ */
#define MCP794XX_REG_WEEKDAY 0x3
#define MCP794XX_REG_WEEKDAY_WDAY_MASK 0x7
#define MCP794XX_REG_CONTROL 0x07 #define MCP794XX_REG_CONTROL 0x07
# define MCP794XX_BIT_ALM0_EN 0x10 # define MCP794XX_BIT_ALM0_EN 0x10
# define MCP794XX_BIT_ALM1_EN 0x20 # define MCP794XX_BIT_ALM1_EN 0x20
...@@ -1231,13 +1228,16 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1231,13 +1228,16 @@ static int ds1307_probe(struct i2c_client *client,
{ {
struct ds1307 *ds1307; struct ds1307 *ds1307;
int err = -ENODEV; int err = -ENODEV;
int tmp; int tmp, wday;
struct chip_desc *chip = &chips[id->driver_data]; struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
bool want_irq = false; bool want_irq = false;
bool ds1307_can_wakeup_device = false; bool ds1307_can_wakeup_device = false;
unsigned char *buf; unsigned char *buf;
struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
struct rtc_time tm;
unsigned long timestamp;
irq_handler_t irq_handler = ds1307_irq; irq_handler_t irq_handler = ds1307_irq;
static const int bbsqi_bitpos[] = { static const int bbsqi_bitpos[] = {
...@@ -1526,6 +1526,27 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1526,6 +1526,27 @@ static int ds1307_probe(struct i2c_client *client,
bin2bcd(tmp)); bin2bcd(tmp));
} }
/*
* Some IPs have weekday reset value = 0x1 which might not correct
* hence compute the wday using the current date/month/year values
*/
ds1307_get_time(&client->dev, &tm);
wday = tm.tm_wday;
timestamp = rtc_tm_to_time64(&tm);
rtc_time64_to_tm(timestamp, &tm);
/*
* Check if reset wday is different from the computed wday
* If different then set the wday which we computed using
* timestamp
*/
if (wday != tm.tm_wday) {
wday = i2c_smbus_read_byte_data(client, MCP794XX_REG_WEEKDAY);
wday = wday & ~MCP794XX_REG_WEEKDAY_WDAY_MASK;
wday = wday | (tm.tm_wday + 1);
i2c_smbus_write_byte_data(client, MCP794XX_REG_WEEKDAY, wday);
}
if (want_irq) { if (want_irq) {
device_set_wakeup_capable(&client->dev, true); device_set_wakeup_capable(&client->dev, true);
set_bit(HAS_ALARM, &ds1307->flags); set_bit(HAS_ALARM, &ds1307->flags);
......
...@@ -504,12 +504,6 @@ static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -504,12 +504,6 @@ static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour; alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour;
alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday; alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday;
alarm->time.tm_mon = -1;
alarm->time.tm_year = -1;
alarm->time.tm_wday = -1;
alarm->time.tm_yday = -1;
alarm->time.tm_isdst = -1;
out: out:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return res; return res;
......
...@@ -102,6 +102,26 @@ ds1685_rtc_bin2bcd(struct ds1685_priv *rtc, u8 val, u8 bin_mask, u8 bcd_mask) ...@@ -102,6 +102,26 @@ ds1685_rtc_bin2bcd(struct ds1685_priv *rtc, u8 val, u8 bin_mask, u8 bcd_mask)
return (val & bin_mask); return (val & bin_mask);
} }
/**
* s1685_rtc_check_mday - check validity of the day of month.
* @rtc: pointer to the ds1685 rtc structure.
* @mday: day of month.
*
* Returns -EDOM if the day of month is not within 1..31 range.
*/
static inline int
ds1685_rtc_check_mday(struct ds1685_priv *rtc, u8 mday)
{
if (rtc->bcd_mode) {
if (mday < 0x01 || mday > 0x31 || (mday & 0x0f) > 0x09)
return -EDOM;
} else {
if (mday < 1 || mday > 31)
return -EDOM;
}
return 0;
}
/** /**
* ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0. * ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0.
* @rtc: pointer to the ds1685 rtc structure. * @rtc: pointer to the ds1685 rtc structure.
...@@ -377,6 +397,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -377,6 +397,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev); struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 seconds, minutes, hours, mday, ctrlb, ctrlc; u8 seconds, minutes, hours, mday, ctrlb, ctrlc;
int ret;
/* Fetch the alarm info from the RTC alarm registers. */ /* Fetch the alarm info from the RTC alarm registers. */
ds1685_rtc_begin_data_access(rtc); ds1685_rtc_begin_data_access(rtc);
...@@ -388,34 +409,29 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -388,34 +409,29 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
ctrlc = rtc->read(rtc, RTC_CTRL_C); ctrlc = rtc->read(rtc, RTC_CTRL_C);
ds1685_rtc_end_data_access(rtc); ds1685_rtc_end_data_access(rtc);
/* Check month date. */ /* Check the month date for validity. */
if (!(mday >= 1) && (mday <= 31)) ret = ds1685_rtc_check_mday(rtc, mday);
return -EDOM; if (ret)
return ret;
/* /*
* Check the three alarm bytes. * Check the three alarm bytes.
* *
* The Linux RTC system doesn't support the "don't care" capability * The Linux RTC system doesn't support the "don't care" capability
* of this RTC chip. We check for it anyways in case support is * of this RTC chip. We check for it anyways in case support is
* added in the future. * added in the future and only assign when we care.
*/ */
if (unlikely(seconds >= 0xc0)) if (likely(seconds < 0xc0))
alrm->time.tm_sec = -1;
else
alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds,
RTC_SECS_BCD_MASK, RTC_SECS_BCD_MASK,
RTC_SECS_BIN_MASK); RTC_SECS_BIN_MASK);
if (unlikely(minutes >= 0xc0)) if (likely(minutes < 0xc0))
alrm->time.tm_min = -1;
else
alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes,
RTC_MINS_BCD_MASK, RTC_MINS_BCD_MASK,
RTC_MINS_BIN_MASK); RTC_MINS_BIN_MASK);
if (unlikely(hours >= 0xc0)) if (likely(hours < 0xc0))
alrm->time.tm_hour = -1;
else
alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours,
RTC_HRS_24_BCD_MASK, RTC_HRS_24_BCD_MASK,
RTC_HRS_24_BIN_MASK); RTC_HRS_24_BIN_MASK);
...@@ -423,11 +439,6 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -423,11 +439,6 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* Write the data to rtc_wkalrm. */ /* Write the data to rtc_wkalrm. */
alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK, alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK,
RTC_MDAY_BIN_MASK); RTC_MDAY_BIN_MASK);
alrm->time.tm_mon = -1;
alrm->time.tm_year = -1;
alrm->time.tm_wday = -1;
alrm->time.tm_yday = -1;
alrm->time.tm_isdst = -1;
alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE); alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE);
alrm->pending = !!(ctrlc & RTC_CTRL_C_AF); alrm->pending = !!(ctrlc & RTC_CTRL_C_AF);
...@@ -445,6 +456,7 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -445,6 +456,7 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev); struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, seconds, minutes, hours, mday; u8 ctrlb, seconds, minutes, hours, mday;
int ret;
/* Fetch the alarm info and convert to BCD. */ /* Fetch the alarm info and convert to BCD. */
seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec, seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec,
...@@ -461,8 +473,9 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -461,8 +473,9 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
RTC_MDAY_BCD_MASK); RTC_MDAY_BCD_MASK);
/* Check the month date for validity. */ /* Check the month date for validity. */
if (!(mday >= 1) && (mday <= 31)) ret = ds1685_rtc_check_mday(rtc, mday);
return -EDOM; if (ret)
return ret;
/* /*
* Check the three alarm bytes. * Check the three alarm bytes.
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/rtc-ds2404.h> #include <linux/platform_data/rtc-ds2404.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -197,12 +197,6 @@ static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -197,12 +197,6 @@ static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F);
alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F);
alarm->time.tm_mon = -1;
alarm->time.tm_year = -1;
alarm->time.tm_wday = -1;
alarm->time.tm_yday = -1;
alarm->time.tm_isdst = -1;
alarm->enabled = !!(control & DS3232_REG_CR_A1IE); alarm->enabled = !!(control & DS3232_REG_CR_A1IE);
alarm->pending = !!(stat & DS3232_REG_SR_A1F); alarm->pending = !!(stat & DS3232_REG_SR_A1F);
......
...@@ -259,6 +259,12 @@ static const struct rtc_class_ops efi_rtc_ops = { ...@@ -259,6 +259,12 @@ static const struct rtc_class_ops efi_rtc_ops = {
static int __init efi_rtc_probe(struct platform_device *dev) static int __init efi_rtc_probe(struct platform_device *dev)
{ {
struct rtc_device *rtc; struct rtc_device *rtc;
efi_time_t eft;
efi_time_cap_t cap;
/* First check if the RTC is usable */
if (efi.get_time(&eft, &cap) != EFI_SUCCESS)
return -ENODEV;
rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops, rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops,
THIS_MODULE); THIS_MODULE);
......
...@@ -9,44 +9,10 @@ ...@@ -9,44 +9,10 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#if defined(CONFIG_M68K) || defined(CONFIG_PARISC) || \
defined(CONFIG_PPC) || defined(CONFIG_SUPERH32)
#include <asm/rtc.h>
static int generic_get_time(struct device *dev, struct rtc_time *tm)
{
unsigned int ret = get_rtc_time(tm);
if (ret & RTC_BATT_BAD)
return -EOPNOTSUPP;
return rtc_valid_tm(tm);
}
static int generic_set_time(struct device *dev, struct rtc_time *tm)
{
if (set_rtc_time(tm) < 0)
return -EOPNOTSUPP;
return 0;
}
static const struct rtc_class_ops generic_rtc_ops = {
.read_time = generic_get_time,
.set_time = generic_set_time,
};
#else
#define generic_rtc_ops *(struct rtc_class_ops*)NULL
#endif
static int __init generic_rtc_probe(struct platform_device *dev) static int __init generic_rtc_probe(struct platform_device *dev)
{ {
struct rtc_device *rtc; struct rtc_device *rtc;
const struct rtc_class_ops *ops; const struct rtc_class_ops *ops = dev_get_platdata(&dev->dev);
ops = dev_get_platdata(&dev->dev);
if (!ops)
ops = &generic_rtc_ops;
rtc = devm_rtc_device_register(&dev->dev, "rtc-generic", rtc = devm_rtc_device_register(&dev->dev, "rtc-generic",
ops, THIS_MODULE); ops, THIS_MODULE);
......
...@@ -198,7 +198,7 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -198,7 +198,7 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
return ret; return ret;
/* The alarm only has a minute accuracy */ /* The alarm only has a minute accuracy */
alm_tm->tm_sec = -1; alm_tm->tm_sec = 0;
alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ? alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ?
-1 : -1 :
...@@ -213,9 +213,6 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -213,9 +213,6 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
-1 : -1 :
bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK); bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK);
alm_tm->tm_mon = -1;
alm_tm->tm_year = -1;
ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -245,8 +245,7 @@ static int isl12057_rtc_update_alarm(struct device *dev, int enable) ...@@ -245,8 +245,7 @@ static int isl12057_rtc_update_alarm(struct device *dev, int enable)
static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ {
struct isl12057_rtc_data *data = dev_get_drvdata(dev); struct isl12057_rtc_data *data = dev_get_drvdata(dev);
struct rtc_time rtc_tm, *alarm_tm = &alarm->time; struct rtc_time *alarm_tm = &alarm->time;
unsigned long rtc_secs, alarm_secs;
u8 regs[ISL12057_A1_SEC_LEN]; u8 regs[ISL12057_A1_SEC_LEN];
unsigned int ir; unsigned int ir;
int ret; int ret;
...@@ -264,36 +263,6 @@ static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -264,36 +263,6 @@ static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f); alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f);
alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f); alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f);
alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f); alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f);
alarm_tm->tm_wday = -1;
/*
* The alarm section does not store year/month. We use the ones in rtc
* section as a basis and increment month and then year if needed to get
* alarm after current time.
*/
ret = _isl12057_rtc_read_time(dev, &rtc_tm);
if (ret)
goto err_unlock;
alarm_tm->tm_year = rtc_tm.tm_year;
alarm_tm->tm_mon = rtc_tm.tm_mon;
ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
if (ret)
goto err_unlock;
ret = rtc_tm_to_time(alarm_tm, &alarm_secs);
if (ret)
goto err_unlock;
if (alarm_secs < rtc_secs) {
if (alarm_tm->tm_mon == 11) {
alarm_tm->tm_mon = 0;
alarm_tm->tm_year += 1;
} else {
alarm_tm->tm_mon += 1;
}
}
ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir); ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir);
if (ret) { if (ret) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment