RTC for 5.3

Drivers:
  - ds1307: properly handle oscillator failure flags
  - imx-sc: alarm support
  - pcf2123: alarm support, correct offset handling
  - sun6i: add R40 support
  - simplify getting the adapter of an i2c client
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEycoQi/giopmpPgB12wIijOdRNOUFAl0tl5UACgkQ2wIijOdR
 NOVMig/8C7o1tBpm1Kfs3GYjZ5o2SI7m6425OypONOa9U2rFVnFHxVogtIHTC7wa
 SXVFdV+L/MT/xHEbQ3Mfv36cRB0h3Q89NqcVWFkjSGvoqliTIA2F2zsLDHYLDyEO
 AdOc8ztzrTCmlPjrg7d64qxA/l/dPChIhDW1nsMTJY7EXO0lBywcEP0KQsnOrjzD
 lNDskhLuYaL0h1OL2KSrx/81ZZW1MXEyTU5nl4e2JowVYFB0f75P7h79MChmjM35
 wE5WVDH8LqhYHOoVR9fW5sjRpNgdKfFsH8Sh5DGVU3jLGA72v0Eo/c1BHHegumoI
 6X+09nv9D3j4l2z5on5TzXMhvwuLdZQ2VRBdpI1XcVjtYA18UTIXZA8wDRgLTb3b
 MZE31s1WM0vxSiGyaL+hfI9APfX0xSd+BIqVvxhUVPvCGCwWvfLJgQfmlsW4eWOk
 LdmifkLb0Mjf+ym+WH8GvXND+ZeNJ9eUUwVZkGHPhb6SfkLiEAnw3f1czOT1fLDR
 q6i0hG9/+BsiwZMCJt86rDZd1D51FjkNzUH1d///iURvaDhoi41nKaFR45kc5Foc
 WVmnWDWw1yg7K6kUQ3kXsyBkbw0jhdCXGN539rrvbElyL5e5XDUo+3gAEi25CkVe
 DCpxICWO+jvOrjJBHdH3T3HJDa7NbFXWkXOwLXe5M42q7rrgZwY=
 =aJ54
 -----END PGP SIGNATURE-----

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

Pull RTC updates from Alexandre Belloni:
 "A quiet cycle this time.

   - ds1307: properly handle oscillator failure flags

   - imx-sc: alarm support

   - pcf2123: alarm support, correct offset handling

   - sun6i: add R40 support

   - simplify getting the adapter of an i2c client"

* tag 'rtc-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (37 commits)
  rtc: wm831x: Add IRQF_ONESHOT flag
  rtc: stm32: remove one condition check in stm32_rtc_set_alarm()
  rtc: pcf2123: Fix build error
  rtc: interface: Change type of 'count' from int to u64
  rtc: pcf8563: Clear event flags and disable interrupts before requesting irq
  rtc: pcf8563: Fix interrupt trigger method
  rtc: pcf2123: fix negative offset rounding
  rtc: pcf2123: add alarm support
  rtc: pcf2123: use %ptR
  rtc: pcf2123: port to regmap
  rtc: pcf2123: remove sysfs register view
  rtc: rx8025: simplify getting the adapter of a client
  rtc: rx8010: simplify getting the adapter of a client
  rtc: rv8803: simplify getting the adapter of a client
  rtc: m41t80: simplify getting the adapter of a client
  rtc: fm3130: simplify getting the adapter of a client
  rtc: tegra: Drop MODULE_ALIAS
  rtc: sun6i: Add R40 compatible
  dt-bindings: rtc: sun6i: Add the R40 RTC compatible
  dt-bindings: rtc: Convert Allwinner A31 RTC to a schema
  ...
This commit is contained in:
Linus Torvalds 2019-07-17 10:03:50 -07:00
commit edafb6fe42
27 changed files with 821 additions and 568 deletions

View file

@ -562,7 +562,7 @@ config RTC_DRV_TPS6586X
config RTC_DRV_TPS65910
tristate "TI TPS65910 RTC driver"
depends on RTC_CLASS && MFD_TPS65910
depends on MFD_TPS65910
help
If you say yes here you get support for the RTC on the
TPS65910 chips.
@ -820,6 +820,7 @@ config RTC_DRV_MAX6902
config RTC_DRV_PCF2123
tristate "NXP PCF2123"
select REGMAP_SPI
help
If you say yes here you get support for the NXP PCF2123
RTC chip.

View file

@ -633,7 +633,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
{
struct rtc_device *rtc;
ktime_t period;
int count;
u64 count;
rtc = container_of(timer, struct rtc_device, pie_timer);

View file

@ -222,6 +222,45 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
return -EINVAL;
}
tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t0:
case m41t00:
case m41t11:
if (tmp & DS1307_BIT_CH)
return -EINVAL;
break;
case ds_1308:
case ds_1338:
if (tmp & DS1307_BIT_CH)
return -EINVAL;
ret = regmap_read(ds1307->regmap, DS1307_REG_CONTROL, &tmp);
if (ret)
return ret;
if (tmp & DS1338_BIT_OSF)
return -EINVAL;
break;
case ds_1340:
if (tmp & DS1340_BIT_nEOSC)
return -EINVAL;
ret = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
if (ret)
return ret;
if (tmp & DS1340_BIT_OSF)
return -EINVAL;
break;
case mcp794xx:
if (!(tmp & MCP794XX_BIT_ST))
return -EINVAL;
break;
default:
break;
}
t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f);
t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
tmp = regs[DS1307_REG_HOUR] & 0x3f;
@ -286,7 +325,17 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
if (t->tm_year > 199 && chip->century_bit)
regs[chip->century_reg] |= chip->century_bit;
if (ds1307->type == mcp794xx) {
switch (ds1307->type) {
case ds_1308:
case ds_1338:
regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL,
DS1338_BIT_OSF, 0);
break;
case ds_1340:
regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG,
DS1340_BIT_OSF, 0);
break;
case mcp794xx:
/*
* these bits were cleared when preparing the date/time
* values and need to be set again before writing the
@ -294,6 +343,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
*/
regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
break;
default:
break;
}
dev_dbg(dev, "%s: %7ph\n", "write", regs);
@ -1702,7 +1754,6 @@ static int ds1307_probe(struct i2c_client *client,
break;
}
read_rtc:
/* read RTC registers */
err = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
@ -1711,75 +1762,11 @@ read_rtc:
goto exit;
}
/*
* minimal sanity checking; some chips (like DS1340) don't
* specify the extra bits as must-be-zero, but there are
* still a few values that are clearly out-of-range.
*/
tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t0:
case m41t00:
case m41t11:
/* clock halted? turn it on, so clock can tick. */
if (tmp & DS1307_BIT_CH) {
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
}
break;
case ds_1308:
case ds_1338:
/* clock halted? turn it on, so clock can tick. */
if (tmp & DS1307_BIT_CH)
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
/* oscillator fault? clear flag, and warn */
if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
regs[DS1307_REG_CONTROL] &
~DS1338_BIT_OSF);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
}
break;
case ds_1340:
/* clock halted? turn it on, so clock can tick. */
if (tmp & DS1340_BIT_nEOSC)
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
err = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator fault? clear flag, and warn */
if (tmp & DS1340_BIT_OSF) {
regmap_write(ds1307->regmap, DS1340_REG_FLAG, 0);
dev_warn(ds1307->dev, "SET TIME!\n");
}
break;
case mcp794xx:
/* make sure that the backup battery is enabled */
if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
regs[DS1307_REG_WDAY] |
MCP794XX_BIT_VBATEN);
}
/* clock halted? turn it on, so clock can tick. */
if (!(tmp & MCP794XX_BIT_ST)) {
regmap_write(ds1307->regmap, DS1307_REG_SECS,
MCP794XX_BIT_ST);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
}
break;
default:
break;
if (ds1307->type == mcp794xx &&
!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
regs[DS1307_REG_WDAY] |
MCP794XX_BIT_VBATEN);
}
tmp = regs[DS1307_REG_HOUR];

