Commit 8b70f716 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RTC updates from Alexandre Belloni:
 "RTC for 4.9

  Subsystem:
   - delete owner assignment in multiple drivers
   - constify rtc_class_ops structures

  Drivers:
   - ac100: support clock-output-names
   - cmos: properly handle ACPI alarms and quirky BIOSes and other fixes
   - ds1307: fix century bit support while staying comaptible with
     previous behaviour by default
   - ds1347: switch to regmap
   - isl12057 is now handled by ds1307
   - omap: support external wakeup
   - rv8803: allow to disable voltage drop detection"

* tag 'rtc-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (25 commits)
  rtc: rv8803: set VDETOFF and SWOFF via device tree
  dt/bindings: Add bindings for Micro Crystal rv8803
  devicetree: Add Micro Crystal AG vendor id
  rtc: cmos: avoid unused function warning
  rtc: ac100: Add NULL checking for devm_kzalloc call
  rtc: ds1347: changed raw spi calls to register map calls
  rtc: cmos: Restore alarm after resume
  rtc: cmos: Clear ACPI-driven alarms upon resume
  rtc: omap: Support ext_wakeup configuration
  rtc: cmos: Initialize hpet timer before irq is registered
  rtc: asm9260: rework locking
  rtc: asm9260: allow COMPILE_TEST
  rtc: constify rtc_class_ops structures
  rtc: ac100: support clock-output-names in device tree binding
  rtc: rx6110: remove owner assignment
  rtc: pic32: Delete owner assignment
  rtc: bq32k: Fix handling of oscillator failure flag
  rtc: bq32k: Use correct mask name for 'minutes' register.
  rtc: sysfs: fix a cast removing the const attribute
  Documentation: dt: Intersil isl12057 is not a trivial device
  ...
