Skip to content

Commit

Permalink
Merge tag 'rtc-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "Core:
   - fix module reference count in rtc-proc
   - Replace simple_strtoul by kstrtoul

  New driver:
   - Epson RX8010SJ

  Subsystem wide cleanups:
   - use %ph for short hex dumps
   - constify *_chip_ops structures

  Drivers:
   - abx80x: Microcrystal rv1805 support, alarm support
   - cmos: prevent kernel warning on IRQ flags mismatch
   - s5m: various cleanups
   - rv8803: rx8900 compatibility, small error path fix
   - sunxi: various cleanups
   - lpc32xx: remove irq > NR_IRQS check from probe()
   - imxdi: fix spelling mistake in warning message
   - ds1685: don't try to micromanage sysfs output size
   - da9063: avoid writing undefined data to rtc
   - gemini: Remove unnecessary platform_set_drvdata()
   - efi: add efi_procfs in efi_rtc_ops
   - pcf8523: refuse to write dates later than 2099"

* tag 'rtc-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (24 commits)
  rtc: cmos: prevent kernel warning on IRQ flags mismatch
  rtc: rtc-ds2404: constify ds2404_chip_ops structures
  rtc: s5m: Make register configuration per S2MPS device to remove exceptions
  rtc: s5m: Add separate field for storing auto-cleared mask in register config
  rtc: s5m: Cleanup by removing useless 'rtc' prefix from fields
  rtc: Replace simple_strtoul by kstrtoul
  rtc: abx80x: add alarm support
  rtc: abx80x: Add Microcrystal rv1805 support
  rtc: v3020: constify v3020_chip_ops structures
  rtc: rv8803: Extend compatibility with the rx8900
  rtc: rv8803: fix handling return value of i2c_smbus_read_byte_data
  rtc: Add Epson RX8010SJ RTC driver
  rtc: lpc32xx: remove irq > NR_IRQS check from probe()
  rtc: imxdi: fix spelling mistake in warning message
  rtc: ds1685: don't try to micromanage sysfs output size
  rtc: use %ph for short hex dumps
  rtc: da9063: avoid writing undefined data to rtc
  rtc: sunxi: use of_device_get_match_data
  rtc: sunxi: constify the data_year_param structure
  rtc: sunxi: fix signedness issues
  ...
  • Loading branch information
Linus Torvalds committed Jan 18, 2016
2 parents d43fb9f + 079062b commit c38dec7
Show file tree
Hide file tree
Showing 22 changed files with 894 additions and 130 deletions.
10 changes: 10 additions & 0 deletions drivers/rtc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,16 @@ config RTC_DRV_FM3130
This driver can also be built as a module. If so the module
will be called rtc-fm3130.

config RTC_DRV_RX8010
tristate "Epson RX8010SJ"
depends on I2C
help
If you say yes here you get support for the Epson RX8010SJ RTC
chip.

This driver can also be built as a module. If so, the module
will be called rtc-rx8010.

config RTC_DRV_RX8581
tristate "Epson RX-8581"
help
Expand Down
1 change: 1 addition & 0 deletions drivers/rtc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o
obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o
obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o
obj-$(CONFIG_RTC_DRV_RX8010) += rtc-rx8010.o
obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o
obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o
obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
Expand Down
146 changes: 142 additions & 4 deletions drivers/rtc/rtc-abx80x.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,28 @@
#define ABX8XX_REG_YR 0x06
#define ABX8XX_REG_WD 0x07

#define ABX8XX_REG_AHTH 0x08
#define ABX8XX_REG_ASC 0x09
#define ABX8XX_REG_AMN 0x0a
#define ABX8XX_REG_AHR 0x0b
#define ABX8XX_REG_ADA 0x0c
#define ABX8XX_REG_AMO 0x0d
#define ABX8XX_REG_AWD 0x0e

#define ABX8XX_REG_STATUS 0x0f
#define ABX8XX_STATUS_AF BIT(2)

#define ABX8XX_REG_CTRL1 0x10
#define ABX8XX_CTRL_WRITE BIT(0)
#define ABX8XX_CTRL_ARST BIT(2)
#define ABX8XX_CTRL_12_24 BIT(6)

#define ABX8XX_REG_IRQ 0x12
#define ABX8XX_IRQ_AIE BIT(2)
#define ABX8XX_IRQ_IM_1_4 (0x3 << 5)

#define ABX8XX_REG_CD_TIMER_CTL 0x18

