Commit e8dff03a authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RTC updates from Alexandre Belloni:
 "Not much this cycle apart from the ingenic rtc driver rework.

  The fixes are mainly minor issues reported by coccinelle rather than
  real world issues.

  Subsystem:

   - new VL flag for backup switch over

  Drivers:

   - ingenic: only support device tree

   - pcf2127: report battery switch over, handle nowayout"

* tag 'rtc-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (29 commits)
  rtc: pcf2127: watchdog: handle nowayout feature
  rtc: fsl-ftm-alarm: fix freeze(s2idle) failed to wake
  rtc: abx80x: Provide debug feedback for invalid dt properties
  rtc: abx80x: Add Device Tree matching table
  rtc: rv3028: Add missed check for devm_regmap_init_i2c()
  rtc: mpc5121: Use correct return value for mpc5121_rtc_probe()
  rtc: goldfish: Use correct return value for goldfish_rtc_probe()
  rtc: snvs: Add necessary clock operations for RTC APIs
  rtc: snvs: Make SNVS clock always prepared
  rtc: ingenic: Reset regulator register in probe
  rtc: ingenic: Fix masking of error code
  rtc: ingenic: Remove unused fields from private structure
  rtc: ingenic: Set wakeup params in probe
  rtc: ingenic: Enable clock in probe
  rtc: ingenic: Use local 'dev' variable in probe
  rtc: ingenic: Only support probing from devicetree
  rtc: mc13xxx: fix a double-unlock issue
  rtc: stmp3xxx: update contact email
  rtc: max77686: Use single-byte writes on MAX77620
  rtc: pcf2127: report battery switch over
  ...