View file

@ -182,9 +182,10 @@ static void ds2404_enable_osc(struct device *dev)
static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
{
unsigned long time = 0;
__le32 hw_time = 0;
ds2404_read_memory(dev, 0x203, 4, (u8 *)&time);
time = le32_to_cpu(time);
ds2404_read_memory(dev, 0x203, 4, (u8 *)&hw_time);
time = le32_to_cpu(hw_time);
rtc_time64_to_tm(time, dt);
return 0;

View file

@ -104,8 +104,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t)
fm3130_rtc_mode(dev, FM3130_MODE_READ);
/* read the RTC date and time registers all at once */
tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent),
fm3130->msg, 2);
tmp = i2c_transfer(fm3130->client->adapter, fm3130->msg, 2);
if (tmp != 2) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
@ -197,8 +196,7 @@ static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
}
/* read the RTC alarm registers all at once */
tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent),
&fm3130->msg[2], 2);
tmp = i2c_transfer(fm3130->client->adapter, &fm3130->msg[2], 2);
if (tmp != 2) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
@ -348,7 +346,7 @@ static int fm3130_probe(struct i2c_client *client,
struct fm3130 *fm3130;
int err = -ENODEV;
int tmp;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter,
I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))

View file

@ -3,6 +3,7 @@
* Copyright 2018 NXP.
*/
#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/arm-smccc.h>
#include <linux/firmware/imx/sci.h>
#include <linux/module.h>
@ -11,11 +12,15 @@
#include <linux/rtc.h>
#define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9
#define IMX_SC_TIMER_FUNC_SET_RTC_ALARM 8
#define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6
#define IMX_SIP_SRTC 0xC2000002
#define IMX_SIP_SRTC_SET_TIME 0x0
#define SC_IRQ_GROUP_RTC 2
#define SC_IRQ_RTC 1
static struct imx_sc_ipc *rtc_ipc_handle;
static struct rtc_device *imx_sc_rtc;
@ -24,6 +29,16 @@ struct imx_sc_msg_timer_get_rtc_time {
u32 time;
} __packed;
struct imx_sc_msg_timer_rtc_set_alarm {
struct imx_sc_rpc_msg hdr;
u16 year;
u8 mon;
u8 day;
u8 hour;
u8 min;
u8 sec;
} __packed;
static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct imx_sc_msg_timer_get_rtc_time msg;
@ -60,9 +75,77 @@ static int imx_sc_rtc_set_time(struct device *dev, struct rtc_time *tm)
return res.a0;
}
static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
{
return imx_scu_irq_group_enable(SC_IRQ_GROUP_RTC, SC_IRQ_RTC, enable);
}
static int imx_sc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
/*
* SCU firmware does NOT provide read alarm API, but .read_alarm
* callback is required by RTC framework to support alarm function,
* so just return here.
*/
return 0;
}
static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct imx_sc_msg_timer_rtc_set_alarm msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
int ret;
struct rtc_time *alrm_tm = &alrm->time;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_TIMER;
hdr->func = IMX_SC_TIMER_FUNC_SET_RTC_ALARM;
hdr->size = 3;
msg.year = alrm_tm->tm_year + 1900;
msg.mon = alrm_tm->tm_mon + 1;
msg.day = alrm_tm->tm_mday;
msg.hour = alrm_tm->tm_hour;
msg.min = alrm_tm->tm_min;
msg.sec = alrm_tm->tm_sec;
ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
if (ret) {
dev_err(dev, "set rtc alarm failed, ret %d\n", ret);
return ret;
}
ret = imx_sc_rtc_alarm_irq_enable(dev, alrm->enabled);
if (ret) {
dev_err(dev, "enable rtc alarm failed, ret %d\n", ret);
return ret;
}
return 0;
}
static const struct rtc_class_ops imx_sc_rtc_ops = {
.read_time = imx_sc_rtc_read_time,
.set_time = imx_sc_rtc_set_time,
.read_alarm = imx_sc_rtc_read_alarm,
.set_alarm = imx_sc_rtc_set_alarm,
.alarm_irq_enable = imx_sc_rtc_alarm_irq_enable,
};
static int imx_sc_rtc_alarm_notify(struct notifier_block *nb,
unsigned long event, void *group)
{
/* ignore non-rtc irq */
if (!((event & SC_IRQ_RTC) && (*(u8 *)group == SC_IRQ_GROUP_RTC)))
return 0;
rtc_update_irq(imx_sc_rtc, 1, RTC_IRQF | RTC_AF);
return 0;
}
static struct notifier_block imx_sc_rtc_alarm_sc_notifier = {
.notifier_call = imx_sc_rtc_alarm_notify,
};
static int imx_sc_rtc_probe(struct platform_device *pdev)
@ -73,6 +156,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
if (ret)
return ret;
device_init_wakeup(&pdev->dev, true);
imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(imx_sc_rtc))
return PTR_ERR(imx_sc_rtc);
@ -87,6 +172,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
return ret;
}
imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier);
return 0;
}