#define ABX8XX_REG_CFG_KEY 0x1f
#define ABX8XX_CFG_KEY_MISC 0x9d

Expand Down Expand Up @@ -63,8 +81,6 @@ static struct abx80x_cap abx80x_caps[] = {
[ABX80X] = {.pn = 0}
};

static struct i2c_driver abx80x_driver;

static int abx80x_enable_trickle_charger(struct i2c_client *client,
u8 trickle_cfg)
{
Expand Down Expand Up @@ -148,9 +164,111 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
return 0;
}

static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct rtc_device *rtc = i2c_get_clientdata(client);
int status;

status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
if (status < 0)
return IRQ_NONE;

if (status & ABX8XX_STATUS_AF)
rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);

i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);

return IRQ_HANDLED;
}

static int abx80x_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
unsigned char buf[7];

int irq_mask, err;

if (client->irq <= 0)
return -EINVAL;

err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ASC,
sizeof(buf), buf);
if (err)
return err;

irq_mask = i2c_smbus_read_byte_data(client, ABX8XX_REG_IRQ);
if (irq_mask < 0)
return irq_mask;

t->time.tm_sec = bcd2bin(buf[0] & 0x7F);
t->time.tm_min = bcd2bin(buf[1] & 0x7F);
t->time.tm_hour = bcd2bin(buf[2] & 0x3F);
t->time.tm_mday = bcd2bin(buf[3] & 0x3F);
t->time.tm_mon = bcd2bin(buf[4] & 0x1F) - 1;
t->time.tm_wday = buf[5] & 0x7;

t->enabled = !!(irq_mask & ABX8XX_IRQ_AIE);
t->pending = (buf[6] & ABX8XX_STATUS_AF) && t->enabled;

return err;
}

static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
u8 alarm[6];
int err;

if (client->irq <= 0)
return -EINVAL;

alarm[0] = 0x0;
alarm[1] = bin2bcd(t->time.tm_sec);
alarm[2] = bin2bcd(t->time.tm_min);
alarm[3] = bin2bcd(t->time.tm_hour);
alarm[4] = bin2bcd(t->time.tm_mday);
alarm[5] = bin2bcd(t->time.tm_mon + 1);

err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_AHTH,
sizeof(alarm), alarm);
if (err < 0) {
dev_err(&client->dev, "Unable to write alarm registers\n");
return -EIO;
}

if (t->enabled) {
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ,
(ABX8XX_IRQ_IM_1_4 |
ABX8XX_IRQ_AIE));
if (err)
return err;
}

return 0;
}

static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
int err;

if (enabled)
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ,
(ABX8XX_IRQ_IM_1_4 |
ABX8XX_IRQ_AIE));
else
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ,
ABX8XX_IRQ_IM_1_4);
return err;
}

static const struct rtc_class_ops abx80x_rtc_ops = {
.read_time = abx80x_rtc_read_time,
.set_time = abx80x_rtc_set_time,
.read_alarm = abx80x_read_alarm,
.set_alarm = abx80x_set_alarm,
.alarm_irq_enable = abx80x_alarm_irq_enable,
};

static int abx80x_dt_trickle_cfg(struct device_node *np)
Expand Down Expand Up @@ -225,7 +343,8 @@ static int abx80x_probe(struct i2c_client *client,
}

err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1,
((data & ~ABX8XX_CTRL_12_24) |
((data & ~(ABX8XX_CTRL_12_24 |
ABX8XX_CTRL_ARST)) |
ABX8XX_CTRL_WRITE));
if (err < 0) {
dev_err(&client->dev, "Unable to write control register\n");
Expand Down Expand Up @@ -260,14 +379,32 @@ static int abx80x_probe(struct i2c_client *client,
abx80x_enable_trickle_charger(client, trickle_cfg);
}

rtc = devm_rtc_device_register(&client->dev, abx80x_driver.driver.name,
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CD_TIMER_CTL,
BIT(2));
if (err)
return err;

rtc = devm_rtc_device_register(&client->dev, "abx8xx",
&abx80x_rtc_ops, THIS_MODULE);

if (IS_ERR(rtc))
return PTR_ERR(rtc);

i2c_set_clientdata(client, rtc);

if (client->irq > 0) {
dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
abx80x_handle_irq,
IRQF_SHARED | IRQF_ONESHOT,
"abx8xx",
client);
if (err) {
dev_err(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0;
}
}

return 0;
}