parents 787f74fc 4601e24a
......@@ -1680,6 +1680,7 @@ config RTC_DRV_MPC5121
config RTC_DRV_JZ4740
tristate "Ingenic JZ4740 SoC"
depends on MIPS || COMPILE_TEST
depends on OF
help
If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
controllers.
......
......@@ -106,12 +106,6 @@ static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm)
unsigned char buf[4];
unsigned long ticks, base, data;
if (tm->tm_year > 206) {
dev_dbg(info->dev, "Set time %d out of range. "
"Please set time between 1970 to 2106.\n",
1900 + tm->tm_year);
return -EINVAL;
}
ticks = rtc_tm_to_time64(tm);
/* load 32-bit read-only counter */
......
......@@ -13,6 +13,7 @@
#include <linux/bcd.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/rtc.h>
#include <linux/watchdog.h>
......@@ -554,8 +555,9 @@ static const struct rtc_class_ops abx80x_rtc_ops = {
.ioctl = abx80x_ioctl,
};
static int abx80x_dt_trickle_cfg(struct device_node *np)
static int abx80x_dt_trickle_cfg(struct i2c_client *client)
{
struct device_node *np = client->dev.of_node;
const char *diode;
int trickle_cfg = 0;
int i, ret;
......@@ -565,12 +567,14 @@ static int abx80x_dt_trickle_cfg(struct device_node *np)
if (ret)
return ret;
if (!strcmp(diode, "standard"))
if (!strcmp(diode, "standard")) {
trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE;
else if (!strcmp(diode, "schottky"))
} else if (!strcmp(diode, "schottky")) {
trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE;
else
} else {
dev_dbg(&client->dev, "Invalid tc-diode value: %s\n", diode);
return -EINVAL;
}
ret = of_property_read_u32(np, "abracon,tc-resistor", &tmp);
if (ret)
......@@ -580,8 +584,10 @@ static int abx80x_dt_trickle_cfg(struct device_node *np)
if (trickle_resistors[i] == tmp)
break;
if (i == sizeof(trickle_resistors))
if (i == sizeof(trickle_resistors)) {
dev_dbg(&client->dev, "Invalid tc-resistor value: %u\n", tmp);
return -EINVAL;
}
return (trickle_cfg | i);
}
......@@ -793,7 +799,7 @@ static int abx80x_probe(struct i2c_client *client,
}
if (np && abx80x_caps[part].has_tc)
trickle_cfg = abx80x_dt_trickle_cfg(np);
trickle_cfg = abx80x_dt_trickle_cfg(client);
if (trickle_cfg > 0) {
dev_info(&client->dev, "Enabling trickle charger: %02x\n",
......@@ -863,9 +869,57 @@ static const struct i2c_device_id abx80x_id[] = {
};
MODULE_DEVICE_TABLE(i2c, abx80x_id);
#ifdef CONFIG_OF
static const struct of_device_id abx80x_of_match[] = {
{
.compatible = "abracon,abx80x",
.data = (void *)ABX80X
},
{
.compatible = "abracon,ab0801",
.data = (void *)AB0801
},
{
.compatible = "abracon,ab0803",
.data = (void *)AB0803
},
{
.compatible = "abracon,ab0804",
.data = (void *)AB0804
},
{
.compatible = "abracon,ab0805",
.data = (void *)AB0805
},
{
.compatible = "abracon,ab1801",
.data = (void *)AB1801
},
{
.compatible = "abracon,ab1803",
.data = (void *)AB1803
},
{
.compatible = "abracon,ab1804",
.data = (void *)AB1804
},
{
.compatible = "abracon,ab1805",
.data = (void *)AB1805
},
{
.compatible = "microcrystal,rv1805",
.data = (void *)RV1805
},
{ }
};
MODULE_DEVICE_TABLE(of, abx80x_of_match);
#endif
static struct i2c_driver abx80x_driver = {
.driver = {
.name = "rtc-abx80x",
.of_match_table = of_match_ptr(abx80x_of_match),
},
.probe = abx80x_probe,
.id_table = abx80x_id,
......
......@@ -21,6 +21,7 @@
#include <linux/rtc.h>
#include <linux/time.h>
#include <linux/acpi.h>
#include <linux/pm_wakeirq.h>
#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_MASK_SHIFT)
......@@ -268,13 +269,11 @@ static int ftm_rtc_probe(struct platform_device *pdev)
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "can't get irq number\n");
if (irq < 0)
return irq;
}
ret = devm_request_irq(&pdev->dev, irq, ftm_rtc_alarm_interrupt,
IRQF_NO_SUSPEND, dev_name(&pdev->dev), rtc);
0, dev_name(&pdev->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "failed to request irq\n");
return ret;
......@@ -287,6 +286,9 @@ static int ftm_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->ops = &ftm_rtc_ops;
device_init_wakeup(&pdev->dev, true);
ret = dev_pm_set_wake_irq(&pdev->dev, irq);
if (ret)
dev_err(&pdev->dev, "failed to enable irq wake\n");
ret = rtc_register_device(rtc->rtc_dev);
if (ret) {
......
......@@ -174,7 +174,7 @@ static int goldfish_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtcdrv);
rtcdrv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtcdrv->base))
return -ENODEV;
return PTR_ERR(rtcdrv->base);
rtcdrv->irq = platform_get_irq(pdev, 0);
if (rtcdrv->irq < 0)
......
......@@ -55,14 +55,8 @@ struct jz4740_rtc {
enum jz4740_rtc_type type;
struct rtc_device *rtc;
struct clk *clk;
int irq;
spinlock_t lock;
unsigned int min_wakeup_pin_assert_time;
unsigned int reset_pin_assert_time;
};
static struct device *dev_for_power_off;
......@@ -259,156 +253,157 @@ static void jz4740_rtc_poweroff(struct device *dev)
static void jz4740_rtc_power_off(void)
{
struct jz4740_rtc *rtc = dev_get_drvdata(dev_for_power_off);
unsigned long rtc_rate;
unsigned long wakeup_filter_ticks;
unsigned long reset_counter_ticks;
jz4740_rtc_poweroff(dev_for_power_off);
kernel_halt();
}
static void jz4740_rtc_clk_disable(void *data)
{
clk_disable_unprepare(data);
}
static const struct of_device_id jz4740_rtc_of_match[] = {
{ .compatible = "ingenic,jz4740-rtc", .data = (void *)ID_JZ4740 },
{ .compatible = "ingenic,jz4760-rtc", .data = (void *)ID_JZ4760 },
{ .compatible = "ingenic,jz4780-rtc", .data = (void *)ID_JZ4780 },
{},
};
MODULE_DEVICE_TABLE(of, jz4740_rtc_of_match);
clk_prepare_enable(rtc->clk);
static void jz4740_rtc_set_wakeup_params(struct jz4740_rtc *rtc,
struct device_node *np,
unsigned long rate)
{
unsigned long wakeup_ticks, reset_ticks;
unsigned int min_wakeup_pin_assert_time = 60; /* Default: 60ms */
unsigned int reset_pin_assert_time = 100; /* Default: 100ms */
rtc_rate = clk_get_rate(rtc->clk);
of_property_read_u32(np, "ingenic,reset-pin-assert-time-ms",
&reset_pin_assert_time);
of_property_read_u32(np, "ingenic,min-wakeup-pin-assert-time-ms",
&min_wakeup_pin_assert_time);
/*
* Set minimum wakeup pin assertion time: 100 ms.
* Range is 0 to 2 sec if RTC is clocked at 32 kHz.
*/
wakeup_filter_ticks =
(rtc->min_wakeup_pin_assert_time * rtc_rate) / 1000;
if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
wakeup_ticks = (min_wakeup_pin_assert_time * rate) / 1000;
if (wakeup_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
wakeup_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
else
wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
jz4740_rtc_reg_write(rtc,
JZ_REG_RTC_WAKEUP_FILTER, wakeup_filter_ticks);
wakeup_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_WAKEUP_FILTER, wakeup_ticks);
/*
* Set reset pin low-level assertion time after wakeup: 60 ms.
* Range is 0 to 125 ms if RTC is clocked at 32 kHz.
*/
reset_counter_ticks = (rtc->reset_pin_assert_time * rtc_rate) / 1000;
if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
reset_ticks = (reset_pin_assert_time * rate) / 1000;
if (reset_ticks < JZ_RTC_RESET_COUNTER_MASK)
reset_ticks &= JZ_RTC_RESET_COUNTER_MASK;
else
reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK;
jz4740_rtc_reg_write(rtc,
JZ_REG_RTC_RESET_COUNTER, reset_counter_ticks);
jz4740_rtc_poweroff(dev_for_power_off);
kernel_halt();
reset_ticks = JZ_RTC_RESET_COUNTER_MASK;
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_RESET_COUNTER, reset_ticks);
}
static const struct of_device_id jz4740_rtc_of_match[] = {
{ .compatible = "ingenic,jz4740-rtc", .data = (void *)ID_JZ4740 },
{ .compatible = "ingenic,jz4760-rtc", .data = (void *)ID_JZ4760 },
{ .compatible = "ingenic,jz4780-rtc", .data = (void *)ID_JZ4780 },
{},
};
MODULE_DEVICE_TABLE(of, jz4740_rtc_of_match);
static int jz4740_rtc_probe(struct platform_device *pdev)
{
int ret;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct jz4740_rtc *rtc;
const struct platform_device_id *id = platform_get_device_id(pdev);
const struct of_device_id *of_id = of_match_device(
jz4740_rtc_of_match, &pdev->dev);
struct device_node *np = pdev->dev.of_node;
unsigned long rate;
struct clk *clk;
int ret, irq;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
if (of_id)
rtc->type = (enum jz4740_rtc_type)of_id->data;
else
rtc->type = id->driver_data;
rtc->type = (enum jz4740_rtc_type)device_get_match_data(dev);
rtc->irq = platform_get_irq(pdev, 0);
if (rtc->irq < 0)
return -ENOENT;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
rtc->clk = devm_clk_get(&pdev->dev, "rtc");
if (IS_ERR(rtc->clk)) {
dev_err(&pdev->dev, "Failed to get RTC clock\n");
return PTR_ERR(rtc->clk);
clk = devm_clk_get(dev, "rtc");
if (IS_ERR(clk)) {
dev_err(dev, "Failed to get RTC clock\n");
return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(dev, "Failed to enable clock\n");
return ret;
}
ret = devm_add_action_or_reset(dev, jz4740_rtc_clk_disable, clk);
if (ret) {
dev_err(dev, "Failed to register devm action\n");
return ret;
}
spin_lock_init(&rtc->lock);
platform_set_drvdata(pdev, rtc);
device_init_wakeup(&pdev->dev, 1);
device_init_wakeup(dev, 1);
ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq);
ret = dev_pm_set_wake_irq(dev, irq);
if (ret) {
dev_err(&pdev->dev, "Failed to set wake irq: %d\n", ret);
dev_err(dev, "Failed to set wake irq: %d\n", ret);
return ret;
}
rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
rtc->rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
dev_err(&pdev->dev, "Failed to allocate rtc device: %d\n", ret);
dev_err(dev, "Failed to allocate rtc device: %d\n", ret);
return ret;
}
rtc->rtc->ops = &jz4740_rtc_ops;
rtc->rtc->range_max = U32_MAX;
rate = clk_get_rate(clk);
jz4740_rtc_set_wakeup_params(rtc, np, rate);
/* Each 1 Hz pulse should happen after (rate) ticks */
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_REGULATOR, rate - 1);
ret = rtc_register_device(rtc->rtc);
if (ret)
return ret;
ret = devm_request_irq(&pdev->dev, rtc->irq, jz4740_rtc_irq, 0,
ret = devm_request_irq(dev, irq, jz4740_rtc_irq, 0,
pdev->name, rtc);
if (ret) {
dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
dev_err(dev, "Failed to request rtc irq: %d\n", ret);
return ret;
}
if (np && of_device_is_system_power_controller(np)) {
if (!pm_power_off) {
/* Default: 60ms */
rtc->reset_pin_assert_time = 60;
of_property_read_u32(np,
"ingenic,reset-pin-assert-time-ms",
&rtc->reset_pin_assert_time);
/* Default: 100ms */
rtc->min_wakeup_pin_assert_time = 100;
of_property_read_u32(np,
"ingenic,min-wakeup-pin-assert-time-ms",
&rtc->min_wakeup_pin_assert_time);
dev_for_power_off = &pdev->dev;
if (of_device_is_system_power_controller(np)) {
dev_for_power_off = dev;
if (!pm_power_off)
pm_power_off = jz4740_rtc_power_off;
} else {
dev_warn(&pdev->dev,
"Poweroff handler already present!\n");
}
else
dev_warn(dev, "Poweroff handler already present!\n");
}
return 0;
}
static const struct platform_device_id jz4740_rtc_ids[] = {
{ "jz4740-rtc", ID_JZ4740 },
{ "jz4780-rtc", ID_JZ4780 },
{}
};
MODULE_DEVICE_TABLE(platform, jz4740_rtc_ids);
static struct platform_driver jz4740_rtc_driver = {
.probe = jz4740_rtc_probe,
.driver = {
.name = "jz4740-rtc",
.of_match_table = of_match_ptr(jz4740_rtc_of_match),
.of_match_table = jz4740_rtc_of_match,
},
.id_table = jz4740_rtc_ids,
};
module_platform_driver(jz4740_rtc_driver);
......
......@@ -205,10 +205,8 @@ static int lpc24xx_rtc_probe(struct platform_device *pdev)
return PTR_ERR(rtc->rtc_base);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_warn(&pdev->dev, "can't get interrupt resource\n");
if (irq < 0)
return irq;
}
rtc->clk_rtc = devm_clk_get(&pdev->dev, "rtc");
if (IS_ERR(rtc->clk_rtc)) {
......
......@@ -78,6 +78,8 @@ struct max77686_rtc_driver_data {
int alarm_pending_status_reg;
/* RTC IRQ CHIP for regmap */
const struct regmap_irq_chip *rtc_irq_chip;
/* regmap configuration for the chip */
const struct regmap_config *regmap_config;
};
struct max77686_rtc_info {
......@@ -182,6 +184,11 @@ static const struct regmap_irq_chip max77686_rtc_irq_chip = {
.num_irqs = ARRAY_SIZE(max77686_rtc_irqs),
};
static const struct regmap_config max77686_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static const struct max77686_rtc_driver_data max77686_drv_data = {
.delay = 16000,
.mask = 0x7f,
......@@ -191,6 +198,13 @@ static const struct max77686_rtc_driver_data max77686_drv_data = {
.alarm_pending_status_reg = MAX77686_REG_STATUS2,
.rtc_i2c_addr = MAX77686_I2C_ADDR_RTC,
.rtc_irq_chip = &max77686_rtc_irq_chip,
.regmap_config = &max77686_rtc_regmap_config,
};
static const struct regmap_config max77620_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.use_single_write = true,
};
static const struct max77686_rtc_driver_data max77620_drv_data = {
......@@ -202,6 +216,7 @@ static const struct max77686_rtc_driver_data max77620_drv_data = {
.alarm_pending_status_reg = MAX77686_INVALID_REG,
.rtc_i2c_addr = MAX77620_I2C_ADDR_RTC,
.rtc_irq_chip = &max77686_rtc_irq_chip,
.regmap_config = &max77620_rtc_regmap_config,
};
static const unsigned int max77802_map[REG_RTC_END] = {
......@@ -658,11 +673,6 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
return ret;
}
static const struct regmap_config max77686_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
{
struct device *parent = info->dev->parent;
......@@ -698,7 +708,7 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
}
info->rtc_regmap = devm_regmap_init_i2c(info->rtc,
&max77686_rtc_regmap_config);
info->drv_data->regmap_config);
if (IS_ERR(info->rtc_regmap)) {
ret = PTR_ERR(info->rtc_regmap);
dev_err(info->dev, "Failed to allocate RTC regmap: %d\n", ret);
......
......@@ -308,8 +308,10 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
mc13xxx_unlock(mc13xxx);
ret = rtc_register_device(priv->rtc);
if (ret)
if (ret) {
mc13xxx_lock(mc13xxx);
goto err_irq_request;
}
return 0;
......
......@@ -316,7 +316,7 @@ static int mpc5121_rtc_probe(struct platform_device *op)
rtc->regs = devm_platform_ioremap_resource(op, 0);
if (IS_ERR(rtc->regs)) {
dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
return -ENOSYS;
return PTR_ERR(rtc->regs);
}
device_init_wakeup(&op->dev, 1);
......
......@@ -310,7 +310,6 @@ static const struct rtc_class_ops mt2712_rtc_ops = {
static int mt2712_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct mt2712_rtc *mt2712_rtc;
int ret;
......@@ -319,8 +318,7 @@ static int mt2712_rtc_probe(struct platform_device *pdev)
if (!mt2712_rtc)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mt2712_rtc->base = devm_ioremap_resource(&pdev->dev, res);
mt2712_rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mt2712_rtc->base))
return PTR_ERR(mt2712_rtc->base);
......@@ -328,10 +326,8 @@ static int mt2712_rtc_probe(struct platform_device *pdev)
mt2712_rtc_hw_init(mt2712_rtc);
mt2712_rtc->irq = platform_get_irq(pdev, 0);
if (mt2712_rtc->irq < 0) {
dev_err(&pdev->dev, "No IRQ resource\n");
if (mt2712_rtc->irq < 0)
return mt2712_rtc->irq;
}
platform_set_drvdata(pdev, mt2712_rtc);
......@@ -356,13 +352,7 @@ static int mt2712_rtc_probe(struct platform_device *pdev)
mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127;
ret = rtc_register_device(mt2712_rtc->rtc);
if (ret) {
dev_err(&pdev->dev, "register rtc device failed\n");
return ret;
}
return 0;
return rtc_register_device(mt2712_rtc->rtc);
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -137,8 +137,7 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]);
if (tm->tm_year < 70)
tm->tm_year += 100; /* assume we are in 1970...2069 */
tm->tm_year += 100;
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
......@@ -172,7 +171,7 @@ static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[i++] = bin2bcd(tm->tm_mon + 1);
/* year */
buf[i++] = bin2bcd(tm->tm_year % 100);
buf[i++] = bin2bcd(tm->tm_year - 100);
/* write register's data */
err = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_SC, buf, i);
......@@ -185,30 +184,35 @@ static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
return 0;
}
#ifdef CONFIG_RTC_INTF_DEV
static int pcf2127_rtc_ioctl(struct device *dev,
unsigned int cmd, unsigned long arg)
{
struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
int touser;
int val, touser = 0;
int ret;
switch (cmd) {
case RTC_VL_READ:
ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &touser);
ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &val);
if (ret)
return ret;
touser = touser & PCF2127_BIT_CTRL3_BLF ? RTC_VL_BACKUP_LOW : 0;
if (val & PCF2127_BIT_CTRL3_BLF)
touser |= RTC_VL_BACKUP_LOW;
if (val & PCF2127_BIT_CTRL3_BF)
touser |= RTC_VL_BACKUP_SWITCH;
return put_user(touser, (unsigned int __user *)arg);
case RTC_VL_CLR:
return regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
PCF2127_BIT_CTRL3_BF, 0);
default:
return -ENOIOCTLCMD;
}
}
#else
#define pcf2127_rtc_ioctl NULL
#endif
static const struct rtc_class_ops pcf2127_rtc_ops = {
.ioctl = pcf2127_rtc_ioctl,
......@@ -433,6 +437,9 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
return PTR_ERR(pcf2127->rtc);
pcf2127->rtc->ops = &pcf2127_rtc_ops;
pcf2127->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099;
pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */
pcf2127->wdd.parent = dev;
pcf2127->wdd.info = &pcf2127_wdt_info;
......@@ -441,6 +448,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
pcf2127->wdd.max_timeout = PCF2127_WD_VAL_MAX;
pcf2127->wdd.timeout = PCF2127_WD_VAL_DEFAULT;
pcf2127->wdd.min_hw_heartbeat_ms = 500;
pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
watchdog_set_drvdata(&pcf2127->wdd, pcf2127);
......@@ -495,7 +503,6 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
*/
ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
PCF2127_BIT_CTRL3_BTSE |
PCF2127_BIT_CTRL3_BF |
PCF2127_BIT_CTRL3_BIE |
PCF2127_BIT_CTRL3_BLIE, 0);
if (ret) {
......@@ -636,6 +643,7 @@ static int pcf2127_i2c_probe(struct i2c_client *client,
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x1d,
};
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
......@@ -703,6 +711,7 @@ static int pcf2127_spi_probe(struct spi_device *spi)
.val_bits = 8,
.read_flag_mask = 0xa0,
.write_flag_mask = 0x20,
.max_register = 0x1d,
};
struct regmap *regmap;
......
......@@ -356,10 +356,8 @@ static int rc5t619_rtc_probe(struct platform_device *pdev)
int err;
rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
if (!rtc)
return -ENOMEM;
}
rtc->rn5t618 = rn5t618;
......
......@@ -755,6 +755,8 @@ static int rv3028_probe(struct i2c_client *client)
return -ENOMEM;
rv3028->regmap = devm_regmap_init_i2c(client, &regmap_config);
if (IS_ERR(rv3028->regmap))
return PTR_ERR(rv3028->regmap);
i2c_set_clientdata(client, rv3028);
......
......@@ -148,10 +148,21 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
unsigned long time = rtc_read_lp_counter(data);
unsigned long time;
int ret;
if (data->clk) {
ret = clk_enable(data->clk);
if (ret)
return ret;
}
time = rtc_read_lp_counter(data);
rtc_time64_to_tm(time, tm);
if (data->clk)
clk_disable(data->clk);
return 0;
}
......@@ -161,6 +172,12 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
unsigned long time = rtc_tm_to_time64(tm);
int ret;
if (data->clk) {
ret = clk_enable(data->clk);
if (ret)
return ret;
}
/* Disable RTC first */
ret = snvs_rtc_enable(data, false);
if (ret)
......@@ -173,6 +190,9 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Enable RTC again */
ret = snvs_rtc_enable(data, true);
if (data->clk)
clk_disable(data->clk);
return ret;
}
......@@ -180,6 +200,13 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
u32 lptar, lpsr;
int ret;
if (data->clk) {
ret = clk_enable(data->clk);
if (ret)
return ret;
}
regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
rtc_time64_to_tm(lptar, &alrm->time);
......@@ -187,18 +214,33 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
if (data->clk)
clk_disable(data->clk);
return 0;
}
static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
int ret;
if (data->clk) {
ret = clk_enable(data->clk);
if (ret)
return ret;
}
regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
return rtc_write_sync_lp(data);
ret = rtc_write_sync_lp(data);
if (data->clk)
clk_disable(data->clk);
return ret;
}
static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
......@@ -207,6 +249,12 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
unsigned long time = rtc_tm_to_time64(&alrm->time);
int ret;
if (data->clk) {
ret = clk_enable(data->clk);
if (ret)
return ret;
}
regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
ret = rtc_write_sync_lp(data);
if (ret)
......@@ -216,6 +264,9 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* Clear alarm interrupt status bit */
regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
if (data->clk)
clk_disable(data->clk);
return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
}
......@@ -362,7 +413,7 @@ static int __maybe_unused snvs_rtc_suspend_noirq(struct device *dev)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
if (data->clk)
clk_disable_unprepare(data->clk);
clk_disable(data->clk);
return 0;
}
......@@ -372,7 +423,7 @@ static int __maybe_unused snvs_rtc_resume_noirq(struct device *dev)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
if (data->clk)
return clk_prepare_enable(data->clk);
return clk_enable(data->clk);
return 0;
}
......
......@@ -416,5 +416,5 @@ module_platform_driver(stmp3xxx_rtcdrv);
MODULE_DESCRIPTION("STMP3xxx RTC Driver");
MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and "
"Wolfram Sang <w.sang@pengutronix.de>");
"Wolfram Sang <kernel@pengutronix.de>");
MODULE_LICENSE("GPL");
......@@ -99,6 +99,7 @@ struct rtc_pll_info {
#define RTC_VL_BACKUP_LOW _BITUL(1) /* Backup voltage is low */
#define RTC_VL_BACKUP_EMPTY _BITUL(2) /* Backup empty or not present */
#define RTC_VL_ACCURACY_LOW _BITUL(3) /* Voltage is low, RTC accuracy is reduced */
#define RTC_VL_BACKUP_SWITCH _BITUL(4) /* Backup switchover happened */
#define RTC_VL_READ _IOR('p', 0x13, unsigned int) /* Voltage low detection */
#define RTC_VL_CLR _IO('p', 0x14) /* Clear voltage low information */
......
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