View file

@ -872,7 +872,7 @@ static struct notifier_block wdt_notifier = {
static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
int rc = 0;
struct rtc_time tm;
struct m41t80_data *m41t80_data = NULL;

View file

@ -40,7 +40,7 @@
#include <linux/rtc.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/sysfs.h>
#include <linux/regmap.h>
/* REGISTERS */
#define PCF2123_REG_CTRL1 (0x00) /* Control Register 1 */
@ -95,6 +95,7 @@
#define OFFSET_SIGN_BIT 6 /* 2's complement sign bit */
#define OFFSET_COARSE BIT(7) /* Coarse mode offset */
#define OFFSET_STEP (2170) /* Offset step in parts per billion */
#define OFFSET_MASK GENMASK(6, 0) /* Offset value */
/* READ/WRITE ADDRESS BITS */
#define PCF2123_WRITE BIT(4)
@ -103,120 +104,35 @@
static struct spi_driver pcf2123_driver;
struct pcf2123_sysfs_reg {
struct device_attribute attr;
char name[2];
};
struct pcf2123_plat_data {
struct rtc_device *rtc;
struct pcf2123_sysfs_reg regs[16];
struct regmap *map;
};
/*
* Causes a 30 nanosecond delay to ensure that the PCF2123 chip select
* is released properly after an SPI write. This function should be
* called after EVERY read/write call over SPI.
*/
static inline void pcf2123_delay_trec(void)
{
ndelay(30);
}
static int pcf2123_read(struct device *dev, u8 reg, u8 *rxbuf, size_t size)
{
struct spi_device *spi = to_spi_device(dev);
int ret;
reg |= PCF2123_READ;
ret = spi_write_then_read(spi, &reg, 1, rxbuf, size);
pcf2123_delay_trec();
return ret;
}
static int pcf2123_write(struct device *dev, u8 *txbuf, size_t size)
{
struct spi_device *spi = to_spi_device(dev);
int ret;
txbuf[0] |= PCF2123_WRITE;
ret = spi_write(spi, txbuf, size);
pcf2123_delay_trec();
return ret;
}
static int pcf2123_write_reg(struct device *dev, u8 reg, u8 val)
{
u8 txbuf[2];
txbuf[0] = reg;
txbuf[1] = val;
return pcf2123_write(dev, txbuf, sizeof(txbuf));
}
static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr,
char *buffer)
{
struct pcf2123_sysfs_reg *r;
u8 rxbuf[1];
unsigned long reg;
int ret;
r = container_of(attr, struct pcf2123_sysfs_reg, attr);
ret = kstrtoul(r->name, 16, &reg);
if (ret)
return ret;
ret = pcf2123_read(dev, reg, rxbuf, 1);
if (ret < 0)
return -EIO;
return sprintf(buffer, "0x%x\n", rxbuf[0]);
}
static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
const char *buffer, size_t count)
{
struct pcf2123_sysfs_reg *r;
unsigned long reg;
unsigned long val;
int ret;
r = container_of(attr, struct pcf2123_sysfs_reg, attr);
ret = kstrtoul(r->name, 16, &reg);
if (ret)
return ret;
ret = kstrtoul(buffer, 10, &val);
if (ret)
return ret;
ret = pcf2123_write_reg(dev, reg, val);
if (ret < 0)
return -EIO;
return count;
}
static const struct regmap_config pcf2123_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.read_flag_mask = PCF2123_READ,
.write_flag_mask = PCF2123_WRITE,
.max_register = PCF2123_REG_CTDWN_TMR,
};
static int pcf2123_read_offset(struct device *dev, long *offset)
{
int ret;
s8 reg;
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
int ret, val;
unsigned int reg;
ret = pcf2123_read(dev, PCF2123_REG_OFFSET, &reg, 1);
if (ret < 0)
ret = regmap_read(pdata->map, PCF2123_REG_OFFSET, &reg);
if (ret)
return ret;
if (reg & OFFSET_COARSE)
reg <<= 1; /* multiply by 2 and sign extend */
else
reg = sign_extend32(reg, OFFSET_SIGN_BIT);
val = sign_extend32((reg & OFFSET_MASK), OFFSET_SIGN_BIT);
*offset = ((long)reg) * OFFSET_STEP;
if (reg & OFFSET_COARSE)
val *= 2;
*offset = ((long)val) * OFFSET_STEP;
return 0;
}
@ -233,6 +149,7 @@ static int pcf2123_read_offset(struct device *dev, long *offset)
*/
static int pcf2123_set_offset(struct device *dev, long offset)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
s8 reg;
if (offset > OFFSET_STEP * 127)
@ -240,7 +157,7 @@ static int pcf2123_set_offset(struct device *dev, long offset)
else if (offset < OFFSET_STEP * -128)
reg = -128;
else
reg = (s8)((offset + (OFFSET_STEP >> 1)) / OFFSET_STEP);
reg = DIV_ROUND_CLOSEST(offset, OFFSET_STEP);
/* choose fine offset only for odd values in the normal range */
if (reg & 1 && reg <= 63 && reg >= -64) {
@ -252,16 +169,18 @@ static int pcf2123_set_offset(struct device *dev, long offset)
reg |= OFFSET_COARSE;
}
return pcf2123_write_reg(dev, PCF2123_REG_OFFSET, reg);
return regmap_write(pdata->map, PCF2123_REG_OFFSET, (unsigned int)reg);
}
static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
u8 rxbuf[7];
int ret;
ret = pcf2123_read(dev, PCF2123_REG_SC, rxbuf, sizeof(rxbuf));
if (ret < 0)
ret = regmap_bulk_read(pdata->map, PCF2123_REG_SC, rxbuf,
sizeof(rxbuf));
if (ret)
return ret;
if (rxbuf[0] & OSC_HAS_STOPPED) {
@ -279,82 +198,168 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
if (tm->tm_year < 70)
tm->tm_year += 100; /* assume we are in 1970...2069 */
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm);
return 0;
}
static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
u8 txbuf[8];
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
u8 txbuf[7];
int ret;
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm);
/* Stop the counter first */
ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_STOP);
if (ret < 0)
ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP);
if (ret)
return ret;
/* Set the new time */
txbuf[0] = PCF2123_REG_SC;
txbuf[1] = bin2bcd(tm->tm_sec & 0x7F);
txbuf[2] = bin2bcd(tm->tm_min & 0x7F);
txbuf[3] = bin2bcd(tm->tm_hour & 0x3F);
txbuf[4] = bin2bcd(tm->tm_mday & 0x3F);
txbuf[5] = tm->tm_wday & 0x07;
txbuf[6] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
txbuf[7] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100);
txbuf[0] = bin2bcd(tm->tm_sec & 0x7F);
txbuf[1] = bin2bcd(tm->tm_min & 0x7F);
txbuf[2] = bin2bcd(tm->tm_hour & 0x3F);
txbuf[3] = bin2bcd(tm->tm_mday & 0x3F);
txbuf[4] = tm->tm_wday & 0x07;
txbuf[5] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
txbuf[6] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100);
ret = pcf2123_write(dev, txbuf, sizeof(txbuf));
if (ret < 0)
ret = regmap_bulk_write(pdata->map, PCF2123_REG_SC, txbuf,
sizeof(txbuf));
if (ret)
return ret;
/* Start the counter */
ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_CLEAR);
if (ret < 0)
ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
if (ret)
return ret;
return 0;
}
static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
u8 rxbuf[4];
int ret;
unsigned int val = 0;
ret = regmap_bulk_read(pdata->map, PCF2123_REG_ALRM_MN, rxbuf,
sizeof(rxbuf));
if (ret)
return ret;
alm->time.tm_min = bcd2bin(rxbuf[0] & 0x7F);
alm->time.tm_hour = bcd2bin(rxbuf[1] & 0x3F);
alm->time.tm_mday = bcd2bin(rxbuf[2] & 0x3F);
alm->time.tm_wday = bcd2bin(rxbuf[3] & 0x07);
dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time);
ret = regmap_read(pdata->map, PCF2123_REG_CTRL2, &val);
if (ret)
return ret;
alm->enabled = !!(val & CTRL2_AIE);
return 0;
}
static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
u8 txbuf[4];
int ret;
dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time);
/* Ensure alarm flag is clear */
ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
if (ret)
return ret;
/* Disable alarm interrupt */
ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0);
if (ret)
return ret;
/* Set new alarm */
txbuf[0] = bin2bcd(alm->time.tm_min & 0x7F);
txbuf[1] = bin2bcd(alm->time.tm_hour & 0x3F);
txbuf[2] = bin2bcd(alm->time.tm_mday & 0x3F);
txbuf[3] = bin2bcd(alm->time.tm_wday & 0x07);
ret = regmap_bulk_write(pdata->map, PCF2123_REG_ALRM_MN, txbuf,
sizeof(txbuf));
if (ret)
return ret;
/* Enable alarm interrupt */
if (alm->enabled) {
ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2,
CTRL2_AIE, CTRL2_AIE);
if (ret)
return ret;
}
return 0;
}
static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
struct mutex *lock = &pdata->rtc->ops_lock;
unsigned int val = 0;
int ret = IRQ_NONE;
mutex_lock(lock);
regmap_read(pdata->map, PCF2123_REG_CTRL2, &val);
/* Alarm? */
if (val & CTRL2_AF) {
ret = IRQ_HANDLED;
/* Clear alarm flag */
regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
}
mutex_unlock(lock);
return ret;
}
static int pcf2123_reset(struct device *dev)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
int ret;
u8 rxbuf[2];
unsigned int val = 0;
ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
if (ret < 0)
ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
if (ret)
return ret;
/* Stop the counter */
dev_dbg(dev, "stopping RTC\n");
ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_STOP);
if (ret < 0)
ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP);
if (ret)
return ret;
/* See if the counter was actually stopped */
dev_dbg(dev, "checking for presence of RTC\n");
ret = pcf2123_read(dev, PCF2123_REG_CTRL1, rxbuf, sizeof(rxbuf));
if (ret < 0)
ret = regmap_read(pdata->map, PCF2123_REG_CTRL1, &val);
if (ret)
return ret;
dev_dbg(dev, "received data from RTC (0x%02X 0x%02X)\n",
rxbuf[0], rxbuf[1]);
if (!(rxbuf[0] & CTRL1_STOP))
dev_dbg(dev, "received data from RTC (0x%08X)\n", val);
if (!(val & CTRL1_STOP))
return -ENODEV;
/* Start the counter */
ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_CLEAR);
if (ret < 0)
ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
if (ret)
return ret;
return 0;
@ -365,7 +370,8 @@ static const struct rtc_class_ops pcf2123_rtc_ops = {
.set_time = pcf2123_rtc_set_time,
.read_offset = pcf2123_read_offset,
.set_offset = pcf2123_set_offset,
.read_alarm = pcf2123_rtc_read_alarm,
.set_alarm = pcf2123_rtc_set_alarm,
};
static int pcf2123_probe(struct spi_device *spi)
@ -373,7 +379,7 @@ static int pcf2123_probe(struct spi_device *spi)
struct rtc_device *rtc;
struct rtc_time tm;
struct pcf2123_plat_data *pdata;
int ret, i;
int ret = 0;
pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data),
GFP_KERNEL);
@ -381,6 +387,13 @@ static int pcf2123_probe(struct spi_device *spi)
return -ENOMEM;
spi->dev.platform_data = pdata;
pdata->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config);
if (IS_ERR(pdata->map)) {
dev_err(&spi->dev, "regmap init failed.\n");
goto kfree_exit;
}
ret = pcf2123_rtc_read_time(&spi->dev, &tm);
if (ret < 0) {
ret = pcf2123_reset(&spi->dev);
@ -405,47 +418,31 @@ static int pcf2123_probe(struct spi_device *spi)
pdata->rtc = rtc;
for (i = 0; i < 16; i++) {
sysfs_attr_init(&pdata->regs[i].attr.attr);
sprintf(pdata->regs[i].name, "%1x", i);
pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR;
pdata->regs[i].attr.attr.name = pdata->regs[i].name;
pdata->regs[i].attr.show = pcf2123_show;
pdata->regs[i].attr.store = pcf2123_store;
ret = device_create_file(&spi->dev, &pdata->regs[i].attr);
if (ret) {
dev_err(&spi->dev, "Unable to create sysfs %s\n",
pdata->regs[i].name);
goto sysfs_exit;
}
/* Register alarm irq */
if (spi->irq > 0) {
ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
pcf2123_rtc_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
pcf2123_driver.driver.name, &spi->dev);
if (!ret)
device_init_wakeup(&spi->dev, true);
else
dev_err(&spi->dev, "could not request irq.\n");
}
return 0;
/* The PCF2123's alarm only has minute accuracy. Must add timer
* support to this driver to generate interrupts more than once
* per minute.
*/
pdata->rtc->uie_unsupported = 1;
sysfs_exit:
for (i--; i >= 0; i--)
device_remove_file(&spi->dev, &pdata->regs[i].attr);
return 0;
kfree_exit:
spi->dev.platform_data = NULL;
return ret;
}
static int pcf2123_remove(struct spi_device *spi)
{
struct pcf2123_plat_data *pdata = dev_get_platdata(&spi->dev);
int i;
if (pdata) {
for (i = 0; i < 16; i++)
if (pdata->regs[i].name[0])
device_remove_file(&spi->dev,
&pdata->regs[i].attr);
}
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id pcf2123_dt_ids[] = {
{ .compatible = "nxp,rtc-pcf2123", },
@ -461,7 +458,6 @@ static struct spi_driver pcf2123_driver = {
.of_match_table = of_match_ptr(pcf2123_dt_ids),
},
.probe = pcf2123_probe,
.remove = pcf2123_remove,
};
module_spi_driver(pcf2123_driver);

View file

@ -560,7 +560,6 @@ static int pcf8563_probe(struct i2c_client *client,
struct pcf8563 *pcf8563;
int err;
unsigned char buf;
unsigned char alm_pending;
dev_dbg(&client->dev, "%s\n", __func__);
@ -584,13 +583,13 @@ static int pcf8563_probe(struct i2c_client *client,
return err;
}
err = pcf8563_get_alarm_mode(client, NULL, &alm_pending);
if (err) {
dev_err(&client->dev, "%s: read error\n", __func__);
/* Clear flags and disable interrupts */
buf = 0;
err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf);
if (err < 0) {
dev_err(&client->dev, "%s: write error\n", __func__);
return err;
}
if (alm_pending)
pcf8563_set_alarm_mode(client, 0);
pcf8563->rtc = devm_rtc_device_register(&client->dev,
pcf8563_driver.driver.name,
@ -602,7 +601,7 @@ static int pcf8563_probe(struct i2c_client *client,
if (client->irq > 0) {
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf8563_irq,
IRQF_SHARED|IRQF_ONESHOT|IRQF_TRIGGER_FALLING,
IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
pcf8563_driver.driver.name, client);
if (err) {
dev_err(&client->dev, "unable to request IRQ %d\n",

View file

@ -517,7 +517,7 @@ static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
static int rv8803_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rv8803_data *rv8803;
int err, flags;
struct nvmem_config nvmem_cfg = {

View file

@ -433,7 +433,7 @@ static struct rtc_class_ops rx8010_rtc_ops = {
static int rx8010_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rx8010_data *rx8010;
int err = 0;

View file

@ -501,7 +501,7 @@ static void rx8025_sysfs_unregister(struct device *dev)
static int rx8025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rx8025_data *rx8025;
int err = 0;

View file

@ -32,21 +32,22 @@
#define S35390A_ALRM_BYTE_MINS 2
/* flags for STATUS1 */
#define S35390A_FLAG_POC 0x01
#define S35390A_FLAG_BLD 0x02
#define S35390A_FLAG_INT2 0x04
#define S35390A_FLAG_24H 0x40
#define S35390A_FLAG_RESET 0x80
#define S35390A_FLAG_POC BIT(0)
#define S35390A_FLAG_BLD BIT(1)
#define S35390A_FLAG_INT2 BIT(2)
#define S35390A_FLAG_24H BIT(6)
#define S35390A_FLAG_RESET BIT(7)
/* flag for STATUS2 */
#define S35390A_FLAG_TEST 0x01
#define S35390A_INT2_MODE_MASK 0xF0
#define S35390A_FLAG_TEST BIT(0)
/* INT2 pin output mode */
#define S35390A_INT2_MODE_MASK 0x0E
#define S35390A_INT2_MODE_NOINTR 0x00
#define S35390A_INT2_MODE_FREQ 0x10
#define S35390A_INT2_MODE_ALARM 0x40
#define S35390A_INT2_MODE_PMIN_EDG 0x20
#define S35390A_INT2_MODE_ALARM BIT(1) /* INT2AE */
#define S35390A_INT2_MODE_PMIN_EDG BIT(2) /* INT2ME */
#define S35390A_INT2_MODE_FREQ BIT(3) /* INT2FE */
#define S35390A_INT2_MODE_PMIN (BIT(3) | BIT(2)) /* INT2FE | INT2ME */
static const struct i2c_device_id s35390a_id[] = {
{ "s35390a", 0 },
@ -284,6 +285,9 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
if (alm->time.tm_sec != 0)
dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n");
/* disable interrupt (which deasserts the irq line) */
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
if (err < 0)
@ -299,9 +303,6 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
else
sts = S35390A_INT2_MODE_NOINTR;
/* This chip expects the bits of each byte to be in reverse order */
sts = bitrev8(sts);
/* set interupt mode*/
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
if (err < 0)
@ -339,7 +340,7 @@ static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
if (err < 0)
return err;
if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) {
if ((sts & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) {
/*
* When the alarm isn't enabled, the register to configure
* the alarm time isn't accessible.
@ -431,14 +432,14 @@ static int s35390a_probe(struct i2c_client *client,
unsigned int i;
struct s35390a *s35390a;
char buf, status1;
struct device *dev = &client->dev;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
err = -ENODEV;
goto exit;
}
s35390a = devm_kzalloc(&client->dev, sizeof(struct s35390a),
GFP_KERNEL);
s35390a = devm_kzalloc(dev, sizeof(struct s35390a), GFP_KERNEL);
if (!s35390a) {
err = -ENOMEM;
goto exit;
@ -452,8 +453,8 @@ static int s35390a_probe(struct i2c_client *client,
s35390a->client[i] = i2c_new_dummy(client->adapter,
client->addr + i);
if (!s35390a->client[i]) {
dev_err(&client->dev, "Address %02x unavailable\n",
client->addr + i);
dev_err(dev, "Address %02x unavailable\n",
client->addr + i);
err = -EBUSY;
goto exit_dummy;
}
@ -462,7 +463,7 @@ static int s35390a_probe(struct i2c_client *client,
err_read = s35390a_read_status(s35390a, &status1);
if (err_read < 0) {
err = err_read;
dev_err(&client->dev, "error resetting chip\n");
dev_err(dev, "error resetting chip\n");
goto exit_dummy;
}
@ -476,28 +477,30 @@ static int s35390a_probe(struct i2c_client *client,
buf = 0;
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1);
if (err < 0) {
dev_err(&client->dev, "error disabling alarm");
dev_err(dev, "error disabling alarm");
goto exit_dummy;
}
} else {
err = s35390a_disable_test_mode(s35390a);
if (err < 0) {
dev_err(&client->dev, "error disabling test mode\n");
dev_err(dev, "error disabling test mode\n");
goto exit_dummy;
}
}
device_set_wakeup_capable(&client->dev, 1);
device_set_wakeup_capable(dev, 1);
s35390a->rtc = devm_rtc_device_register(&client->dev,
s35390a_driver.driver.name,
&s35390a_rtc_ops, THIS_MODULE);
s35390a->rtc = devm_rtc_device_register(dev, s35390a_driver.driver.name,
&s35390a_rtc_ops, THIS_MODULE);
if (IS_ERR(s35390a->rtc)) {
err = PTR_ERR(s35390a->rtc);
goto exit_dummy;
}
/* supports per-minute alarms only, therefore set uie_unsupported */
s35390a->rtc->uie_unsupported = 1;
if (status1 & S35390A_FLAG_INT2)
rtc_update_irq(s35390a->rtc, 1, RTC_AF);

View file

@ -162,10 +162,6 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
now_secs = rtc_tm_to_time64(&now);
alarm_secs = rtc_tm_to_time64(&t->time);
/* Invalid alarm time */
if (now_secs > alarm_secs)
return -EINVAL;
memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm));
/* Now many secs to fire */

View file

@ -519,11 +519,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* Write to Alarm register */
writel_relaxed(alrmar, rtc->base + regs->alrmar);
if (alrm->enabled)
stm32_rtc_alarm_irq_enable(dev, 1);
else
stm32_rtc_alarm_irq_enable(dev, 0);
stm32_rtc_alarm_irq_enable(dev, alrm->enabled);
end:
stm32_rtc_wpr_lock(rtc);

View file

@ -672,6 +672,7 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-rtc" },
{ .compatible = "allwinner,sun8i-a23-rtc" },
{ .compatible = "allwinner,sun8i-h3-rtc" },
{ .compatible = "allwinner,sun8i-r40-rtc" },
{ .compatible = "allwinner,sun8i-v3-rtc" },
{ .compatible = "allwinner,sun50i-h5-rtc" },
{ /* sentinel */ },

View file

@ -2,7 +2,7 @@
/*
* An RTC driver for the NVIDIA Tegra 200 series internal RTC.
*
* Copyright (c) 2010, NVIDIA Corporation.
* Copyright (c) 2010-2019, NVIDIA Corporation.
*/
#include <linux/clk.h>
@ -18,10 +18,10 @@
#include <linux/rtc.h>
#include <linux/slab.h>
/* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */
/* Set to 1 = busy every eight 32 kHz clocks during copy of sec+msec to AHB. */
#define TEGRA_RTC_REG_BUSY 0x004
#define TEGRA_RTC_REG_SECONDS 0x008
/* when msec is read, the seconds are buffered into shadow seconds. */
/* When msec is read, the seconds are buffered into shadow seconds. */
#define TEGRA_RTC_REG_SHADOW_SECONDS 0x00c
#define TEGRA_RTC_REG_MILLI_SECONDS 0x010
#define TEGRA_RTC_REG_SECONDS_ALARM0 0x014
@ -46,44 +46,48 @@
#define TEGRA_RTC_INTR_STATUS_SEC_ALARM0 (1<<0)
struct tegra_rtc_info {
struct platform_device *pdev;
struct rtc_device *rtc_dev;
void __iomem *rtc_base; /* NULL if not initialized. */
struct clk *clk;
int tegra_rtc_irq; /* alarm and periodic irq */
spinlock_t tegra_rtc_lock;
struct platform_device *pdev;
struct rtc_device *rtc;
void __iomem *base; /* NULL if not initialized */
struct clk *clk;
int irq; /* alarm and periodic IRQ */
spinlock_t lock;
};
/* RTC hardware is busy when it is updating its values over AHB once
* every eight 32kHz clocks (~250uS).
* outside of these updates the CPU is free to write.
* CPU is always free to read.
/*
* RTC hardware is busy when it is updating its values over AHB once every
* eight 32 kHz clocks (~250 us). Outside of these updates the CPU is free to
* write. CPU is always free to read.
*/
static inline u32 tegra_rtc_check_busy(struct tegra_rtc_info *info)
{
return readl(info->rtc_base + TEGRA_RTC_REG_BUSY) & 1;
return readl(info->base + TEGRA_RTC_REG_BUSY) & 1;
}
/* Wait for hardware to be ready for writing.
* This function tries to maximize the amount of time before the next update.
* It does this by waiting for the RTC to become busy with its periodic update,
* then returning once the RTC first becomes not busy.
/*
* Wait for hardware to be ready for writing. This function tries to maximize
* the amount of time before the next update. It does this by waiting for the
* RTC to become busy with its periodic update, then returning once the RTC
* first becomes not busy.
*
* This periodic update (where the seconds and milliseconds are copied to the
* AHB side) occurs every eight 32kHz clocks (~250uS).
* The behavior of this function allows us to make some assumptions without
* introducing a race, because 250uS is plenty of time to read/write a value.
* AHB side) occurs every eight 32 kHz clocks (~250 us). The behavior of this
* function allows us to make some assumptions without introducing a race,
* because 250 us is plenty of time to read/write a value.
*/
static int tegra_rtc_wait_while_busy(struct device *dev)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
int retries = 500; /* ~490 us is the worst case, ~250 us is best */
int retries = 500; /* ~490 us is the worst case, ~250 us is best. */
/* first wait for the RTC to become busy. this is when it
* posts its updated seconds+msec registers to AHB side. */
/*
* First wait for the RTC to become busy. This is when it posts its
* updated seconds+msec registers to AHB side.
*/
while (tegra_rtc_check_busy(info)) {
if (!retries--)
goto retry_failed;
udelay(1);
}
@ -91,28 +95,30 @@ static int tegra_rtc_wait_while_busy(struct device *dev)
return 0;
retry_failed:
dev_err(dev, "write failed:retry count exceeded.\n");
dev_err(dev, "write failed: retry count exceeded\n");
return -ETIMEDOUT;
}
static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long sec, msec;
unsigned long sl_irq_flags;
unsigned long flags;
u32 sec, msec;
/* RTC hardware copies seconds to shadow seconds when a read
* of milliseconds occurs. use a lock to keep other threads out. */
spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags);
/*
* RTC hardware copies seconds to shadow seconds when a read of
* milliseconds occurs. use a lock to keep other threads out.
*/
spin_lock_irqsave(&info->lock, flags);
msec = readl(info->rtc_base + TEGRA_RTC_REG_MILLI_SECONDS);
sec = readl(info->rtc_base + TEGRA_RTC_REG_SHADOW_SECONDS);
msec = readl(info->base + TEGRA_RTC_REG_MILLI_SECONDS);
sec = readl(info->base + TEGRA_RTC_REG_SHADOW_SECONDS);
spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags);
spin_unlock_irqrestore(&info->lock, flags);
rtc_time64_to_tm(sec, tm);
dev_vdbg(dev, "time read as %lu. %ptR\n", sec, tm);
dev_vdbg(dev, "time read as %u, %ptR\n", sec, tm);
return 0;
}
@ -120,21 +126,21 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long sec;
u32 sec;
int ret;
/* convert tm to seconds. */
/* convert tm to seconds */
sec = rtc_tm_to_time64(tm);
dev_vdbg(dev, "time set to %lu. %ptR\n", sec, tm);
dev_vdbg(dev, "time set to %u, %ptR\n", sec, tm);
/* seconds only written if wait succeeded. */
/* seconds only written if wait succeeded */
ret = tegra_rtc_wait_while_busy(dev);
if (!ret)
writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS);
writel(sec, info->base + TEGRA_RTC_REG_SECONDS);
dev_vdbg(dev, "time read back as %d\n",
readl(info->rtc_base + TEGRA_RTC_REG_SECONDS));
readl(info->base + TEGRA_RTC_REG_SECONDS));
return ret;
}
@ -142,22 +148,21 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long sec;
unsigned tmp;
u32 sec, value;
sec = readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
sec = readl(info->base + TEGRA_RTC_REG_SECONDS_ALARM0);
if (sec == 0) {
/* alarm is disabled. */
/* alarm is disabled */
alarm->enabled = 0;
} else {
/* alarm is enabled. */
/* alarm is enabled */
alarm->enabled = 1;
rtc_time64_to_tm(sec, &alarm->time);
}
tmp = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
alarm->pending = (tmp & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) != 0;
value = readl(info->base + TEGRA_RTC_REG_INTR_STATUS);
alarm->pending = (value & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) != 0;
return 0;
}
@ -165,22 +170,22 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned status;
unsigned long sl_irq_flags;
unsigned long flags;
u32 status;
tegra_rtc_wait_while_busy(dev);
spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags);
spin_lock_irqsave(&info->lock, flags);
/* read the original value, and OR in the flag. */
status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
/* read the original value, and OR in the flag */
status = readl(info->base + TEGRA_RTC_REG_INTR_MASK);
if (enabled)
status |= TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* set it */
else
status &= ~TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* clear it */
writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
writel(status, info->base + TEGRA_RTC_REG_INTR_MASK);
spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags);
spin_unlock_irqrestore(&info->lock, flags);
return 0;
}
@ -188,7 +193,7 @@ static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long sec;
u32 sec;
if (alarm->enabled)
sec = rtc_tm_to_time64(&alarm->time);
@ -196,16 +201,16 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
sec = 0;
tegra_rtc_wait_while_busy(dev);
writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
writel(sec, info->base + TEGRA_RTC_REG_SECONDS_ALARM0);
dev_vdbg(dev, "alarm read back as %d\n",
readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0));
readl(info->base + TEGRA_RTC_REG_SECONDS_ALARM0));
/* if successfully written and alarm is enabled ... */
if (sec) {
tegra_rtc_alarm_irq_enable(dev, 1);
dev_vdbg(dev, "alarm set as %lu. %ptR\n", sec, &alarm->time);
dev_vdbg(dev, "alarm set as %u, %ptR\n", sec, &alarm->time);
} else {
/* disable alarm if 0 or write error. */
/* disable alarm if 0 or write error */
dev_vdbg(dev, "alarm disabled\n");
tegra_rtc_alarm_irq_enable(dev, 0);
}
@ -227,39 +232,39 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
{
struct device *dev = data;
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long events = 0;
unsigned status;
unsigned long sl_irq_flags;
unsigned long events = 0, flags;
u32 status;
status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
status = readl(info->base + TEGRA_RTC_REG_INTR_STATUS);
if (status) {
/* clear the interrupt masks and status on any irq. */
/* clear the interrupt masks and status on any IRQ */
tegra_rtc_wait_while_busy(dev);
spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags);
writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags);
spin_lock_irqsave(&info->lock, flags);
writel(0, info->base + TEGRA_RTC_REG_INTR_MASK);
writel(status, info->base + TEGRA_RTC_REG_INTR_STATUS);
spin_unlock_irqrestore(&info->lock, flags);
}
/* check if Alarm */
if ((status & TEGRA_RTC_INTR_STATUS_SEC_ALARM0))
/* check if alarm */
if (status & TEGRA_RTC_INTR_STATUS_SEC_ALARM0)
events |= RTC_IRQF | RTC_AF;
/* check if Periodic */
if ((status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM))
/* check if periodic */
if (status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM)
events |= RTC_IRQF | RTC_PF;
rtc_update_irq(info->rtc_dev, 1, events);
rtc_update_irq(info->rtc, 1, events);
return IRQ_HANDLED;
}
static const struct rtc_class_ops tegra_rtc_ops = {
.read_time = tegra_rtc_read_time,
.set_time = tegra_rtc_set_time,
.read_alarm = tegra_rtc_read_alarm,
.set_alarm = tegra_rtc_set_alarm,
.proc = tegra_rtc_proc,
.read_time = tegra_rtc_read_time,
.set_time = tegra_rtc_set_time,
.read_alarm = tegra_rtc_read_alarm,
.set_alarm = tegra_rtc_set_alarm,
.proc = tegra_rtc_proc,
.alarm_irq_enable = tegra_rtc_alarm_irq_enable,
};
@ -269,21 +274,20 @@ static const struct of_device_id tegra_rtc_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, tegra_rtc_dt_match);
static int __init tegra_rtc_probe(struct platform_device *pdev)
static int tegra_rtc_probe(struct platform_device *pdev)
{
struct tegra_rtc_info *info;
struct resource *res;
int ret;
info = devm_kzalloc(&pdev->dev, sizeof(struct tegra_rtc_info),
GFP_KERNEL);
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->rtc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(info->rtc_base))
return PTR_ERR(info->rtc_base);
info->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(info->base))
return PTR_ERR(info->base);
ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
@ -291,14 +295,14 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
return ret;
}
info->tegra_rtc_irq = ret;
info->irq = ret;
info->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(info->rtc_dev))
return PTR_ERR(info->rtc_dev);
info->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(info->rtc))
return PTR_ERR(info->rtc);
info->rtc_dev->ops = &tegra_rtc_ops;
info->rtc_dev->range_max = U32_MAX;
info->rtc->ops = &tegra_rtc_ops;
info->rtc->range_max = U32_MAX;
info->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk))
@ -308,33 +312,30 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
/* set context info. */
/* set context info */
info->pdev = pdev;
spin_lock_init(&info->tegra_rtc_lock);
spin_lock_init(&info->lock);
platform_set_drvdata(pdev, info);
/* clear out the hardware. */
writel(0, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
/* clear out the hardware */
writel(0, info->base + TEGRA_RTC_REG_SECONDS_ALARM0);
writel(0xffffffff, info->base + TEGRA_RTC_REG_INTR_STATUS);
writel(0, info->base + TEGRA_RTC_REG_INTR_MASK);
device_init_wakeup(&pdev->dev, 1);
ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq,
tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH,
dev_name(&pdev->dev), &pdev->dev);
ret = devm_request_irq(&pdev->dev, info->irq, tegra_rtc_irq_handler,
IRQF_TRIGGER_HIGH, dev_name(&pdev->dev),
&pdev->dev);
if (ret) {
dev_err(&pdev->dev,
"Unable to request interrupt for device (err=%d).\n",
ret);
dev_err(&pdev->dev, "failed to request interrupt: %d\n", ret);
goto disable_clk;
}
ret = rtc_register_device(info->rtc_dev);
ret = rtc_register_device(info->rtc);
if (ret) {
dev_err(&pdev->dev, "Unable to register device (err=%d).\n",
ret);
dev_err(&pdev->dev, "failed to register device: %d\n", ret);
goto disable_clk;
}
@ -363,20 +364,20 @@ static int tegra_rtc_suspend(struct device *dev)
tegra_rtc_wait_while_busy(dev);
/* only use ALARM0 as a wake source. */
writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
/* only use ALARM0 as a wake source */
writel(0xffffffff, info->base + TEGRA_RTC_REG_INTR_STATUS);
writel(TEGRA_RTC_INTR_STATUS_SEC_ALARM0,
info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
info->base + TEGRA_RTC_REG_INTR_MASK);
dev_vdbg(dev, "alarm sec = %d\n",
readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0));
readl(info->base + TEGRA_RTC_REG_SECONDS_ALARM0));
dev_vdbg(dev, "Suspend (device_may_wakeup=%d) irq:%d\n",
device_may_wakeup(dev), info->tegra_rtc_irq);
dev_vdbg(dev, "Suspend (device_may_wakeup=%d) IRQ:%d\n",
device_may_wakeup(dev), info->irq);
/* leave the alarms on as a wake source. */
/* leave the alarms on as a wake source */
if (device_may_wakeup(dev))
enable_irq_wake(info->tegra_rtc_irq);
enable_irq_wake(info->irq);
return 0;
}
@ -386,10 +387,11 @@ static int tegra_rtc_resume(struct device *dev)
struct tegra_rtc_info *info = dev_get_drvdata(dev);
dev_vdbg(dev, "Resume (device_may_wakeup=%d)\n",
device_may_wakeup(dev));
/* alarms were left on as a wake source, turn them off. */
device_may_wakeup(dev));
/* alarms were left on as a wake source, turn them off */
if (device_may_wakeup(dev))
disable_irq_wake(info->tegra_rtc_irq);
disable_irq_wake(info->irq);
return 0;
}
@ -399,22 +401,21 @@ static SIMPLE_DEV_PM_OPS(tegra_rtc_pm_ops, tegra_rtc_suspend, tegra_rtc_resume);
static void tegra_rtc_shutdown(struct platform_device *pdev)
{
dev_vdbg(&pdev->dev, "disabling interrupts.\n");
dev_vdbg(&pdev->dev, "disabling interrupts\n");
tegra_rtc_alarm_irq_enable(&pdev->dev, 0);
}
MODULE_ALIAS("platform:tegra_rtc");
static struct platform_driver tegra_rtc_driver = {
.remove = tegra_rtc_remove,
.shutdown = tegra_rtc_shutdown,
.driver = {
.name = "tegra_rtc",
.probe = tegra_rtc_probe,
.remove = tegra_rtc_remove,
.shutdown = tegra_rtc_shutdown,
.driver = {
.name = "tegra_rtc",
.of_match_table = tegra_rtc_dt_match,
.pm = &tegra_rtc_pm_ops,
.pm = &tegra_rtc_pm_ops,
},
};
module_platform_driver_probe(tegra_rtc_driver, tegra_rtc_probe);
module_platform_driver(tegra_rtc_driver);
MODULE_AUTHOR("Jon Mayo <[email protected]>");
MODULE_DESCRIPTION("driver for Tegra internal RTC");

View file

@ -133,6 +133,7 @@ static int test_probe(struct platform_device *plat_dev)
break;
default:
rtd->rtc->ops = &test_rtc_ops;
device_init_wakeup(&plat_dev->dev, 1);
}
timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);

View file

@ -143,7 +143,7 @@ static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
struct tps65910 *tps = dev_get_drvdata(dev->parent);
int ret;
ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data,
ret = regmap_bulk_read(tps->regmap, TPS65910_ALARM_SECONDS, alarm_data,
NUM_TIME_REGS);
if (ret < 0) {
dev_err(dev, "rtc_read_alarm error %d\n", ret);

View file

@ -435,7 +435,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
wm831x_alm_irq,
IRQF_TRIGGER_RISING, "RTC alarm",
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"RTC alarm",
wm831x_rtc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",