Expand All @@ -286,6 +423,7 @@ static const struct i2c_device_id abx80x_id[] = {
{ "ab1803", AB1803 },
{ "ab1804", AB1804 },
{ "ab1805", AB1805 },
{ "rv1805", AB1805 },
{ }
};
MODULE_DEVICE_TABLE(i2c, abx80x_id);
Expand Down
2 changes: 1 addition & 1 deletion drivers/rtc/rtc-cmos.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
rtc_cmos_int_handler = cmos_interrupt;

retval = request_irq(rtc_irq, rtc_cmos_int_handler,
0, dev_name(&cmos_rtc.rtc->dev),
IRQF_SHARED, dev_name(&cmos_rtc.rtc->dev),
cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
Expand Down
23 changes: 6 additions & 17 deletions drivers/rtc/rtc-da9063.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,24 +191,13 @@ static void da9063_tm_to_data(struct rtc_time *tm, u8 *data,
{
const struct da9063_compatible_rtc_regmap *config = rtc->config;

data[RTC_SEC] &= ~config->rtc_count_sec_mask;
data[RTC_SEC] |= tm->tm_sec & config->rtc_count_sec_mask;

data[RTC_MIN] &= ~config->rtc_count_min_mask;
data[RTC_MIN] |= tm->tm_min & config->rtc_count_min_mask;

data[RTC_HOUR] &= ~config->rtc_count_hour_mask;
data[RTC_HOUR] |= tm->tm_hour & config->rtc_count_hour_mask;

data[RTC_DAY] &= ~config->rtc_count_day_mask;
data[RTC_DAY] |= tm->tm_mday & config->rtc_count_day_mask;

data[RTC_MONTH] &= ~config->rtc_count_month_mask;
data[RTC_MONTH] |= MONTHS_TO_DA9063(tm->tm_mon) &
data[RTC_SEC] = tm->tm_sec & config->rtc_count_sec_mask;
data[RTC_MIN] = tm->tm_min & config->rtc_count_min_mask;
data[RTC_HOUR] = tm->tm_hour & config->rtc_count_hour_mask;
data[RTC_DAY] = tm->tm_mday & config->rtc_count_day_mask;
data[RTC_MONTH] = MONTHS_TO_DA9063(tm->tm_mon) &
config->rtc_count_month_mask;

data[RTC_YEAR] &= ~config->rtc_count_year_mask;
data[RTC_YEAR] |= YEARS_TO_DA9063(tm->tm_year) &
data[RTC_YEAR] = YEARS_TO_DA9063(tm->tm_year) &
config->rtc_count_year_mask;
}

Expand Down
8 changes: 2 additions & 6 deletions drivers/rtc/rtc-ds1305.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time)
if (status < 0)
return status;

dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
"read", buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6]);
dev_vdbg(dev, "%s: %3ph, %4ph\n", "read", &buf[0], &buf[3]);

/* Decode the registers */
time->tm_sec = bcd2bin(buf[DS1305_SEC]);
Expand Down Expand Up @@ -232,9 +230,7 @@ static int ds1305_set_time(struct device *dev, struct rtc_time *time)
*bp++ = bin2bcd(time->tm_mon + 1);
*bp++ = bin2bcd(time->tm_year - 100);

dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
"write", buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6], buf[7]);
dev_dbg(dev, "%s: %3ph, %4ph\n", "write", &buf[1], &buf[4]);

/* use write-then-read since dma from stack is nonportable */
return spi_write_then_read(ds1305->spi, buf, sizeof(buf),
Expand Down
17 changes: 4 additions & 13 deletions drivers/rtc/rtc-ds1307.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
return -EIO;
}

dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
"alarm read",
ds1307->regs[0], ds1307->regs[1],
ds1307->regs[2], ds1307->regs[3],
ds1307->regs[4], ds1307->regs[5],
ds1307->regs[6], ds1307->regs[7],
ds1307->regs[8]);
dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read",
&ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]);

/*
* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
Expand Down Expand Up @@ -522,12 +517,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
control = ds1307->regs[7];
status = ds1307->regs[8];

dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
"alarm set (old status)",
ds1307->regs[0], ds1307->regs[1],
ds1307->regs[2], ds1307->regs[3],
ds1307->regs[4], ds1307->regs[5],
ds1307->regs[6], control, status);
dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)",
&ds1307->regs[0], &ds1307->regs[4], control, status);

/* set ALARM1, using 24 hour and day-of-month modes */
buf[0] = bin2bcd(t->time.tm_sec);
Expand Down
Loading

0 comments on commit c38dec7

Please sign in to comment.