parents e5050143 1cd71376
......@@ -51,7 +51,6 @@ fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec
gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
isil,isl12057 Intersil ISL12057 I2C RTC Chip
isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
......
......@@ -11,7 +11,7 @@ Optional properties:
- trickle-diode-disable : Do not use internal trickle charger diode
Should be given if internal trickle charger diode should be disabled
Example:
ds1390: rtc@68 {
ds1390: rtc@0 {
compatible = "dallas,ds1390";
trickle-resistor-ohms = <250>;
reg = <0>;
......
Real Time Clock driver for:
- Epson RX8900
- Micro Crystal rv8803
Required properties:
- compatible: should be: "microcrystal,rv8803" or "epson,rx8900"
- reg : the I2C address of the device for I2C
Optional properties:
- epson,vdet-disable : boolean, if present will disable voltage detector.
Should be set if no backup battery is used.
- trickle-diode-disable : boolean, if present will disable internal trickle
charger diode
Example:
rtc: rtc@32 {
compatible = "epson,rx8900"
reg = <0x32>;
epson,vdet-disable;
trickle-diode-disable;
};
......@@ -18,6 +18,18 @@ Optional properties:
through pmic_power_en
- clocks: Any internal or external clocks feeding in to rtc
- clock-names: Corresponding names of the clocks
- pinctrl-0: a phandle pointing to the pin settings for the device
- pinctrl-names: should be "default"
Optional subnodes:
- generic pinctrl node
Required pinctrl subnodes properties:
- pins - Names of ext_wakeup pins to configure
Optional pinctrl subnodes properties:
- input-enable - Enables ext_wakeup
- ti,active-high - Set input active high (by default active low)
Example:
......@@ -30,4 +42,13 @@ rtc@1c23000 {
system-power-controller;
clocks = <&clk_32k_rtc>, <&clk_32768_ck>;
clock-names = "ext-clk", "int-clk";
pinctrl-0 = <&ext_wakeup>;
pinctrl-names = "default";
ext_wakeup: ext-wakeup {
pins = "ext_wakeup0";
input-enable;
ti,active-high;
};
};
......@@ -166,6 +166,7 @@ melexis Melexis N.V.
merrii Merrii Technology Co., Ltd.
micrel Micrel Inc.
microchip Microchip Technology Inc.
microcrystal Micro Crystal AG
micron Micron Technology Inc.
minix MINIX Technology Ltd.
mitsubishi Mitsubishi Electric Corporation
......
......@@ -208,14 +208,14 @@ config RTC_DRV_AS3722
will be called rtc-as3722.
config RTC_DRV_DS1307
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, ISL12057"
help
If you say yes here you get support for various compatible RTC
chips (often with battery backup) connected with I2C. This driver
should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
EPSON RX-8025 and probably other chips. In some cases the RTC
must already have been initialized (by manufacturing or a
bootloader).
EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
cases the RTC must already have been initialized (by manufacturing or
a bootloader).
The first seven registers on these chips hold an RTC, and other
registers may add features such as NVRAM, a trickle charger for
......@@ -234,6 +234,20 @@ config RTC_DRV_DS1307_HWMON
Say Y here if you want to expose temperature sensor data on
rtc-ds1307 (only DS3231)
config RTC_DRV_DS1307_CENTURY
bool "Century bit support for rtc-ds1307"
depends on RTC_DRV_DS1307
default n
help
The DS1307 driver suffered from a bug where it was enabling the
century bit inconditionnally but never used it when reading the time.
It made the driver unable to support dates beyond 2099.
Setting this option will add proper support for the century bit but if
the time was previously set using a kernel predating this option,
reading the date will return a date in the next century.
To solve that, you could boot a kernel without this option set, set
the RTC date and then boot a kernel with this option set.
config RTC_DRV_DS1374
tristate "Dallas/Maxim DS1374"
help
......@@ -374,16 +388,6 @@ config RTC_DRV_ISL12022
This driver can also be built as a module. If so, the module
will be called rtc-isl12022.
config RTC_DRV_ISL12057
select REGMAP_I2C
tristate "Intersil ISL12057"
help
If you say yes here you get support for the Intersil ISL12057
I2C RTC chip.
This driver can also be built as a module. If so, the module
will be called rtc-isl12057.
config RTC_DRV_X1205
tristate "Xicor/Intersil X1205"
help
......@@ -661,6 +665,7 @@ config RTC_DRV_DS1343
will be called rtc-ds1343.
config RTC_DRV_DS1347
select REGMAP_SPI
tristate "Dallas/Maxim DS1347"
help
If you say yes here you get support for the
......@@ -1201,7 +1206,7 @@ comment "on-CPU RTC drivers"
config RTC_DRV_ASM9260
tristate "Alphascale asm9260 RTC"
depends on MACH_ASM9260
depends on MACH_ASM9260 || COMPILE_TEST
help
If you say yes here you get support for the RTC on the
Alphascale asm9260 SoC.
......@@ -1241,6 +1246,9 @@ config RTC_DRV_IMXDI
config RTC_DRV_OMAP
tristate "TI OMAP Real Time Clock"
depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
depends on OF
depends on PINCTRL
select GENERIC_PINCONF
help
Say "yes" here to support the on chip real time clock
present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx.
......
......@@ -72,7 +72,6 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
obj-$(CONFIG_RTC_DRV_ISL12057) += rtc-isl12057.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o
......
......@@ -327,6 +327,8 @@ static int ac100_rtc_register_clks(struct ac100_rtc_dev *chip)
.flags = 0,
};
of_property_read_string_index(np, "clock-output-names",
i, &init.name);
clk->regmap = chip->regmap;
clk->offset = AC100_CLKOUT_CTRL1 + i;
clk->hw.init = &init;
......@@ -552,6 +554,9 @@ static int ac100_rtc_probe(struct platform_device *pdev)
int ret;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
platform_set_drvdata(pdev, chip);
chip->dev = &pdev->dev;
chip->regmap = ac100->regmap;
......
......@@ -112,8 +112,6 @@ struct asm9260_rtc_priv {
void __iomem *iobase;
struct rtc_device *rtc;
struct clk *clk;
/* io lock */
spinlock_t lock;
};
static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id)
......@@ -122,11 +120,15 @@ static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id)
u32 isr;
unsigned long events = 0;
mutex_lock(&priv->rtc->ops_lock);
isr = ioread32(priv->iobase + HW_CIIR);
if (!isr)
if (!isr) {
mutex_unlock(&priv->rtc->ops_lock);
return IRQ_NONE;
}
iowrite32(0, priv->iobase + HW_CIIR);
mutex_unlock(&priv->rtc->ops_lock);
events |= RTC_AF | RTC_IRQF;
......@@ -139,9 +141,7 @@ static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
u32 ctime0, ctime1, ctime2;
unsigned long irq_flags;
spin_lock_irqsave(&priv->lock, irq_flags);
ctime0 = ioread32(priv->iobase + HW_CTIME0);
ctime1 = ioread32(priv->iobase + HW_CTIME1);
ctime2 = ioread32(priv->iobase + HW_CTIME2);
......@@ -155,7 +155,6 @@ static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm)
ctime1 = ioread32(priv->iobase + HW_CTIME1);
ctime2 = ioread32(priv->iobase + HW_CTIME2);
}
spin_unlock_irqrestore(&priv->lock, irq_flags);
tm->tm_sec = (ctime0 >> BM_CTIME0_SEC_S) & BM_CTIME0_SEC_M;
tm->tm_min = (ctime0 >> BM_CTIME0_MIN_S) & BM_CTIME0_MIN_M;
......@@ -174,9 +173,7 @@ static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
unsigned long irq_flags;
spin_lock_irqsave(&priv->lock, irq_flags);
/*
* make sure SEC counter will not flip other counter on write time,
* real value will be written at the enf of sequence.
......@@ -191,7 +188,6 @@ static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm)
iowrite32(tm->tm_hour, priv->iobase + HW_HOUR);
iowrite32(tm->tm_min, priv->iobase + HW_MIN);
iowrite32(tm->tm_sec, priv->iobase + HW_SEC);
spin_unlock_irqrestore(&priv->lock, irq_flags);
return 0;
}
......@@ -199,9 +195,7 @@ static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int asm9260_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
unsigned long irq_flags;
spin_lock_irqsave(&priv->lock, irq_flags);
alrm->time.tm_year = ioread32(priv->iobase + HW_ALYEAR);
alrm->time.tm_mon = ioread32(priv->iobase + HW_ALMON);
alrm->time.tm_mday = ioread32(priv->iobase + HW_ALDOM);
......@@ -213,7 +207,6 @@ static int asm9260_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = ioread32(priv->iobase + HW_AMR) ? 1 : 0;
alrm->pending = ioread32(priv->iobase + HW_CIIR) ? 1 : 0;
spin_unlock_irqrestore(&priv->lock, irq_flags);
return rtc_valid_tm(&alrm->time);
}
......@@ -221,9 +214,7 @@ static int asm9260_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int asm9260_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
unsigned long irq_flags;
spin_lock_irqsave(&priv->lock, irq_flags);
iowrite32(alrm->time.tm_year, priv->iobase + HW_ALYEAR);
iowrite32(alrm->time.tm_mon, priv->iobase + HW_ALMON);
iowrite32(alrm->time.tm_mday, priv->iobase + HW_ALDOM);
......@@ -234,7 +225,6 @@ static int asm9260_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
iowrite32(alrm->time.tm_sec, priv->iobase + HW_ALSEC);
iowrite32(alrm->enabled ? 0 : BM_AMR_OFF, priv->iobase + HW_AMR);
spin_unlock_irqrestore(&priv->lock, irq_flags);
return 0;
}
......
......@@ -187,7 +187,7 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
return ret;
}
static struct rtc_class_ops at32_rtc_ops = {
static const struct rtc_class_ops at32_rtc_ops = {
.read_time = at32_rtc_readtime,
.set_time = at32_rtc_settime,
.read_alarm = at32_rtc_readalarm,
......
......@@ -93,8 +93,15 @@ static int bq32k_rtc_read_time(struct device *dev, struct rtc_time *tm)
if (error)
return error;
/*
* In case of oscillator failure, the register contents should be
* considered invalid. The flag is cleared the next time the RTC is set.
*/
if (regs.minutes & BQ32K_OF)
return -EINVAL;
tm->tm_sec = bcd2bin(regs.seconds & BQ32K_SECONDS_MASK);
tm->tm_min = bcd2bin(regs.minutes & BQ32K_SECONDS_MASK);
tm->tm_min = bcd2bin(regs.minutes & BQ32K_MINUTES_MASK);
tm->tm_hour = bcd2bin(regs.cent_hours & BQ32K_HOURS_MASK);
tm->tm_mday = bcd2bin(regs.date);
tm->tm_wday = bcd2bin(regs.day) - 1;
......@@ -204,13 +211,10 @@ static int bq32k_probe(struct i2c_client *client,
/* Check Oscillator Failure flag */
error = bq32k_read(dev, &reg, BQ32K_MINUTES, 1);
if (!error && (reg & BQ32K_OF)) {
dev_warn(dev, "Oscillator Failure. Check RTC battery.\n");
reg &= ~BQ32K_OF;
error = bq32k_write(dev, &reg, BQ32K_MINUTES, 1);
}
if (error)
return error;
if (reg & BQ32K_OF)
dev_warn(dev, "Oscillator Failure. Check RTC battery.\n");
if (client->dev.of_node)
trickle_charger_of_init(dev, client->dev.of_node);
......
......@@ -62,6 +62,8 @@ struct cmos_rtc {
u8 day_alrm;
u8 mon_alrm;
u8 century;
struct rtc_wkalrm saved_wkalrm;
};
/* both platform and pnp busses use negative numbers for invalid irqs */
......@@ -707,6 +709,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
goto cleanup1;
}
hpet_rtc_timer_init();
if (is_valid_irq(rtc_irq)) {
irq_handler_t rtc_cmos_int_handler;
......@@ -714,6 +718,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
rtc_cmos_int_handler = hpet_rtc_interrupt;
retval = hpet_register_irq_handler(cmos_interrupt);
if (retval) {
hpet_mask_rtc_irq_bit(RTC_IRQMASK);
dev_warn(dev, "hpet_register_irq_handler "
" failed in rtc_init().");
goto cleanup1;
......@@ -729,7 +734,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
goto cleanup1;
}
}
hpet_rtc_timer_init();
/* export at least the first block of NVRAM */
nvram.size = address_space - NVRAM_OFFSET;
......@@ -844,8 +848,6 @@ static int cmos_aie_poweroff(struct device *dev)
return retval;
}
#ifdef CONFIG_PM
static int cmos_suspend(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
......@@ -877,6 +879,8 @@ static int cmos_suspend(struct device *dev)
enable_irq_wake(cmos->irq);
}
cmos_read_alarm(dev, &cmos->saved_wkalrm);
dev_dbg(dev, "suspend%s, ctrl %02x\n",
(tmp & RTC_AIE) ? ", alarm may wake" : "",
tmp);
......@@ -892,12 +896,32 @@ static int cmos_suspend(struct device *dev)
*/
static inline int cmos_poweroff(struct device *dev)
{
if (!IS_ENABLED(CONFIG_PM))
return -ENOSYS;
return cmos_suspend(dev);
}
#ifdef CONFIG_PM_SLEEP
static void cmos_check_wkalrm(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
struct rtc_wkalrm current_alarm;
time64_t t_current_expires;
time64_t t_saved_expires;
cmos_read_alarm(dev, &current_alarm);
t_current_expires = rtc_tm_to_time64(&current_alarm.time);
t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time);
if (t_current_expires != t_saved_expires ||
cmos->saved_wkalrm.enabled != current_alarm.enabled) {
cmos_set_alarm(dev, &cmos->saved_wkalrm);
}
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control);
static int cmos_resume(struct device *dev)
static int __maybe_unused cmos_resume(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp;
......@@ -910,6 +934,9 @@ static int cmos_resume(struct device *dev)
cmos->enabled_wake = 0;
}
/* The BIOS might have changed the alarm, restore it */
cmos_check_wkalrm(dev);
spin_lock_irq(&rtc_lock);
tmp = cmos->suspend_ctrl;
cmos->suspend_ctrl = 0;
......@@ -936,6 +963,9 @@ static int cmos_resume(struct device *dev)
tmp &= ~RTC_AIE;
hpet_mask_rtc_irq_bit(RTC_AIE);
} while (mask & RTC_AIE);
if (tmp & RTC_AIE)
cmos_check_acpi_rtc_status(dev, &tmp);
}
spin_unlock_irq(&rtc_lock);
......@@ -944,16 +974,6 @@ static int cmos_resume(struct device *dev)
return 0;
}
#endif
#else
static inline int cmos_poweroff(struct device *dev)
{
return -ENOSYS;
}
#endif
static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
/*----------------------------------------------------------------*/
......@@ -973,6 +993,20 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
static u32 rtc_handler(void *context)
{
struct device *dev = context;
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char rtc_control = 0;
unsigned char rtc_intr;
spin_lock_irq(&rtc_lock);
if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL);
if (rtc_control & RTC_AIE) {
cmos_rtc.suspend_ctrl &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, rtc_intr);
}
spin_unlock_irq(&rtc_lock);
pm_wakeup_event(dev, 0);
acpi_clear_event(ACPI_EVENT_RTC);
......@@ -1039,12 +1073,39 @@ static void cmos_wake_setup(struct device *dev)
device_init_wakeup(dev, 1);
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
acpi_event_status rtc_status;
acpi_status status;
if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
return;
status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
if (ACPI_FAILURE(status)) {
dev_err(dev, "Could not get RTC status\n");
} else if (rtc_status & ACPI_EVENT_FLAG_SET) {
unsigned char mask;
*rtc_control &= ~RTC_AIE;
CMOS_WRITE(*rtc_control, RTC_CONTROL);
mask = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, mask);
}
}
#else
static void cmos_wake_setup(struct device *dev)
{
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control)
{
}
#endif
#ifdef CONFIG_PNP
......@@ -1206,9 +1267,7 @@ static struct platform_driver cmos_platform_driver = {
.shutdown = cmos_platform_shutdown,
.driver = {
.name = driver_name,
#ifdef CONFIG_PM
.pm = &cmos_pm_ops,
#endif
.of_match_table = of_match_ptr(of_cmos_match),
}
};
......
......@@ -140,7 +140,7 @@ static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
static struct rtc_class_ops coh901331_ops = {
static const struct rtc_class_ops coh901331_ops = {
.read_time = coh901331_read_time,
.set_mmss = coh901331_set_mmss,
.read_alarm = coh901331_read_alarm,
......
......@@ -469,7 +469,7 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
return 0;
}
static struct rtc_class_ops davinci_rtc_ops = {
static const struct rtc_class_ops davinci_rtc_ops = {
.ioctl = davinci_rtc_ioctl,
.read_time = davinci_rtc_read_time,
.set_time = davinci_rtc_set_time,
......
......@@ -159,7 +159,7 @@ static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
static struct rtc_class_ops dc_rtc_ops = {
static const struct rtc_class_ops dc_rtc_ops = {
.read_time = dc_rtc_read_time,
.set_mmss = dc_rtc_set_mmss,
.read_alarm = dc_rtc_read_alarm,
......
......@@ -102,7 +102,7 @@ static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time)
return rtc_valid_tm(time);
}
static struct rtc_class_ops ds1302_rtc_ops = {
static const struct rtc_class_ops ds1302_rtc_ops = {
.read_time = ds1302_rtc_get_time,
.set_time = ds1302_rtc_set_time,
};
......
......@@ -186,6 +186,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "mcp7941x", mcp794xx },
{ "pt7c4338", ds_1307 },
{ "rx8025", rx_8025 },
{ "isl12057", ds_1337 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
......@@ -382,10 +383,25 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
/* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
switch (ds1307->type) {
case ds_1337:
case ds_1339:
case ds_3231:
if (ds1307->regs[DS1307_REG_MONTH] & DS1337_BIT_CENTURY)
t->tm_year += 100;
break;
case ds_1340:
if (ds1307->regs[DS1307_REG_HOUR] & DS1340_BIT_CENTURY)
t->tm_year += 100;
break;
default:
break;
}
#endif
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"read", t->tm_sec, t->tm_min,
......@@ -409,6 +425,27 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
if (t->tm_year < 100)
return -EINVAL;
switch (ds1307->type) {
case ds_1337:
case ds_1339:
case ds_3231:
case ds_1340:
if (t->tm_year > 299)
return -EINVAL;
default:
if (t->tm_year > 199)
return -EINVAL;
break;
}
#else
if (t->tm_year < 100 || t->tm_year > 199)
return -EINVAL;
#endif
buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
......@@ -424,11 +461,13 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
case ds_1337:
case ds_1339:
case ds_3231:
buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
if (t->tm_year > 199)
buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
break;
case ds_1340:
buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
| DS1340_BIT_CENTURY;
buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN;
if (t->tm_year > 199)
buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY;
break;
case mcp794xx:
/*
......@@ -1295,6 +1334,11 @@ static int ds1307_probe(struct i2c_client *client,
if (of_property_read_bool(client->dev.of_node, "wakeup-source")) {
ds1307_can_wakeup_device = true;
}
/* Intersil ISL12057 DT backward compatibility */
if (of_property_read_bool(client->dev.of_node,
"isil,irq2-can-wakeup-machine")) {
ds1307_can_wakeup_device = true;
}
#endif
switch (ds1307->type) {
......
......@@ -18,6 +18,7 @@
#include <linux/rtc.h>
#include <linux/spi/spi.h>
#include <linux/bcd.h>
#include <linux/regmap.h>
/* Registers in ds1347 rtc */
......@@ -32,37 +33,28 @@
#define DS1347_STATUS_REG 0x17
#define DS1347_CLOCK_BURST 0x3F
static int ds1347_read_reg(struct device *dev, unsigned char address,
unsigned char *data)
{
struct spi_device *spi = to_spi_device(dev);
*data = address | 0x80;
return spi_write_then_read(spi, data, 1, data, 1);
}
static int ds1347_write_reg(struct device *dev, unsigned char address,
unsigned char data)
{
struct spi_device *spi = to_spi_device(dev);
unsigned char buf[2];
buf[0] = address & 0x7F;
buf[1] = data;
static const struct regmap_range ds1347_ranges[] = {
{
.range_min = DS1347_SECONDS_REG,
.range_max = DS1347_STATUS_REG,
},
};
return spi_write_then_read(spi, buf, 2, NULL, 0);
}
static const struct regmap_access_table ds1347_access_table = {
.yes_ranges = ds1347_ranges,
.n_yes_ranges = ARRAY_SIZE(ds1347_ranges),
};
static int ds1347_read_time(struct device *dev, struct rtc_time *dt)
{
struct spi_device *spi = to_spi_device(dev);
struct regmap *map;
int err;
unsigned char buf[8];
buf[0] = DS1347_CLOCK_BURST | 0x80;
map = spi_get_drvdata(spi);
err = spi_write_then_read(spi, buf, 1, buf, 8);
err = regmap_bulk_read(map, DS1347_CLOCK_BURST, buf, 8);
if (err)
return err;
......@@ -80,25 +72,27 @@ static int ds1347_read_time(struct device *dev, struct rtc_time *dt)
static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
{
struct spi_device *spi = to_spi_device(dev);
unsigned char buf[9];
struct regmap *map;
unsigned char buf[8];
map = spi_get_drvdata(spi);
buf[0] = DS1347_CLOCK_BURST & 0x7F;
buf[1] = bin2bcd(dt->tm_sec);
buf[2] = bin2bcd(dt->tm_min);
buf[3] = (bin2bcd(dt->tm_hour) & 0x3F);
buf[4] = bin2bcd(dt->tm_mday);
buf[5] = bin2bcd(dt->tm_mon + 1);
buf[6] = bin2bcd(dt->tm_wday + 1);
buf[0] = bin2bcd(dt->tm_sec);
buf[1] = bin2bcd(dt->tm_min);
buf[2] = (bin2bcd(dt->tm_hour) & 0x3F);
buf[3] = bin2bcd(dt->tm_mday);
buf[4] = bin2bcd(dt->tm_mon + 1);
buf[5] = bin2bcd(dt->tm_wday + 1);
/* year in linux is from 1900 i.e in range of 100
in rtc it is from 00 to 99 */
dt->tm_year = dt->tm_year % 100;
buf[7] = bin2bcd(dt->tm_year);
buf[8] = bin2bcd(0x00);
buf[6] = bin2bcd(dt->tm_year);
buf[7] = bin2bcd(0x00);
/* write the rtc settings */
return spi_write_then_read(spi, buf, 9, NULL, 0);
return regmap_bulk_write(map, DS1347_CLOCK_BURST, buf, 8);
}
static const struct rtc_class_ops ds1347_rtc_ops = {
......@@ -109,35 +103,53 @@ static const struct rtc_class_ops ds1347_rtc_ops = {
static int ds1347_probe(struct spi_device *spi)
{
struct rtc_device *rtc;
unsigned char data;
struct regmap_config config;
struct regmap *map;
unsigned int data;
int res;
memset(&config, 0, sizeof(config));
config.reg_bits = 8;
config.val_bits = 8;
config.read_flag_mask = 0x80;
config.max_register = 0x3F;
config.wr_table = &ds1347_access_table;
/* spi setup with ds1347 in mode 3 and bits per word as 8 */
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
map = devm_regmap_init_spi(spi, &config);
if (IS_ERR(map)) {
dev_err(&spi->dev, "ds1347 regmap init spi failed\n");
return PTR_ERR(map);
}
spi_set_drvdata(spi, map);
/* RTC Settings */
res = ds1347_read_reg(&spi->dev, DS1347_SECONDS_REG, &data);
res = regmap_read(map, DS1347_SECONDS_REG, &data);
if (res)
return res;
/* Disable the write protect of rtc */
ds1347_read_reg(&spi->dev, DS1347_CONTROL_REG, &data);
regmap_read(map, DS1347_CONTROL_REG, &data);
data = data & ~(1<<7);
ds1347_write_reg(&spi->dev, DS1347_CONTROL_REG, data);
regmap_write(map, DS1347_CONTROL_REG, data);
/* Enable the oscillator , disable the oscillator stop flag,
and glitch filter to reduce current consumption */
ds1347_read_reg(&spi->dev, DS1347_STATUS_REG, &data);
regmap_read(map, DS1347_STATUS_REG, &data);
data = data & 0x1B;
ds1347_write_reg(&spi->dev, DS1347_STATUS_REG, data);
regmap_write(map, DS1347_STATUS_REG, data);
/* display the settings */
ds1347_read_reg(&spi->dev, DS1347_CONTROL_REG, &data);
regmap_read(map, DS1347_CONTROL_REG, &data);
dev_info(&spi->dev, "DS1347 RTC CTRL Reg = 0x%02x\n", data);
ds1347_read_reg(&spi->dev, DS1347_STATUS_REG, &data);
regmap_read(map, DS1347_STATUS_REG, &data);
dev_info(&spi->dev, "DS1347 RTC Status Reg = 0x%02x\n", data);
rtc = devm_rtc_device_register(&spi->dev, "ds1347",
......@@ -146,8 +158,6 @@ static int ds1347_probe(struct spi_device *spi)
if (IS_ERR(rtc))
return PTR_ERR(rtc);
spi_set_drvdata(spi, rtc);
return 0;
}
......
......@@ -110,7 +110,7 @@ static int gemini_rtc_set_time(struct device *dev, struct rtc_time *tm)
return 0;
}
static struct rtc_class_ops gemini_rtc_ops = {
static const struct rtc_class_ops gemini_rtc_ops = {
.read_time = gemini_rtc_read_time,
.set_time = gemini_rtc_set_time,
};
......
/*
* rtc-isl12057 - Driver for Intersil ISL12057 I2C Real Time Clock
*
* Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
*
* This work is largely based on Intersil ISL1208 driver developed by
* Hebert Valerio Riedel <hvr@gnu.org>.
*
* Detailed datasheet on which this development is based is available here:
*
* http://natisbad.org/NAS2/refs/ISL12057.pdf
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/rtc.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#define DRV_NAME "rtc-isl12057"
/* RTC section */
#define ISL12057_REG_RTC_SC 0x00 /* Seconds */
#define ISL12057_REG_RTC_MN 0x01 /* Minutes */
#define ISL12057_REG_RTC_HR 0x02 /* Hours */
#define ISL12057_REG_RTC_HR_PM BIT(5) /* AM/PM bit in 12h format */
#define ISL12057_REG_RTC_HR_MIL BIT(6) /* 24h/12h format */
#define ISL12057_REG_RTC_DW 0x03 /* Day of the Week */
#define ISL12057_REG_RTC_DT 0x04 /* Date */
#define ISL12057_REG_RTC_MO 0x05 /* Month */
#define ISL12057_REG_RTC_MO_CEN BIT(7) /* Century bit */
#define ISL12057_REG_RTC_YR 0x06 /* Year */
#define ISL12057_RTC_SEC_LEN 7
/* Alarm 1 section */
#define ISL12057_REG_A1_SC 0x07 /* Alarm 1 Seconds */
#define ISL12057_REG_A1_MN 0x08 /* Alarm 1 Minutes */
#define ISL12057_REG_A1_HR 0x09 /* Alarm 1 Hours */
#define ISL12057_REG_A1_HR_PM BIT(5) /* AM/PM bit in 12h format */
#define ISL12057_REG_A1_HR_MIL BIT(6) /* 24h/12h format */
#define ISL12057_REG_A1_DWDT 0x0A /* Alarm 1 Date / Day of the week */
#define ISL12057_REG_A1_DWDT_B BIT(6) /* DW / DT selection bit */
#define ISL12057_A1_SEC_LEN 4
/* Alarm 2 section */
#define ISL12057_REG_A2_MN 0x0B /* Alarm 2 Minutes */
#define ISL12057_REG_A2_HR 0x0C /* Alarm 2 Hours */
#define ISL12057_REG_A2_DWDT 0x0D /* Alarm 2 Date / Day of the week */
#define ISL12057_A2_SEC_LEN 3
/* Control/Status registers */
#define ISL12057_REG_INT 0x0E
#define ISL12057_REG_INT_A1IE BIT(0) /* Alarm 1 interrupt enable bit */
#define ISL12057_REG_INT_A2IE BIT(1) /* Alarm 2 interrupt enable bit */
#define ISL12057_REG_INT_INTCN BIT(2) /* Interrupt control enable bit */
#define ISL12057_REG_INT_RS1 BIT(3) /* Freq out control bit 1 */
#define ISL12057_REG_INT_RS2 BIT(4) /* Freq out control bit 2 */
#define ISL12057_REG_INT_EOSC BIT(7) /* Oscillator enable bit */
#define ISL12057_REG_SR 0x0F
#define ISL12057_REG_SR_A1F BIT(0) /* Alarm 1 interrupt bit */
#define ISL12057_REG_SR_A2F BIT(1) /* Alarm 2 interrupt bit */
#define ISL12057_REG_SR_OSF BIT(7) /* Oscillator failure bit */
/* Register memory map length */
#define ISL12057_MEM_MAP_LEN 0x10
struct isl12057_rtc_data {
struct rtc_device *rtc;
struct regmap *regmap;
struct mutex lock;
int irq;
};
static void isl12057_rtc_regs_to_tm(struct rtc_time *tm, u8 *regs)
{
tm->tm_sec = bcd2bin(regs[ISL12057_REG_RTC_SC]);
tm->tm_min = bcd2bin(regs[ISL12057_REG_RTC_MN]);
if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_MIL) { /* AM/PM */
tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x1f);
if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_PM)
tm->tm_hour += 12;
} else { /* 24 hour mode */
tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x3f);
}
tm->tm_mday = bcd2bin(regs[ISL12057_REG_RTC_DT]);
tm->tm_wday = bcd2bin(regs[ISL12057_REG_RTC_DW]) - 1; /* starts at 1 */
tm->tm_mon = bcd2bin(regs[ISL12057_REG_RTC_MO] & 0x1f) - 1; /* ditto */
tm->tm_year = bcd2bin(regs[ISL12057_REG_RTC_YR]) + 100;
/* Check if years register has overflown from 99 to 00 */
if (regs[ISL12057_REG_RTC_MO] & ISL12057_REG_RTC_MO_CEN)
tm->tm_year += 100;
}
static int isl12057_rtc_tm_to_regs(u8 *regs, struct rtc_time *tm)
{
u8 century_bit;
/*
* The clock has an 8 bit wide bcd-coded register for the year.
* It also has a century bit encoded in MO flag which provides
* information about overflow of year register from 99 to 00.
* tm_year is an offset from 1900 and we are interested in the
* 2000-2199 range, so any value less than 100 or larger than
* 299 is invalid.
*/
if (tm->tm_year < 100 || tm->tm_year > 299)
return -EINVAL;
century_bit = (tm->tm_year > 199) ? ISL12057_REG_RTC_MO_CEN : 0;
regs[ISL12057_REG_RTC_SC] = bin2bcd(tm->tm_sec);
regs[ISL12057_REG_RTC_MN] = bin2bcd(tm->tm_min);
regs[ISL12057_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */
regs[ISL12057_REG_RTC_DT] = bin2bcd(tm->tm_mday);
regs[ISL12057_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1) | century_bit;
regs[ISL12057_REG_RTC_YR] = bin2bcd(tm->tm_year % 100);
regs[ISL12057_REG_RTC_DW] = bin2bcd(tm->tm_wday + 1);
return 0;
}
/*
* Try and match register bits w/ fixed null values to see whether we
* are dealing with an ISL12057. Note: this function is called early
* during init and hence does need mutex protection.
*/
static int isl12057_i2c_validate_chip(struct regmap *regmap)
{
u8 regs[ISL12057_MEM_MAP_LEN];
static const u8 mask[ISL12057_MEM_MAP_LEN] = { 0x80, 0x80, 0x80, 0xf8,
0xc0, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x60, 0x7c };
int ret, i;
ret = regmap_bulk_read(regmap, 0, regs, ISL12057_MEM_MAP_LEN);
if (ret)
return ret;
for (i = 0; i < ISL12057_MEM_MAP_LEN; ++i) {
if (regs[i] & mask[i]) /* check if bits are cleared */
return -ENODEV;
}
return 0;
}
static int _isl12057_rtc_clear_alarm(struct device *dev)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
int ret;
ret = regmap_update_bits(data->regmap, ISL12057_REG_SR,
ISL12057_REG_SR_A1F, 0);
if (ret)
dev_err(dev, "%s: clearing alarm failed (%d)\n", __func__, ret);
return ret;
}
static int _isl12057_rtc_update_alarm(struct device *dev, int enable)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
int ret;
ret = regmap_update_bits(data->regmap, ISL12057_REG_INT,
ISL12057_REG_INT_A1IE,
enable ? ISL12057_REG_INT_A1IE : 0);
if (ret)
dev_err(dev, "%s: changing alarm interrupt flag failed (%d)\n",
__func__, ret);
return ret;
}
/*
* Note: as we only read from device and do not perform any update, there is
* no need for an equivalent function which would try and get driver's main
* lock. Here, it is safe for everyone if we just use regmap internal lock
* on the device when reading.
*/
static int _isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
u8 regs[ISL12057_RTC_SEC_LEN];
unsigned int sr;
int ret;
ret = regmap_read(data->regmap, ISL12057_REG_SR, &sr);
if (ret) {
dev_err(dev, "%s: unable to read oscillator status flag (%d)\n",
__func__, ret);
goto out;
} else {
if (sr & ISL12057_REG_SR_OSF) {
ret = -ENODATA;
goto out;
}
}
ret = regmap_bulk_read(data->regmap, ISL12057_REG_RTC_SC, regs,
ISL12057_RTC_SEC_LEN);
if (ret)
dev_err(dev, "%s: unable to read RTC time section (%d)\n",
__func__, ret);
out:
if (ret)
return ret;
isl12057_rtc_regs_to_tm(tm, regs);
return rtc_valid_tm(tm);
}
static int isl12057_rtc_update_alarm(struct device *dev, int enable)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
int ret;
mutex_lock(&data->lock);
ret = _isl12057_rtc_update_alarm(dev, enable);
mutex_unlock(&data->lock);
return ret;
}
static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
struct rtc_time *alarm_tm = &alarm->time;
u8 regs[ISL12057_A1_SEC_LEN];
unsigned int ir;
int ret;
mutex_lock(&data->lock);
ret = regmap_bulk_read(data->regmap, ISL12057_REG_A1_SC, regs,
ISL12057_A1_SEC_LEN);
if (ret) {
dev_err(dev, "%s: reading alarm section failed (%d)\n",
__func__, ret);
goto err_unlock;
}
alarm_tm->tm_sec = bcd2bin(regs[0] & 0x7f);
alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f);
alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f);
alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f);
ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir);
if (ret) {
dev_err(dev, "%s: reading alarm interrupt flag failed (%d)\n",
__func__, ret);
goto err_unlock;
}
alarm->enabled = !!(ir & ISL12057_REG_INT_A1IE);
err_unlock:
mutex_unlock(&data->lock);
return ret;
}
static int isl12057_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
struct rtc_time *alarm_tm = &alarm->time;
unsigned long rtc_secs, alarm_secs;
u8 regs[ISL12057_A1_SEC_LEN];
struct rtc_time rtc_tm;
int ret, enable = 1;
mutex_lock(&data->lock);
ret = _isl12057_rtc_read_time(dev, &rtc_tm);
if (ret)
goto err_unlock;
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 time is before current time, disable the alarm */
if (!alarm->enabled || alarm_secs <= rtc_secs) {
enable = 0;
} else {
/*
* Chip only support alarms up to one month in the future. Let's
* return an error if we get something after that limit.
* Comparison is done by incrementing rtc_tm month field by one
* and checking alarm value is still below.
*/
if (rtc_tm.tm_mon == 11) { /* handle year wrapping */
rtc_tm.tm_mon = 0;
rtc_tm.tm_year += 1;
} else {
rtc_tm.tm_mon += 1;
}
ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
if (ret)
goto err_unlock;
if (alarm_secs > rtc_secs) {
dev_err(dev, "%s: max for alarm is one month (%d)\n",
__func__, ret);
ret = -EINVAL;
goto err_unlock;
}
}
/* Disable the alarm before modifying it */
ret = _isl12057_rtc_update_alarm(dev, 0);
if (ret < 0) {
dev_err(dev, "%s: unable to disable the alarm (%d)\n",
__func__, ret);
goto err_unlock;
}
/* Program alarm registers */
regs[0] = bin2bcd(alarm_tm->tm_sec) & 0x7f;
regs[1] = bin2bcd(alarm_tm->tm_min) & 0x7f;
regs[2] = bin2bcd(alarm_tm->tm_hour) & 0x3f;
regs[3] = bin2bcd(alarm_tm->tm_mday) & 0x3f;
ret = regmap_bulk_write(data->regmap, ISL12057_REG_A1_SC, regs,
ISL12057_A1_SEC_LEN);
if (ret < 0) {
dev_err(dev, "%s: writing alarm section failed (%d)\n",
__func__, ret);
goto err_unlock;
}
/* Enable or disable alarm */
ret = _isl12057_rtc_update_alarm(dev, enable);
err_unlock:
mutex_unlock(&data->lock);
return ret;
}
static int isl12057_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
u8 regs[ISL12057_RTC_SEC_LEN];
int ret;
ret = isl12057_rtc_tm_to_regs(regs, tm);
if (ret)
return ret;
mutex_lock(&data->lock);
ret = regmap_bulk_write(data->regmap, ISL12057_REG_RTC_SC, regs,
ISL12057_RTC_SEC_LEN);
if (ret) {
dev_err(dev, "%s: unable to write RTC time section (%d)\n",
__func__, ret);
goto out;
}
/*
* Now that RTC time has been updated, let's clear oscillator
* failure flag, if needed.
*/
ret = regmap_update_bits(data->regmap, ISL12057_REG_SR,
ISL12057_REG_SR_OSF, 0);
if (ret < 0)
dev_err(dev, "%s: unable to clear osc. failure bit (%d)\n",
__func__, ret);
out:
mutex_unlock(&data->lock);
return ret;
}
/*
* Check current RTC status and enable/disable what needs to be. Return 0 if
* everything went ok and a negative value upon error. Note: this function
* is called early during init and hence does need mutex protection.
*/
static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)
{
int ret;
/* Enable oscillator if not already running */
ret = regmap_update_bits(regmap, ISL12057_REG_INT,
ISL12057_REG_INT_EOSC, 0);
if (ret < 0) {
dev_err(dev, "%s: unable to enable oscillator (%d)\n",
__func__, ret);
return ret;
}
/* Clear alarm bit if needed */
ret = regmap_update_bits(regmap, ISL12057_REG_SR,
ISL12057_REG_SR_A1F, 0);
if (ret < 0) {
dev_err(dev, "%s: unable to clear alarm bit (%d)\n",
__func__, ret);
return ret;
}
return 0;
}
#ifdef CONFIG_OF
/*
* One would expect the device to be marked as a wakeup source only
* when an IRQ pin of the RTC is routed to an interrupt line of the
* CPU. In practice, such an IRQ pin can be connected to a PMIC and
* this allows the device to be powered up when RTC alarm rings. This
* is for instance the case on ReadyNAS 102, 104 and 2120. On those
* devices with no IRQ driectly connected to the SoC, the RTC chip
* can be forced as a wakeup source by stating that explicitly in
* the device's .dts file using the "wakeup-source" boolean property.
* This will guarantee 'wakealarm' sysfs entry is available on the device.
*
* The function below returns 1, i.e. the capability of the chip to
* wakeup the device, based on IRQ availability or if the boolean
* property has been set in the .dts file. Otherwise, it returns 0.
*/
static bool isl12057_can_wakeup_machine(struct device *dev)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
return data->irq || of_property_read_bool(dev->of_node, "wakeup-source")
|| of_property_read_bool(dev->of_node, /* legacy */
"isil,irq2-can-wakeup-machine");
}
#else
static bool isl12057_can_wakeup_machine(struct device *dev)
{
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
return !!data->irq;
}
#endif
static int isl12057_rtc_alarm_irq_enable(struct device *dev,
unsigned int enable)
{
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
int ret = -ENOTTY;
if (rtc_data->irq)
ret = isl12057_rtc_update_alarm(dev, enable);
return ret;
}
static irqreturn_t isl12057_rtc_interrupt(int irq, void *data)
{
struct i2c_client *client = data;
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(&client->dev);
struct rtc_device *rtc = rtc_data->rtc;
int ret, handled = IRQ_NONE;
unsigned int sr;
ret = regmap_read(rtc_data->regmap, ISL12057_REG_SR, &sr);
if (!ret && (sr & ISL12057_REG_SR_A1F)) {
dev_dbg(&client->dev, "RTC alarm!\n");
rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
/* Acknowledge and disable the alarm */
_isl12057_rtc_clear_alarm(&client->dev);
_isl12057_rtc_update_alarm(&client->dev, 0);
handled = IRQ_HANDLED;
}
return handled;
}
static const struct rtc_class_ops rtc_ops = {
.read_time = _isl12057_rtc_read_time,
.set_time = isl12057_rtc_set_time,
.read_alarm = isl12057_rtc_read_alarm,
.set_alarm = isl12057_rtc_set_alarm,
.alarm_irq_enable = isl12057_rtc_alarm_irq_enable,
};
static const struct regmap_config isl12057_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int isl12057_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct isl12057_rtc_data *data;
struct regmap *regmap;
int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENODEV;
regmap = devm_regmap_init_i2c(client, &isl12057_rtc_regmap_config);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(dev, "%s: regmap allocation failed (%d)\n",
__func__, ret);
return ret;
}
ret = isl12057_i2c_validate_chip(regmap);
if (ret)
return ret;
ret = isl12057_check_rtc_status(dev, regmap);
if (ret)
return ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
mutex_init(&data->lock);
data->regmap = regmap;
dev_set_drvdata(dev, data);
if (client->irq > 0) {
ret = devm_request_threaded_irq(dev, client->irq, NULL,
isl12057_rtc_interrupt,
IRQF_SHARED|IRQF_ONESHOT,
DRV_NAME, client);
if (!ret)
data->irq = client->irq;
else
dev_err(dev, "%s: irq %d unavailable (%d)\n", __func__,
client->irq, ret);
}
if (isl12057_can_wakeup_machine(dev))
device_init_wakeup(dev, true);
data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops,
THIS_MODULE);
ret = PTR_ERR_OR_ZERO(data->rtc);
if (ret) {
dev_err(dev, "%s: unable to register RTC device (%d)\n",
__func__, ret);
goto err;
}
/* We cannot support UIE mode if we do not have an IRQ line */
if (!data->irq)
data->rtc->uie_unsupported = 1;
err:
return ret;
}
static int isl12057_remove(struct i2c_client *client)
{
if (isl12057_can_wakeup_machine(&client->dev))
device_init_wakeup(&client->dev, false);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int isl12057_rtc_suspend(struct device *dev)
{
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
if (rtc_data->irq && device_may_wakeup(dev))
return enable_irq_wake(rtc_data->irq);
return 0;
}
static int isl12057_rtc_resume(struct device *dev)
{
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
if (rtc_data->irq && device_may_wakeup(dev))
return disable_irq_wake(rtc_data->irq);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(isl12057_rtc_pm_ops, isl12057_rtc_suspend,
isl12057_rtc_resume);
#ifdef CONFIG_OF
static const struct of_device_id isl12057_dt_match[] = {
{ .compatible = "isl,isl12057" }, /* for backward compat., don't use */
{ .compatible = "isil,isl12057" },
{ },
};
MODULE_DEVICE_TABLE(of, isl12057_dt_match);
#endif
static const struct i2c_device_id isl12057_id[] = {
{ "isl12057", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl12057_id);
static struct i2c_driver isl12057_driver = {
.driver = {
.name = DRV_NAME,
.pm = &isl12057_rtc_pm_ops,
.of_match_table = of_match_ptr(isl12057_dt_match),
},
.probe = isl12057_probe,
.remove = isl12057_remove,
.id_table = isl12057_id,
};
module_i2c_driver(isl12057_driver);
MODULE_AUTHOR("Arnaud EBALARD <arno@natisbad.org>");
MODULE_DESCRIPTION("Intersil ISL12057 RTC driver");
MODULE_LICENSE("GPL");
......@@ -174,7 +174,7 @@ static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable);
}
static struct rtc_class_ops jz4740_rtc_ops = {
static const struct rtc_class_ops jz4740_rtc_ops = {
.read_time = jz4740_rtc_read_time,
.set_mmss = jz4740_rtc_set_mmss,
.read_alarm = jz4740_rtc_read_alarm,
......
......@@ -151,7 +151,7 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
return rtc_valid_tm(tim);
}
static struct rtc_class_ops mcp795_rtc_ops = {
static const struct rtc_class_ops mcp795_rtc_ops = {
.read_time = mcp795_read_time,
.set_time = mcp795_set_time
};
......
......@@ -301,7 +301,7 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
return ret;
}
static struct rtc_class_ops mtk_rtc_ops = {
static const struct rtc_class_ops mtk_rtc_ops = {
.read_time = mtk_rtc_read_time,
.set_time = mtk_rtc_set_time,
.read_alarm = mtk_rtc_read_alarm,
......
......@@ -214,7 +214,7 @@ static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return 0;
}
static struct rtc_class_ops nuc900_rtc_ops = {
static const struct rtc_class_ops nuc900_rtc_ops = {
.read_time = nuc900_rtc_read_time,
.set_time = nuc900_rtc_set_time,
.read_alarm = nuc900_rtc_read_alarm,
......
......@@ -13,19 +13,23 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
#include <dt-bindings/gpio/gpio.h>
#include <linux/bcd.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/rtc.h>
/*
* The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
......@@ -115,6 +119,8 @@
/* OMAP_RTC_PMIC bit fields: */
#define OMAP_RTC_PMIC_POWER_EN_EN BIT(16)
#define OMAP_RTC_PMIC_EXT_WKUP_EN(x) BIT(x)
#define OMAP_RTC_PMIC_EXT_WKUP_POL(x) BIT(4 + x)
/* OMAP_RTC_KICKER values */
#define KICK0_VALUE 0x83e70b13
......@@ -141,6 +147,7 @@ struct omap_rtc {
bool is_pmic_controller;
bool has_ext_clk;
const struct omap_rtc_device_type *type;
struct pinctrl_dev *pctldev;
};
static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg)
......@@ -469,7 +476,7 @@ static void omap_rtc_power_off(void)
mdelay(2500);
}
static struct rtc_class_ops omap_rtc_ops = {
static const struct rtc_class_ops omap_rtc_ops = {
.read_time = omap_rtc_read_time,
.set_time = omap_rtc_set_time,
.read_alarm = omap_rtc_read_alarm,
......@@ -525,6 +532,139 @@ static const struct of_device_id omap_rtc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
static const struct pinctrl_pin_desc rtc_pins_desc[] = {
PINCTRL_PIN(0, "ext_wakeup0"),
PINCTRL_PIN(1, "ext_wakeup1"),
PINCTRL_PIN(2, "ext_wakeup2"),
PINCTRL_PIN(3, "ext_wakeup3"),
};
static int rtc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
return 0;
}
static const char *rtc_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
return NULL;
}
static const struct pinctrl_ops rtc_pinctrl_ops = {
.get_groups_count = rtc_pinctrl_get_groups_count,
.get_group_name = rtc_pinctrl_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_free_map = pinconf_generic_dt_free_map,
};
enum rtc_pin_config_param {
PIN_CONFIG_ACTIVE_HIGH = PIN_CONFIG_END + 1,
};
static const struct pinconf_generic_params rtc_params[] = {
{"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
};
#ifdef CONFIG_DEBUG_FS
static const struct pin_config_item rtc_conf_items[ARRAY_SIZE(rtc_params)] = {
PCONFDUMP(PIN_CONFIG_ACTIVE_HIGH, "input active high", NULL, false),
};
#endif
static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
unsigned int param = pinconf_to_config_param(*config);
u32 val;
u16 arg = 0;
rtc->type->unlock(rtc);
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc->type->lock(rtc);
switch (param) {
case PIN_CONFIG_INPUT_ENABLE:
if (!(val & OMAP_RTC_PMIC_EXT_WKUP_EN(pin)))
return -EINVAL;
break;
case PIN_CONFIG_ACTIVE_HIGH:
if (val & OMAP_RTC_PMIC_EXT_WKUP_POL(pin))
return -EINVAL;
break;
default:
return -ENOTSUPP;
};
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int rtc_pinconf_set(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *configs,
unsigned int num_configs)
{
struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
u32 val;
unsigned int param;
u16 param_val;
int i;
rtc->type->unlock(rtc);
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc->type->lock(rtc);
/* active low by default */
val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
param_val = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_INPUT_ENABLE:
if (param_val)
val |= OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
else
val &= ~OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
break;
case PIN_CONFIG_ACTIVE_HIGH:
val &= ~OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
break;
default:
dev_err(&rtc->rtc->dev, "Property %u not supported\n",
param);
return -ENOTSUPP;
}
}
rtc->type->unlock(rtc);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val);
rtc->type->lock(rtc);
return 0;
}
static const struct pinconf_ops rtc_pinconf_ops = {
.is_generic = true,
.pin_config_get = rtc_pinconf_get,
.pin_config_set = rtc_pinconf_set,
};
static struct pinctrl_desc rtc_pinctrl_desc = {
.pins = rtc_pins_desc,
.npins = ARRAY_SIZE(rtc_pins_desc),
.pctlops = &rtc_pinctrl_ops,
.confops = &rtc_pinconf_ops,
.custom_params = rtc_params,
.num_custom_params = ARRAY_SIZE(rtc_params),
#ifdef CONFIG_DEBUG_FS
.custom_conf_items = rtc_conf_items,
#endif
.owner = THIS_MODULE,
};
static int omap_rtc_probe(struct platform_device *pdev)
{
struct omap_rtc *rtc;
......@@ -681,6 +821,15 @@ static int omap_rtc_probe(struct platform_device *pdev)
}
}
/* Support ext_wakeup pinconf */
rtc_pinctrl_desc.name = dev_name(&pdev->dev);
rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc);
if (IS_ERR(rtc->pctldev)) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
return PTR_ERR(rtc->pctldev);
}
return 0;
err:
......@@ -724,6 +873,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
/* Remove ext_wakeup pinconf */
pinctrl_unregister(rtc->pctldev);
return 0;
}
......
......@@ -225,7 +225,7 @@ static irqreturn_t palmas_rtc_interrupt(int irq, void *context)
return IRQ_HANDLED;
}
static struct rtc_class_ops palmas_rtc_ops = {
static const struct rtc_class_ops palmas_rtc_ops = {
.read_time = palmas_rtc_read_time,
.set_time = palmas_rtc_set_time,
.read_alarm = palmas_rtc_read_alarm,
......
......@@ -182,7 +182,8 @@ static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr,
}
static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
const char *buffer, size_t count) {
const char *buffer, size_t count)
{
struct pcf2123_sysfs_reg *r;
unsigned long reg;
unsigned long val;
......@@ -199,7 +200,7 @@ static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
pcf2123_write_reg(dev, reg, val);
ret = pcf2123_write_reg(dev, reg, val);
if (ret < 0)
return -EIO;
return count;
......
......@@ -232,7 +232,7 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
static struct rtc_class_ops pcf50633_rtc_ops = {
static const struct rtc_class_ops pcf50633_rtc_ops = {
.read_time = pcf50633_rtc_read_time,
.set_time = pcf50633_rtc_set_time,
.read_alarm = pcf50633_rtc_read_alarm,
......
......@@ -400,7 +400,6 @@ static struct platform_driver pic32_rtc_driver = {
.remove = pic32_rtc_remove,
.driver = {
.name = "pic32-rtc",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(pic32_rtc_dt_ids),
},
};
......
......@@ -52,11 +52,21 @@
#define RV8803_CTRL_TIE BIT(4)
#define RV8803_CTRL_UIE BIT(5)
#define RX8900_BACKUP_CTRL 0x18
#define RX8900_FLAG_SWOFF BIT(2)
#define RX8900_FLAG_VDETOFF BIT(3)
enum rv8803_type {
rv_8803,
rx_8900
};
struct rv8803_data {
struct i2c_client *client;
struct rtc_device *rtc;
struct mutex flags_lock;
u8 ctrl;
enum rv8803_type type;
};
static int rv8803_read_reg(const struct i2c_client *client, u8 reg)
......@@ -497,6 +507,35 @@ static struct rtc_class_ops rv8803_rtc_ops = {
.ioctl = rv8803_ioctl,
};
static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
{
struct i2c_client *client = rv8803->client;
struct device_node *node = client->dev.of_node;
int err;
u8 flags;
if (!node)
return 0;
if (rv8803->type != rx_8900)
return 0;
err = i2c_smbus_read_byte_data(rv8803->client, RX8900_BACKUP_CTRL);
if (err < 0)
return err;
flags = ~(RX8900_FLAG_VDETOFF | RX8900_FLAG_SWOFF) & (u8)err;
if (of_property_read_bool(node, "epson,vdet-disable"))
flags |= RX8900_FLAG_VDETOFF;
if (of_property_read_bool(node, "trickle-diode-disable"))
flags |= RX8900_FLAG_SWOFF;
return i2c_smbus_write_byte_data(rv8803->client, RX8900_BACKUP_CTRL,
flags);
}
static int rv8803_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -517,6 +556,7 @@ static int rv8803_probe(struct i2c_client *client,
mutex_init(&rv8803->flags_lock);
rv8803->client = client;
rv8803->type = id->driver_data;
i2c_set_clientdata(client, rv8803);
flags = rv8803_read_reg(client, RV8803_FLAG);
......@@ -558,6 +598,12 @@ static int rv8803_probe(struct i2c_client *client,
if (err)
return err;
err = rx8900_trickle_charger_init(rv8803);
if (err) {
dev_err(&client->dev, "failed to init charger\n");
return err;
}
err = device_create_bin_file(&client->dev, &rv8803_nvram_attr);
if (err)
return err;
......@@ -575,8 +621,8 @@ static int rv8803_remove(struct i2c_client *client)
}
static const struct i2c_device_id rv8803_id[] = {
{ "rv8803", 0 },
{ "rx8900", 0 },
{ "rv8803", rv_8803 },
{ "rx8900", rx_8900 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rv8803_id);
......
......@@ -317,7 +317,7 @@ static int rx6110_init(struct rx6110_data *rx6110)
return ret;
}
static struct rtc_class_ops rx6110_rtc_ops = {
static const struct rtc_class_ops rx6110_rtc_ops = {
.read_time = rx6110_get_time,
.set_time = rx6110_set_time,
};
......@@ -388,7 +388,6 @@ MODULE_DEVICE_TABLE(spi, rx6110_id);
static struct spi_driver rx6110_driver = {
.driver = {
.name = RX6110_DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = rx6110_probe,
.remove = rx6110_remove,
......
......@@ -403,7 +403,7 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
static struct rtc_class_ops rx8025_rtc_ops = {
static const struct rtc_class_ops rx8025_rtc_ops = {
.read_time = rx8025_get_time,
.set_time = rx8025_set_time,
.read_alarm = rx8025_read_alarm,
......
......@@ -343,7 +343,7 @@ static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled)
return ret;
}
static struct rtc_class_ops spear_rtc_ops = {
static const struct rtc_class_ops spear_rtc_ops = {
.read_time = spear_rtc_read_time,
.set_time = spear_rtc_set_time,
.read_alarm = spear_rtc_read_alarm,
......
......@@ -231,7 +231,7 @@ static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
return 0;
}
static struct rtc_class_ops stmp3xxx_rtc_ops = {
static const struct rtc_class_ops stmp3xxx_rtc_ops = {
.alarm_irq_enable =
stmp3xxx_alarm_irq_enable,
.read_time = stmp3xxx_rtc_gettime,
......
......@@ -160,7 +160,7 @@ wakealarm_store(struct device *dev, struct device_attribute *attr,
unsigned long push = 0;
struct rtc_wkalrm alm;
struct rtc_device *rtc = to_rtc_device(dev);
char *buf_ptr;
const char *buf_ptr;
int adjust = 0;
/* Only request alarms that trigger in the future. Disable them
......@@ -171,7 +171,7 @@ wakealarm_store(struct device *dev, struct device_attribute *attr,
return retval;
rtc_tm_to_time(&alm.time, &now);
buf_ptr = (char *)buf;
buf_ptr = buf;
if (*buf_ptr == '+') {
buf_ptr++;
if (*buf_ptr == '=') {
......
......@@ -291,7 +291,7 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
static struct rtc_class_ops tegra_rtc_ops = {
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,
......
......@@ -462,7 +462,7 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
return ret;
}
static struct rtc_class_ops twl_rtc_ops = {
static const struct rtc_class_ops twl_rtc_ops = {
.read_time = twl_rtc_read_time,
.set_time = twl_rtc_set_time,
.read_alarm = twl_rtc_read_alarm,
......
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