1
0
Fork 0

RTC for 4.20

Subsystem:
  - non devm managed registration is now removed from the driver API.
  - all the unnecessary rtc_valid_tm() calls have been removed
 
 Drivers:
  - abx80X: watchdog support
  - cmos: fix non ACPI support
  - sc27xx: fix alarm support
  - Remove a possible sysfs race condition for ab8500, ds1307, ds1685, isl1208
  - Fix a possible race condition where an irq handler may be called before the
    rtc_device struct is allocated for mt6397, pl030, menelaus, armada38x
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEXx9Viay1+e7J/aM4AyWl4gNJNJIFAlvTekMACgkQAyWl4gNJ
 NJIJaA/+ONa/L5xvbMXRAAx164WX1f/8kZUZzku5rDAdnwrfj/4N13LRj3rtQlpD
 0tv7/JZW3f1P8Ccfd3AkIZa1t7i3ruFpsCvQ9ModzB+gAR9n9ic+k8ugExEXXi4d
 wrVwEiPHgoYyX/GwGKLUrbTJTqOBcp3PeSW5jK2WhKdnCnYVOQNL38MVmBxSCZ/m
 3p+lOBsR4ND2bIf3QjJpck6K+6thaX0JQUIuM14oK2rmNA5dfrhaUw2benlBG/dv
 Cd/H7TO5qRuUaY+HwwUB/M78wYhaLyVjPU0JbfHwVf04dZFyWQYuZxVZJh9boowO
 XwkwKBPgti43Opa9i6VIcOR6j2/ym2U8JJcU5eL4scFxjwoTUbbE2WAvNJ9/sF5J
 z434yfn9Iy0dVEmp/K5Dl0YQAhNHVQChi0RsQ0UnqxDzuxEU8J26JQvp8MHNKYsp
 FxeyCDjEMf8u+xqQpCQ24chzyIKUGSyFurYGVDhDOW2/Rh08Z17GMhiLfOO73pFU
 B9GAaEpsJwfZbmtlqJAm3lE521kCo4JBoVM7tY+75p3b9epPW5L6tGQIDdj6Q2A7
 VJkCo+O/2cVO3NRXWopTe6/vMm8mvJALvaQVccrLqx/oBpN6GBDFPXfz4a6AB+GF
 o2XBNEkUOrEAkSONfGKEKAkKU//tIssr9Yx6XmpjFOcrZxgfAL0=
 =5JM5
 -----END PGP SIGNATURE-----

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

Pull RTC updates from Alexandre Belloni:
 "This cycle, there were mostly non urgent fixes in drivers. I also
  finally unexported the non managed registration.

  Subsystem:

   - non devm managed registration is now removed from the driver API

   - all the unnecessary rtc_valid_tm() calls have been removed

  Drivers:

   - abx80X: watchdog support

   - cmos: fix non ACPI support

   - sc27xx: fix alarm support

   - Remove a possible sysfs race condition for ab8500, ds1307, ds1685,
     isl1208

   - Fix a possible race condition where an irq handler may be called
     before the rtc_device struct is allocated for mt6397, pl030,
     menelaus, armada38x"

* tag 'rtc-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (54 commits)
  rtc: sc27xx: Always read normal alarm when registering RTC device
  rtc: sc27xx: Add check to see if need to enable the alarm interrupt
  rtc: sc27xx: Remove interrupts disable and clear in probe()
  rtc: sc27xx: Clear SPG value update interrupt status
  rtc: sc27xx: Set wakeup capability before registering rtc device
  rtc: s35390a: Change buf's type to u8 in s35390a_init
  rtc: ds1307: fix ds1339 wakealarm support
  rtc: ds1685: simplify getting .driver_data
  rtc: m41t80: mark expected switch fall-through
  rtc: tegra: Propagate errors from platform_get_irq()
  rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI
  rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt'
  rtc: mv: let the core handle invalid alarms
  rtc: vr41xx: switch to rtc_time64_to_tm/rtc_tm_to_time64
  rtc: ab8500: remove useless check
  rtc: ab8500: let the core handle range
  rtc: ab8500: use rtc_add_group
  rtc: rs5c348: report error when time is invalid
  rtc: rs5c348: remove forward declaration
  rtc: rs5c348: remove useless label
  ...
hifive-unleashed-5.1
Linus Torvalds 2018-10-27 09:24:24 -07:00
commit c7b7eefa57
33 changed files with 547 additions and 482 deletions

View File

@ -75,7 +75,7 @@ config MIPS
select MODULES_USE_ELF_RELA if MODULES && 64BIT
select MODULES_USE_ELF_REL if MODULES
select PERF_USE_VMALLOC
select RTC_LIB if !MACH_LOONGSON64
select RTC_LIB
select SYSCTL_EXCEPTION_TRACE
select VIRT_TO_BUS
select NO_BOOTMEM

View File

@ -268,7 +268,7 @@ if RTC_LIB=n
config RTC
tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)"
depends on ALPHA || (MIPS && MACH_LOONGSON64)
depends on ALPHA
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you

View File

@ -187,6 +187,7 @@ config RTC_DRV_ABB5ZES3
config RTC_DRV_ABX80X
tristate "Abracon ABx80x"
select WATCHDOG_CORE if WATCHDOG
help
If you say yes here you get support for Abracon AB080X and AB180X
families of ultra-low-power battery- and capacitor-backed real-time
@ -1007,17 +1008,6 @@ config RTC_DRV_DS17885
endchoice
config RTC_DS1685_PROC_REGS
bool "Display register values in /proc"
depends on RTC_DRV_DS1685_FAMILY && PROC_FS
help
Enable this to display a readout of all of the RTC registers in
/proc/drivers/rtc. Keep in mind that this can potentially lead
to lost interrupts, as reading Control Register C will clear
all pending IRQ flags.
Unless you are debugging this driver, choose N.
config RTC_DRV_DS1742
tristate "Maxim/Dallas DS1742/1743"
depends on HAS_IOMEM
@ -1587,7 +1577,7 @@ config RTC_DRV_MPC5121
config RTC_DRV_JZ4740
tristate "Ingenic JZ4740 SoC"
depends on MACH_INGENIC || COMPILE_TEST
depends on MIPS || COMPILE_TEST
help
If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
controllers.

View File

@ -36,9 +36,9 @@ obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o
obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o
obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o
@ -71,6 +71,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
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
@ -78,10 +79,10 @@ obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o
obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o
obj-$(CONFIG_RTC_DRV_LPC24XX) += rtc-lpc24xx.o
obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o
obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o
obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o
obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
@ -100,7 +101,6 @@ obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o
obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o
obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o
obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o
obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o
@ -116,8 +116,8 @@ obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PIC32) += rtc-pic32.o
@ -154,9 +154,9 @@ obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o
obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
obj-$(CONFIG_RTC_DRV_SUN6I) += rtc-sun6i.o
obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o
@ -169,10 +169,10 @@ obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o
obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o
obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o
obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o

View File

@ -286,9 +286,10 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
*
* Returns the pointer to the new struct class device.
*/
struct rtc_device *rtc_device_register(const char *name, struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner)
static struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner)
{
struct rtc_device *rtc;
struct rtc_wkalrm alrm;
@ -351,15 +352,13 @@ exit:
name, err);
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(rtc_device_register);
/**
* rtc_device_unregister - removes the previously registered RTC class device
*
* @rtc: the RTC class device to destroy
*/
void rtc_device_unregister(struct rtc_device *rtc)
static void rtc_device_unregister(struct rtc_device *rtc)
{
mutex_lock(&rtc->ops_lock);
/*
@ -372,7 +371,6 @@ void rtc_device_unregister(struct rtc_device *rtc)
mutex_unlock(&rtc->ops_lock);
put_device(&rtc->dev);
}
EXPORT_SYMBOL_GPL(rtc_device_unregister);
static void devm_rtc_device_release(struct device *dev, void *res)
{

View File

@ -596,7 +596,6 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
* This function is called when an AIE, UIE or PIE mode interrupt
* has occurred (or been emulated).
*
* Triggers the registered irq_task function callback.
*/
void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
{
@ -741,7 +740,6 @@ static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
/**
* rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
* @rtc: the rtc device
* @task: currently registered with rtc_irq_register()
* @enabled: true to enable periodic IRQs
* Context: any
*
@ -764,7 +762,6 @@ int rtc_irq_set_state(struct rtc_device *rtc, int enabled)
/**
* rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
* @rtc: the rtc device
* @task: currently registered with rtc_irq_register()
* @freq: positive frequency
* Context: any
*

View File

@ -46,7 +46,6 @@
#define RTC_STATUS_DATA 0x01
#define COUNTS_PER_SEC (0xF000 / 60)
#define AB8500_RTC_EPOCH 2000
static const u8 ab8500_rtc_time_regs[] = {
AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG,
@ -59,23 +58,6 @@ static const u8 ab8500_rtc_alarm_regs[] = {
AB8500_RTC_ALRM_MIN_LOW_REG
};
/* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */
static unsigned long get_elapsed_seconds(int year)
{
unsigned long secs;
struct rtc_time tm = {
.tm_year = year - 1900,
.tm_mday = 1,
};
/*
* This function calculates secs from 1970 and not from
* 1900, even if we supply the offset from year 1900.
*/
rtc_tm_to_time(&tm, &secs);
return secs;
}
static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
unsigned long timeout = jiffies + HZ;
@ -118,9 +100,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
secs = secs / COUNTS_PER_SEC;
secs = secs + (mins * 60);
/* Add back the initially subtracted number of seconds */
secs += get_elapsed_seconds(AB8500_RTC_EPOCH);
rtc_time_to_tm(secs, tm);
return 0;
}
@ -131,21 +110,8 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
unsigned long no_secs, no_mins, secs = 0;
if (tm->tm_year < (AB8500_RTC_EPOCH - 1900)) {
dev_dbg(dev, "year should be equal to or greater than %d\n",
AB8500_RTC_EPOCH);
return -EINVAL;
}
/* Get the number of seconds since 1970 */
rtc_tm_to_time(tm, &secs);
/*
* Convert it to the number of seconds since 01-01-2000 00:00:00, since
* we only have a small counter in the RTC.
*/
secs -= get_elapsed_seconds(AB8500_RTC_EPOCH);
no_mins = secs / 60;
no_secs = secs % 60;
@ -202,12 +168,9 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
secs = mins * 60;
/* Add back the initially subtracted number of seconds */
secs += get_elapsed_seconds(AB8500_RTC_EPOCH);
rtc_time_to_tm(secs, &alarm->time);
return rtc_valid_tm(&alarm->time);
return 0;
}
static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled)
@ -224,12 +187,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
unsigned long mins, secs = 0, cursec = 0;
struct rtc_time curtm;
if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) {
dev_dbg(dev, "year should be equal to or greater than %d\n",
AB8500_RTC_EPOCH);
return -EINVAL;
}
/* Get the number of seconds since 1970 */
rtc_tm_to_time(&alarm->time, &secs);
@ -245,12 +202,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
return -EINVAL;
}
/*
* Convert it to the number of seconds since 01-01-2000 00:00:00, since
* we only have a small counter in the RTC.
*/
secs -= get_elapsed_seconds(AB8500_RTC_EPOCH);
mins = secs / 60;
buf[2] = mins & 0xFF;
@ -360,15 +311,14 @@ static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR,
ab8500_sysfs_show_rtc_calibration,
ab8500_sysfs_store_rtc_calibration);
static int ab8500_sysfs_rtc_register(struct device *dev)
{
return device_create_file(dev, &dev_attr_rtc_calibration);
}
static struct attribute *ab8500_rtc_attrs[] = {
&dev_attr_rtc_calibration.attr,
NULL
};
static void ab8500_sysfs_rtc_unregister(struct device *dev)
{
device_remove_file(dev, &dev_attr_rtc_calibration);
}
static const struct attribute_group ab8500_rtc_sysfs_files = {
.attrs = ab8500_rtc_attrs,
};
static irqreturn_t rtc_alarm_handler(int irq, void *data)
{
@ -429,14 +379,11 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, true);
rtc = devm_rtc_device_register(&pdev->dev, "ab8500-rtc",
(struct rtc_class_ops *)platid->driver_data,
THIS_MODULE);
if (IS_ERR(rtc)) {
dev_err(&pdev->dev, "Registration failed\n");
err = PTR_ERR(rtc);
return err;
}
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
rtc->ops = (struct rtc_class_ops *)platid->driver_data;
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
rtc_alarm_handler, IRQF_ONESHOT,
@ -447,22 +394,23 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
dev_pm_set_wake_irq(&pdev->dev, irq);
platform_set_drvdata(pdev, rtc);
err = ab8500_sysfs_rtc_register(&pdev->dev);
if (err) {
dev_err(&pdev->dev, "sysfs RTC failed to register\n");
return err;
}
rtc->uie_unsupported = 1;
return 0;
rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs
rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000;
rtc->set_start_time = true;
err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files);
if (err)
return err;
return rtc_register_device(rtc);
}
static int ab8500_rtc_remove(struct platform_device *pdev)
{
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
ab8500_sysfs_rtc_unregister(&pdev->dev);
return 0;
}

View File

@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/watchdog.h>
#define ABX8XX_REG_HTH 0x00
#define ABX8XX_REG_SC 0x01
@ -37,6 +38,7 @@
#define ABX8XX_REG_STATUS 0x0f
#define ABX8XX_STATUS_AF BIT(2)
#define ABX8XX_STATUS_WDT BIT(6)
#define ABX8XX_REG_CTRL1 0x10
#define ABX8XX_CTRL_WRITE BIT(0)
@ -61,6 +63,14 @@
#define ABX8XX_OSS_OF BIT(1)
#define ABX8XX_OSS_OMODE BIT(4)
#define ABX8XX_REG_WDT 0x1b
#define ABX8XX_WDT_WDS BIT(7)
#define ABX8XX_WDT_BMB_MASK 0x7c
#define ABX8XX_WDT_BMB_SHIFT 2
#define ABX8XX_WDT_MAX_TIME (ABX8XX_WDT_BMB_MASK >> ABX8XX_WDT_BMB_SHIFT)
#define ABX8XX_WDT_WRB_MASK 0x03
#define ABX8XX_WDT_WRB_1HZ 0x02
#define ABX8XX_REG_CFG_KEY 0x1f
#define ABX8XX_CFG_KEY_OSC 0xa1
#define ABX8XX_CFG_KEY_MISC 0x9d
@ -80,20 +90,27 @@ enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
struct abx80x_cap {
u16 pn;
bool has_tc;
bool has_wdog;
};
static struct abx80x_cap abx80x_caps[] = {
[AB0801] = {.pn = 0x0801},
[AB0803] = {.pn = 0x0803},
[AB0804] = {.pn = 0x0804, .has_tc = true},
[AB0805] = {.pn = 0x0805, .has_tc = true},
[AB0804] = {.pn = 0x0804, .has_tc = true, .has_wdog = true},
[AB0805] = {.pn = 0x0805, .has_tc = true, .has_wdog = true},
[AB1801] = {.pn = 0x1801},
[AB1803] = {.pn = 0x1803},
[AB1804] = {.pn = 0x1804, .has_tc = true},
[AB1805] = {.pn = 0x1805, .has_tc = true},
[AB1804] = {.pn = 0x1804, .has_tc = true, .has_wdog = true},
[AB1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
[ABX80X] = {.pn = 0}
};
struct abx80x_priv {
struct rtc_device *rtc;
struct i2c_client *client;
struct watchdog_device wdog;
};
static int abx80x_is_rc_mode(struct i2c_client *client)
{
int flags = 0;
@ -218,7 +235,8 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct rtc_device *rtc = i2c_get_clientdata(client);
struct abx80x_priv *priv = i2c_get_clientdata(client);
struct rtc_device *rtc = priv->rtc;
int status;
status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
@ -228,6 +246,13 @@ static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
if (status & ABX8XX_STATUS_AF)
rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
/*
* It is unclear if we'll get an interrupt before the external
* reset kicks in.
*/
if (status & ABX8XX_STATUS_WDT)
dev_alert(&client->dev, "watchdog timeout interrupt.\n");
i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
return IRQ_HANDLED;
@ -529,11 +554,94 @@ static void rtc_calib_remove_sysfs_group(void *_dev)
sysfs_remove_group(&dev->kobj, &rtc_calib_attr_group);
}
#ifdef CONFIG_WATCHDOG
static inline u8 timeout_bits(unsigned int timeout)
{
return ((timeout << ABX8XX_WDT_BMB_SHIFT) & ABX8XX_WDT_BMB_MASK) |
ABX8XX_WDT_WRB_1HZ;
}
static int __abx80x_wdog_set_timeout(struct watchdog_device *wdog,
unsigned int timeout)
{
struct abx80x_priv *priv = watchdog_get_drvdata(wdog);
u8 val = ABX8XX_WDT_WDS | timeout_bits(timeout);
/*
* Writing any timeout to the WDT register resets the watchdog timer.
* Writing 0 disables it.
*/
return i2c_smbus_write_byte_data(priv->client, ABX8XX_REG_WDT, val);
}
static int abx80x_wdog_set_timeout(struct watchdog_device *wdog,
unsigned int new_timeout)
{
int err = 0;
if (watchdog_hw_running(wdog))
err = __abx80x_wdog_set_timeout(wdog, new_timeout);
if (err == 0)
wdog->timeout = new_timeout;
return err;
}
static int abx80x_wdog_ping(struct watchdog_device *wdog)
{
return __abx80x_wdog_set_timeout(wdog, wdog->timeout);
}
static int abx80x_wdog_start(struct watchdog_device *wdog)
{
return __abx80x_wdog_set_timeout(wdog, wdog->timeout);
}
static int abx80x_wdog_stop(struct watchdog_device *wdog)
{
return __abx80x_wdog_set_timeout(wdog, 0);
}
static const struct watchdog_info abx80x_wdog_info = {
.identity = "abx80x watchdog",
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
};
static const struct watchdog_ops abx80x_wdog_ops = {
.owner = THIS_MODULE,
.start = abx80x_wdog_start,
.stop = abx80x_wdog_stop,
.ping = abx80x_wdog_ping,
.set_timeout = abx80x_wdog_set_timeout,
};
static int abx80x_setup_watchdog(struct abx80x_priv *priv)
{
priv->wdog.parent = &priv->client->dev;
priv->wdog.ops = &abx80x_wdog_ops;
priv->wdog.info = &abx80x_wdog_info;
priv->wdog.min_timeout = 1;
priv->wdog.max_timeout = ABX8XX_WDT_MAX_TIME;
priv->wdog.timeout = ABX8XX_WDT_MAX_TIME;
watchdog_set_drvdata(&priv->wdog, priv);
return devm_watchdog_register_device(&priv->client->dev, &priv->wdog);
}
#else
static int abx80x_setup_watchdog(struct abx80x_priv *priv)
{
return 0;
}
#endif
static int abx80x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device_node *np = client->dev.of_node;
struct rtc_device *rtc;
struct abx80x_priv *priv;
int i, data, err, trickle_cfg = -EINVAL;
char buf[7];
unsigned int part = id->driver_data;
@ -610,13 +718,24 @@ static int abx80x_probe(struct i2c_client *client,
if (err)
return err;
rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
rtc->ops = &abx80x_rtc_ops;
priv->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(priv->rtc))
return PTR_ERR(priv->rtc);
i2c_set_clientdata(client, rtc);
priv->rtc->ops = &abx80x_rtc_ops;
priv->client = client;
i2c_set_clientdata(client, priv);
if (abx80x_caps[part].has_wdog) {
err = abx80x_setup_watchdog(priv);
if (err)
return err;
}
if (client->irq > 0) {
dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
@ -649,7 +768,7 @@ static int abx80x_probe(struct i2c_client *client,
return err;
}
err = rtc_register_device(rtc);
err = rtc_register_device(priv->rtc);
return err;
}

View File

@ -224,7 +224,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
spin_unlock_irqrestore(&rtc->lock, flags);
rtc_time_to_tm(time, tm);
rtc_time64_to_tm(time, tm);
return 0;
}
@ -249,13 +249,9 @@ static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
int ret = 0;
unsigned long time, flags;
ret = rtc_tm_to_time(tm, &time);
if (ret)
goto out;
time = rtc_tm_to_time64(tm);
if (!rtc->initialized)
armada38x_rtc_reset(rtc);
@ -264,8 +260,7 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_delayed_write(time, rtc, RTC_TIME);
spin_unlock_irqrestore(&rtc->lock, flags);
out:
return ret;
return 0;
}
static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@ -284,7 +279,7 @@ static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
spin_unlock_irqrestore(&rtc->lock, flags);
alrm->enabled = val ? 1 : 0;
rtc_time_to_tm(time, &alrm->time);
rtc_time64_to_tm(time, &alrm->time);
return 0;
}
@ -295,12 +290,8 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
unsigned long time, flags;
int ret = 0;
ret = rtc_tm_to_time(&alrm->time, &time);
if (ret)
goto out;
time = rtc_tm_to_time64(&alrm->time);
spin_lock_irqsave(&rtc->lock, flags);
@ -313,8 +304,7 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
spin_unlock_irqrestore(&rtc->lock, flags);
out:
return ret;
return 0;
}
static int armada38x_rtc_alarm_irq_enable(struct device *dev,
@ -514,7 +504,6 @@ MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
static __init int armada38x_rtc_probe(struct platform_device *pdev)
{
const struct rtc_class_ops *ops;
struct resource *res;
struct armada38x_rtc *rtc;
const struct of_device_id *match;
@ -551,6 +540,11 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no irq\n");
return rtc->irq;
}
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
0, pdev->name, rtc) < 0) {
dev_warn(&pdev->dev, "Interrupt not available.\n");
@ -560,28 +554,26 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
if (rtc->irq != -1) {
device_init_wakeup(&pdev->dev, 1);
ops = &armada38x_rtc_ops;
rtc->rtc_dev->ops = &armada38x_rtc_ops;
} else {
/*
* If there is no interrupt available then we can't
* use the alarm
*/
ops = &armada38x_rtc_ops_noirq;
rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq;
}
rtc->data = (struct armada38x_rtc_data *)match->data;
/* Update RTC-MBUS bridge timing parameters */
rtc->data->update_mbus_timing(rtc);
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
ret = PTR_ERR(rtc->rtc_dev);
rtc->rtc_dev->range_max = U32_MAX;
ret = rtc_register_device(rtc->rtc_dev);
if (ret)
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
return ret;
}
return 0;
return ret;
}
#ifdef CONFIG_PM_SLEEP

View File

@ -50,6 +50,7 @@
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#include <linux/mc146818rtc.h>
#ifdef CONFIG_ACPI
/*
* Use ACPI SCI to replace HPET interrupt for RTC Alarm event
*
@ -61,6 +62,18 @@
static bool use_acpi_alarm;
module_param(use_acpi_alarm, bool, 0444);
static inline int cmos_use_acpi_alarm(void)
{
return use_acpi_alarm;
}
#else /* !CONFIG_ACPI */
static inline int cmos_use_acpi_alarm(void)
{
return 0;
}
#endif
struct cmos_rtc {
struct rtc_device *rtc;
struct device *dev;
@ -167,9 +180,9 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
#endif
/* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */
static int use_hpet_alarm(void)
static inline int use_hpet_alarm(void)
{
return is_hpet_enabled() && !use_acpi_alarm;
return is_hpet_enabled() && !cmos_use_acpi_alarm();
}
/*----------------------------------------------------------------*/
@ -340,7 +353,7 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
if (use_hpet_alarm())
hpet_set_rtc_irq_bit(mask);
if ((mask & RTC_AIE) && use_acpi_alarm) {
if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {
if (cmos->wake_on)
cmos->wake_on(cmos->dev);
}
@ -358,7 +371,7 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(mask);
if ((mask & RTC_AIE) && use_acpi_alarm) {
if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {
if (cmos->wake_off)
cmos->wake_off(cmos->dev);
}
@ -980,7 +993,7 @@ static int cmos_suspend(struct device *dev)
}
spin_unlock_irq(&rtc_lock);
if ((tmp & RTC_AIE) && !use_acpi_alarm) {
if ((tmp & RTC_AIE) && !cmos_use_acpi_alarm()) {
cmos->enabled_wake = 1;
if (cmos->wake_on)
cmos->wake_on(dev);
@ -1031,7 +1044,7 @@ static void cmos_check_wkalrm(struct device *dev)
* ACPI RTC wake event is cleared after resume from STR,
* ACK the rtc irq here
*/
if (t_now >= cmos->alarm_expires && use_acpi_alarm) {
if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) {
cmos_interrupt(0, (void *)cmos->rtc);
return;
}
@ -1053,7 +1066,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp;
if (cmos->enabled_wake && !use_acpi_alarm) {
if (cmos->enabled_wake && !cmos_use_acpi_alarm()) {
if (cmos->wake_off)
cmos->wake_off(dev);
else
@ -1132,7 +1145,7 @@ static u32 rtc_handler(void *context)
* Or else, ACPI SCI is enabled during suspend/resume only,
* update rtc irq in that case.
*/
if (use_acpi_alarm)
if (cmos_use_acpi_alarm())
cmos_interrupt(0, (void *)cmos->rtc);
else {
/* Fix me: can we use cmos_interrupt() here as well? */

View File

@ -40,23 +40,9 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc)
#ifdef CONFIG_RTC_INTF_SYSFS
const struct attribute_group **rtc_get_dev_attribute_groups(void);
int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp);
int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps);
#else
static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)
{
return NULL;
}
static inline
int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
{
return 0;
}
static inline
int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
{
return 0;
}
#endif

View File

@ -114,6 +114,20 @@ enum ds_type {
# define RX8025_BIT_VDET 0x40
# define RX8025_BIT_XST 0x20
#define M41TXX_REG_CONTROL 0x07
# define M41TXX_BIT_OUT BIT(7)
# define M41TXX_BIT_FT BIT(6)
# define M41TXX_BIT_CALIB_SIGN BIT(5)
# define M41TXX_M_CALIBRATION GENMASK(4, 0)
/* negative offset step is -2.034ppm */
#define M41TXX_NEG_OFFSET_STEP_PPB 2034
/* positive offset step is +4.068ppm */
#define M41TXX_POS_OFFSET_STEP_PPB 4068
/* Min and max values supported with 'offset' interface by M41TXX */
#define M41TXX_MIN_OFFSET ((-31) * M41TXX_NEG_OFFSET_STEP_PPB)
#define M41TXX_MAX_OFFSET ((31) * M41TXX_POS_OFFSET_STEP_PPB)
struct ds1307 {
enum ds_type type;
unsigned long flags;
@ -146,6 +160,9 @@ struct chip_desc {
static int ds1307_get_time(struct device *dev, struct rtc_time *t);
static int ds1307_set_time(struct device *dev, struct rtc_time *t);
static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t);
static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t);
static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled);
static u8 do_trickle_setup_ds1339(struct ds1307 *, u32 ohms, bool diode);
static irqreturn_t rx8130_irq(int irq, void *dev_id);
static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t);
@ -155,6 +172,8 @@ static irqreturn_t mcp794xx_irq(int irq, void *dev_id);
static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t);
static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t);
static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled);
static int m41txx_rtc_read_offset(struct device *dev, long *offset);
static int m41txx_rtc_set_offset(struct device *dev, long offset);
static const struct rtc_class_ops rx8130_rtc_ops = {
.read_time = ds1307_get_time,
@ -172,6 +191,16 @@ static const struct rtc_class_ops mcp794xx_rtc_ops = {
.alarm_irq_enable = mcp794xx_alarm_irq_enable,
};
static const struct rtc_class_ops m41txx_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
.read_alarm = ds1337_read_alarm,
.set_alarm = ds1337_set_alarm,
.alarm_irq_enable = ds1307_alarm_irq_enable,
.read_offset = m41txx_rtc_read_offset,
.set_offset = m41txx_rtc_set_offset,
};
static const struct chip_desc chips[last_ds_type] = {
[ds_1307] = {
.nvram_offset = 8,
@ -228,10 +257,17 @@ static const struct chip_desc chips[last_ds_type] = {
.irq_handler = rx8130_irq,
.rtc_ops = &rx8130_rtc_ops,
},
[m41t0] = {
.rtc_ops = &m41txx_rtc_ops,
},
[m41t00] = {
.rtc_ops = &m41txx_rtc_ops,
},
[m41t11] = {
/* this is battery backed SRAM */
.nvram_offset = 8,
.nvram_size = 56,
.rtc_ops = &m41txx_rtc_ops,
},
[mcp794xx] = {
.alarm = 1,
@ -973,6 +1009,110 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
enabled ? MCP794XX_BIT_ALM0_EN : 0);
}
static int m41txx_rtc_read_offset(struct device *dev, long *offset)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
unsigned int ctrl_reg;
u8 val;
regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg);
val = ctrl_reg & M41TXX_M_CALIBRATION;
/* check if positive */
if (ctrl_reg & M41TXX_BIT_CALIB_SIGN)
*offset = (val * M41TXX_POS_OFFSET_STEP_PPB);
else
*offset = -(val * M41TXX_NEG_OFFSET_STEP_PPB);
return 0;
}
static int m41txx_rtc_set_offset(struct device *dev, long offset)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
unsigned int ctrl_reg;
if ((offset < M41TXX_MIN_OFFSET) || (offset > M41TXX_MAX_OFFSET))
return -ERANGE;
if (offset >= 0) {
ctrl_reg = DIV_ROUND_CLOSEST(offset,
M41TXX_POS_OFFSET_STEP_PPB);
ctrl_reg |= M41TXX_BIT_CALIB_SIGN;
} else {
ctrl_reg = DIV_ROUND_CLOSEST(abs(offset),
M41TXX_NEG_OFFSET_STEP_PPB);
}
return regmap_update_bits(ds1307->regmap, M41TXX_REG_CONTROL,
M41TXX_M_CALIBRATION | M41TXX_BIT_CALIB_SIGN,
ctrl_reg);
}
static ssize_t frequency_test_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev->parent);
bool freq_test_en;
int ret;
ret = kstrtobool(buf, &freq_test_en);
if (ret) {
dev_err(dev, "Failed to store RTC Frequency Test attribute\n");
return ret;
}
regmap_update_bits(ds1307->regmap, M41TXX_REG_CONTROL, M41TXX_BIT_FT,
freq_test_en ? M41TXX_BIT_FT : 0);
return count;
}
static ssize_t frequency_test_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev->parent);
unsigned int ctrl_reg;
regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg);
return scnprintf(buf, PAGE_SIZE, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" :
"off\n");
}
static DEVICE_ATTR_RW(frequency_test);
static struct attribute *rtc_freq_test_attrs[] = {
&dev_attr_frequency_test.attr,
NULL,
};
static const struct attribute_group rtc_freq_test_attr_group = {
.attrs = rtc_freq_test_attrs,
};
static int ds1307_add_frequency_test(struct ds1307 *ds1307)
{
int err;
switch (ds1307->type) {
case m41t0:
case m41t00:
case m41t11:
err = rtc_add_group(ds1307->rtc, &rtc_freq_test_attr_group);
if (err)
return err;
break;
default:
break;
}
return 0;
}
/*----------------------------------------------------------------------*/
static int ds1307_nvram_read(void *priv, unsigned int offset, void *val,
@ -1384,7 +1524,6 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
static const struct regmap_config regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x9,
};
static int ds1307_probe(struct i2c_client *client,
@ -1711,6 +1850,10 @@ read_rtc:
}
ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops;
err = ds1307_add_frequency_test(ds1307);
if (err)
return err;
err = rtc_register_device(ds1307->rtc);
if (err)
return err;

View File

@ -770,33 +770,6 @@ static const char *ds1685_rtc_sqw_freq[16] = {
"512Hz", "256Hz", "128Hz", "64Hz", "32Hz", "16Hz", "8Hz", "4Hz", "2Hz"
};
#ifdef CONFIG_RTC_DS1685_PROC_REGS
/**
* ds1685_rtc_print_regs - helper function to print register values.
* @hex: hex byte to convert into binary bits.
* @dest: destination char array.
*
* This is basically a hex->binary function, just with extra spacing between
* the digits. It only works on 1-byte values (8 bits).
*/
static char*
ds1685_rtc_print_regs(u8 hex, char *dest)
{
u32 i, j;
char *tmp = dest;
for (i = 0; i < NUM_BITS; i++) {
*tmp++ = ((hex & 0x80) != 0 ? '1' : '0');
for (j = 0; j < NUM_SPACES; j++)
*tmp++ = ' ';
hex <<= 1;
}
*tmp++ = '\0';
return dest;
}
#endif
/**
* ds1685_rtc_proc - procfs access function.
* @dev: pointer to device structure.
@ -805,13 +778,9 @@ ds1685_rtc_print_regs(u8 hex, char *dest)
static int
ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8];
char *model;
#ifdef CONFIG_RTC_DS1685_PROC_REGS
char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1];
#endif
/* Read all the relevant data from the control registers. */
ds1685_rtc_switch_to_bank1(rtc);
@ -859,28 +828,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
"Periodic IRQ\t: %s\n"
"Periodic Rate\t: %s\n"
"SQW Freq\t: %s\n"
#ifdef CONFIG_RTC_DS1685_PROC_REGS
"Serial #\t: %8phC\n"
"Register Status\t:\n"
" Ctrl A\t: UIP DV2 DV1 DV0 RS3 RS2 RS1 RS0\n"
"\t\t: %s\n"
" Ctrl B\t: SET PIE AIE UIE SQWE DM 2412 DSE\n"
"\t\t: %s\n"
" Ctrl C\t: IRQF PF AF UF --- --- --- ---\n"
"\t\t: %s\n"
" Ctrl D\t: VRT --- --- --- --- --- --- ---\n"
"\t\t: %s\n"
#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
" Ctrl 4A\t: VRT2 INCR BME --- PAB RF WF KF\n"
#else
" Ctrl 4A\t: VRT2 INCR --- --- PAB RF WF KF\n"
#endif
"\t\t: %s\n"
" Ctrl 4B\t: ABE E32k CS RCE PRS RIE WIE KSE\n"
"\t\t: %s\n",
#else
"Serial #\t: %8phC\n",
#endif
model,
((ctrla & RTC_CTRL_A_DV1) ? "enabled" : "disabled"),
((ctrlb & RTC_CTRL_B_2412) ? "24-hour" : "12-hour"),
@ -894,17 +842,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
ds1685_rtc_pirq_rate[(ctrla & RTC_CTRL_A_RS_MASK)] : "none"),
(!((ctrl4b & RTC_CTRL_4B_E32K)) ?
ds1685_rtc_sqw_freq[(ctrla & RTC_CTRL_A_RS_MASK)] : "32768Hz"),
#ifdef CONFIG_RTC_DS1685_PROC_REGS
ssn,
ds1685_rtc_print_regs(ctrla, bits[0]),
ds1685_rtc_print_regs(ctrlb, bits[1]),
ds1685_rtc_print_regs(ctrlc, bits[2]),
ds1685_rtc_print_regs(ctrld, bits[3]),
ds1685_rtc_print_regs(ctrl4a, bits[4]),
ds1685_rtc_print_regs(ctrl4b, bits[5]));
#else
ssn);
#endif
return 0;
}
#else
@ -927,30 +865,13 @@ ds1685_rtc_ops = {
};
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* SysFS interface */
#ifdef CONFIG_SYSFS
/**
* ds1685_rtc_sysfs_nvram_read - reads rtc nvram via sysfs.
* @file: pointer to file structure.
* @kobj: pointer to kobject structure.
* @bin_attr: pointer to bin_attribute structure.
* @buf: pointer to char array to hold the output.
* @pos: current file position pointer.
* @size: size of the data to read.
*/
static ssize_t
ds1685_rtc_sysfs_nvram_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t pos, size_t size)
static int ds1685_nvram_read(void *priv, unsigned int pos, void *val,
size_t size)
{
struct platform_device *pdev =
to_platform_device(container_of(kobj, struct device, kobj));
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = priv;
ssize_t count;
unsigned long flags = 0;
u8 *buf = val;
spin_lock_irqsave(&rtc->lock, flags);
ds1685_rtc_switch_to_bank0(rtc);
@ -1004,33 +925,16 @@ ds1685_rtc_sysfs_nvram_read(struct file *filp, struct kobject *kobj,
#endif /* !CONFIG_RTC_DRV_DS1689 */
spin_unlock_irqrestore(&rtc->lock, flags);
/*
* XXX: Bug? this appears to cause the function to get executed
* several times in succession. But it's the only way to actually get
* data written out to a file.
*/
return count;
return 0;
}
/**
* ds1685_rtc_sysfs_nvram_write - writes rtc nvram via sysfs.
* @file: pointer to file structure.
* @kobj: pointer to kobject structure.
* @bin_attr: pointer to bin_attribute structure.
* @buf: pointer to char array to hold the input.
* @pos: current file position pointer.
* @size: size of the data to write.
*/
static ssize_t
ds1685_rtc_sysfs_nvram_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t pos, size_t size)
static int ds1685_nvram_write(void *priv, unsigned int pos, void *val,
size_t size)
{
struct platform_device *pdev =
to_platform_device(container_of(kobj, struct device, kobj));
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = priv;
ssize_t count;
unsigned long flags = 0;
u8 *buf = val;
spin_lock_irqsave(&rtc->lock, flags);
ds1685_rtc_switch_to_bank0(rtc);
@ -1084,26 +988,11 @@ ds1685_rtc_sysfs_nvram_write(struct file *filp, struct kobject *kobj,
#endif /* !CONFIG_RTC_DRV_DS1689 */
spin_unlock_irqrestore(&rtc->lock, flags);
return count;
return 0;
}
/**
* struct ds1685_rtc_sysfs_nvram_attr - sysfs attributes for rtc nvram.
* @attr: nvram attributes.
* @read: nvram read function.
* @write: nvram write function.
* @size: nvram total size (bank0 + extended).
*/
static struct bin_attribute
ds1685_rtc_sysfs_nvram_attr = {
.attr = {
.name = "nvram",
.mode = S_IRUGO | S_IWUSR,
},
.read = ds1685_rtc_sysfs_nvram_read,
.write = ds1685_rtc_sysfs_nvram_write,
.size = NVRAM_TOTAL_SZ
};
/* ----------------------------------------------------------------------- */
/* SysFS interface */
/**
* ds1685_rtc_sysfs_battery_show - sysfs file for main battery status.
@ -1188,43 +1077,6 @@ ds1685_rtc_sysfs_misc_grp = {
.attrs = ds1685_rtc_sysfs_misc_attrs,
};
/**
* ds1685_rtc_sysfs_register - register sysfs files.
* @dev: pointer to device structure.
*/
static int
ds1685_rtc_sysfs_register(struct device *dev)
{
int ret = 0;
sysfs_bin_attr_init(&ds1685_rtc_sysfs_nvram_attr);
ret = sysfs_create_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
if (ret)
return ret;
ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
if (ret)
return ret;
return 0;
}
/**
* ds1685_rtc_sysfs_unregister - unregister sysfs files.
* @dev: pointer to device structure.
*/
static int
ds1685_rtc_sysfs_unregister(struct device *dev)
{
sysfs_remove_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
return 0;
}
#endif /* CONFIG_SYSFS */
/* ----------------------------------------------------------------------- */
/* Driver Probe/Removal */
@ -1242,6 +1094,12 @@ ds1685_rtc_probe(struct platform_device *pdev)
u8 ctrla, ctrlb, hours;
unsigned char am_pm;
int ret = 0;
struct nvmem_config nvmem_cfg = {
.name = "ds1685_nvram",
.size = NVRAM_TOTAL_SZ,
.reg_read = ds1685_nvram_read,
.reg_write = ds1685_nvram_write,
};
/* Get the platform data. */
pdata = (struct ds1685_rtc_platform_data *) pdev->dev.platform_data;
@ -1499,11 +1357,15 @@ ds1685_rtc_probe(struct platform_device *pdev)
/* Setup complete. */
ds1685_rtc_switch_to_bank0(rtc);
#ifdef CONFIG_SYSFS
ret = ds1685_rtc_sysfs_register(&pdev->dev);
ret = rtc_add_group(rtc_dev, &ds1685_rtc_sysfs_misc_grp);
if (ret)
return ret;
rtc_dev->nvram_old_abi = true;
nvmem_cfg.priv = rtc;
ret = rtc_nvmem_register(rtc_dev, &nvmem_cfg);
if (ret)
return ret;
#endif
return rtc_register_device(rtc_dev);
}
@ -1517,10 +1379,6 @@ ds1685_rtc_remove(struct platform_device *pdev)
{
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
#ifdef CONFIG_SYSFS
ds1685_rtc_sysfs_unregister(&pdev->dev);
#endif
/* Read Ctrl B and clear PIE/AIE/UIE. */
rtc->write(rtc, RTC_CTRL_B,
(rtc->read(rtc, RTC_CTRL_B) &

View File

@ -10,12 +10,11 @@
*
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#include "rtc-core.h"
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/rtc.h>
/* Register map */
/* rtc section */
@ -518,7 +517,7 @@ static ssize_t timestamp0_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev->parent);
int sr;
sr = isl1208_i2c_get_sr(client);
@ -540,7 +539,7 @@ static ssize_t timestamp0_store(struct device *dev,
static ssize_t timestamp0_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev->parent);
u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, };
struct rtc_time tm;
int sr;
@ -650,7 +649,7 @@ static ssize_t
isl1208_sysfs_show_atrim(struct device *dev,
struct device_attribute *attr, char *buf)
{
int atr = isl1208_i2c_get_atr(to_i2c_client(dev));
int atr = isl1208_i2c_get_atr(to_i2c_client(dev->parent));
if (atr < 0)
return atr;
@ -663,7 +662,7 @@ static ssize_t
isl1208_sysfs_show_dtrim(struct device *dev,
struct device_attribute *attr, char *buf)
{
int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev->parent));
if (dtr < 0)
return dtr;
@ -676,7 +675,7 @@ static ssize_t
isl1208_sysfs_show_usr(struct device *dev,
struct device_attribute *attr, char *buf)
{
int usr = isl1208_i2c_get_usr(to_i2c_client(dev));
int usr = isl1208_i2c_get_usr(to_i2c_client(dev->parent));
if (usr < 0)
return usr;
@ -701,7 +700,10 @@ isl1208_sysfs_store_usr(struct device *dev,
if (usr < 0 || usr > 0xffff)
return -EINVAL;
return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
if (isl1208_i2c_set_usr(to_i2c_client(dev->parent), usr))
return -EIO;
return count;
}
static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
@ -765,7 +767,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
rtc->ops = &isl1208_rtc_ops;
i2c_set_clientdata(client, rtc);
dev_set_drvdata(&rtc->dev, client);
rc = isl1208_i2c_get_sr(client);
if (rc < 0) {
@ -804,7 +805,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
evdet_irq = of_irq_get_byname(np, "evdet");
}
rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files);
rc = rtc_add_group(rtc, &isl1208_rtc_sysfs_files);
if (rc)
return rc;
@ -821,14 +822,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
return rtc_register_device(rtc);
}
static int
isl1208_remove(struct i2c_client *client)
{
sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files);
return 0;
}
static const struct i2c_device_id isl1208_id[] = {
{ "isl1208", TYPE_ISL1208 },
{ "isl1218", TYPE_ISL1218 },
@ -851,7 +844,6 @@ static struct i2c_driver isl1208_driver = {
.of_match_table = of_match_ptr(isl1208_of_match),
},
.probe = isl1208_probe,
.remove = isl1208_remove,
.id_table = isl1208_id,
};

View File

@ -47,7 +47,7 @@ EXPORT_SYMBOL(rtc_year_days);
/*
* rtc_time_to_tm64 - Converts time64_t to rtc_time.
* rtc_time64_to_tm - Converts time64_t to rtc_time.
* Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
*/
void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)

View File

@ -745,7 +745,7 @@ static int wdt_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
wdt_margin = new_margin;
wdt_ping();
/* Fall */
/* Fall through */
case WDIOC_GETTIMEOUT:
return put_user(wdt_margin, (int __user *)arg);

View File

@ -90,7 +90,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
unsigned long flags;
if (vrtc_is_updating())
mdelay(20);
msleep(20);
spin_lock_irqsave(&rtc_lock, flags);
time->tm_sec = vrtc_cmos_read(RTC_SECONDS);
@ -261,11 +261,10 @@ static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int mrst_procfs(struct device *dev, struct seq_file *seq)
{
unsigned char rtc_control, valid;
unsigned char rtc_control;
spin_lock_irq(&rtc_lock);
rtc_control = vrtc_cmos_read(RTC_CONTROL);
valid = vrtc_cmos_read(RTC_VALID);
spin_unlock_irq(&rtc_lock);
seq_printf(seq,

View File

@ -332,6 +332,10 @@ static int mtk_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
ret = request_threaded_irq(rtc->irq, NULL,
mtk_rtc_irq_handler_thread,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
@ -344,11 +348,11 @@ static int mtk_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev,
&mtk_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
rtc->rtc_dev->ops = &mtk_rtc_ops;
ret = rtc_register_device(rtc->rtc_dev);
if (ret) {
dev_err(&pdev->dev, "register rtc device failed\n");
ret = PTR_ERR(rtc->rtc_dev);
goto out_free_irq;
}
@ -365,7 +369,6 @@ static int mtk_rtc_remove(struct platform_device *pdev)
{
struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
rtc_device_unregister(rtc->rtc_dev);
free_irq(rtc->irq, rtc->rtc_dev);
irq_dispose_mapping(rtc->irq);

View File

@ -125,13 +125,9 @@ static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
/* hw counts from year 2000, but tm_year is relative to 1900 */
alm->time.tm_year = bcd2bin(year) + 100;
if (rtc_valid_tm(&alm->time) < 0) {
dev_err(dev, "retrieved alarm date/time is not valid.\n");
rtc_time_to_tm(0, &alm->time);
}
alm->enabled = !!readl(ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
return 0;
return rtc_valid_tm(&alm->time);
}
static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)

View File

@ -421,12 +421,6 @@ static struct omap_rtc *omap_rtc_power_off_rtc;
* The RTC can be used to control an external PMIC via the pmic_power_en pin,
* which can be configured to transition to OFF on ALARM2 events.
*
* Notes:
* The two-second alarm offset is the shortest offset possible as the alarm
* registers must be set before the next timer update and the offset
* calculation is too heavy for everything to be done within a single access
* period (~15 us).
*
* Called with local interrupts disabled.
*/
static void omap_rtc_power_off(void)
@ -434,6 +428,7 @@ static void omap_rtc_power_off(void)
struct omap_rtc *rtc = omap_rtc_power_off_rtc;
struct rtc_time tm;
unsigned long now;
int seconds;
u32 val;
rtc->type->unlock(rtc);
@ -441,11 +436,13 @@ static void omap_rtc_power_off(void)
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
/* set alarm two seconds from now */
again:
/* set alarm one second from now */
omap_rtc_read_time_raw(rtc, &tm);
seconds = tm.tm_sec;
bcd2tm(&tm);
rtc_tm_to_time(&tm, &now);
rtc_time_to_tm(now + 2, &tm);
rtc_time_to_tm(now + 1, &tm);
if (tm2bcd(&tm) < 0) {
dev_err(&rtc->rtc->dev, "power off failed\n");
@ -470,14 +467,22 @@ static void omap_rtc_power_off(void)
val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
/* Retry in case roll over happened before alarm was armed. */
if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) {
val = rtc_read(rtc, OMAP_RTC_STATUS_REG);
if (!(val & OMAP_RTC_STATUS_ALARM2))
goto again;
}
rtc->type->lock(rtc);
/*
* Wait for alarm to trigger (within two seconds) and external PMIC to
* Wait for alarm to trigger (within one second) and external PMIC to
* power off the system. Add a 500 ms margin for external latencies
* (e.g. debounce circuits).
*/
mdelay(2500);
mdelay(1500);
}
static const struct rtc_class_ops omap_rtc_ops = {
@ -721,8 +726,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (of_id) {
rtc->type = of_id->data;
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
of_property_read_bool(pdev->dev.of_node,
"system-power-controller");
of_device_is_system_power_controller(pdev->dev.of_node);
} else {
id_entry = platform_get_device_id(pdev);
rtc->type = (void *)id_entry->driver_data;

View File

@ -112,6 +112,13 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
goto err_rtc;
}
rtc->rtc = devm_rtc_allocate_device(&dev->dev);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
goto err_rtc;
}
rtc->rtc->ops = &pl030_ops;
rtc->base = ioremap(dev->res.start, resource_size(&dev->res));
if (!rtc->base) {
ret = -ENOMEM;
@ -128,12 +135,9 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
goto err_irq;
rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops,
THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
ret = rtc_register_device(rtc->rtc);
if (ret)
goto err_reg;
}
return 0;
@ -154,7 +158,6 @@ static int pl030_remove(struct amba_device *dev)
writel(0, rtc->base + RTC_CR);
free_irq(dev->irq[0], rtc);
rtc_device_unregister(rtc->rtc);
iounmap(rtc->base);
amba_release_regions(dev);

View File

@ -310,7 +310,6 @@ static int pl031_remove(struct amba_device *adev)
device_init_wakeup(&adev->dev, false);
if (adev->irq[0])
free_irq(adev->irq[0], ldata);
rtc_device_unregister(ldata->rtc);
amba_release_regions(adev);
return 0;
@ -383,24 +382,25 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
}
device_init_wakeup(&adev->dev, true);
ldata->rtc = rtc_device_register("pl031", &adev->dev, ops,
THIS_MODULE);
if (IS_ERR(ldata->rtc)) {
ret = PTR_ERR(ldata->rtc);
ldata->rtc = devm_rtc_allocate_device(&adev->dev);
if (IS_ERR(ldata->rtc))
return PTR_ERR(ldata->rtc);
ldata->rtc->ops = ops;
ret = rtc_register_device(ldata->rtc);
if (ret)
goto out;
}
if (adev->irq[0]) {
ret = request_irq(adev->irq[0], pl031_interrupt,
vendor->irqflags, "rtc-pl031", ldata);
if (ret)
goto out_no_irq;
goto out;
dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
}
return 0;
out_no_irq:
rtc_device_unregister(ldata->rtc);
out:
amba_release_regions(adev);
err_req:

View File

@ -66,6 +66,17 @@ rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
u8 txbuf[5+7], *txp;
int ret;
ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
if (ret < 0)
return ret;
if (ret & RS5C348_BIT_XSTP) {
txbuf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
txbuf[1] = 0;
ret = spi_write_then_read(spi, txbuf, 2, NULL, 0);
if (ret < 0)
return ret;
}
/* Transfer 5 bytes before writing SEC. This gives 31us for carry. */
txp = txbuf;
txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
@ -102,6 +113,16 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
u8 txbuf[5], rxbuf[7];
int ret;
ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
if (ret < 0)
return ret;
if (ret & RS5C348_BIT_VDET)
dev_warn(&spi->dev, "voltage-low detected.\n");
if (ret & RS5C348_BIT_XSTP) {
dev_warn(&spi->dev, "oscillator-stop detected.\n");
return -EINVAL;
}
/* Transfer 5 byte befores reading SEC. This gives 31us for carry. */
txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
txbuf[1] = 0; /* dummy */
@ -143,8 +164,6 @@ static const struct rtc_class_ops rs5c348_rtc_ops = {
.set_time = rs5c348_rtc_set_time,
};
static struct spi_driver rs5c348_driver;
static int rs5c348_probe(struct spi_device *spi)
{
int ret;
@ -161,53 +180,27 @@ static int rs5c348_probe(struct spi_device *spi)
ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS));
if (ret < 0 || (ret & 0x80)) {
dev_err(&spi->dev, "not found.\n");
goto kfree_exit;
return ret;
}
dev_info(&spi->dev, "spiclk %u KHz.\n",
(spi->max_speed_hz + 500) / 1000);
/* turn RTC on if it was not on */
ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
if (ret < 0)
goto kfree_exit;
if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
u8 buf[2];
struct rtc_time tm;
if (ret & RS5C348_BIT_VDET)
dev_warn(&spi->dev, "voltage-low detected.\n");
if (ret & RS5C348_BIT_XSTP)
dev_warn(&spi->dev, "oscillator-stop detected.\n");
rtc_time_to_tm(0, &tm); /* 1970/1/1 */
ret = rs5c348_rtc_set_time(&spi->dev, &tm);
if (ret < 0)
goto kfree_exit;
buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
buf[1] = 0;
ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
if (ret < 0)
goto kfree_exit;
}
ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
if (ret < 0)
goto kfree_exit;
return ret;
if (ret & RS5C348_BIT_24H)
pdata->rtc_24h = 1;
rtc = devm_rtc_device_register(&spi->dev, rs5c348_driver.driver.name,
&rs5c348_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
ret = PTR_ERR(rtc);
goto kfree_exit;
}
rtc = devm_rtc_allocate_device(&spi->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pdata->rtc = rtc;
return 0;
kfree_exit:
return ret;
rtc->ops = &rs5c348_rtc_ops;
return rtc_register_device(rtc);
}
static struct spi_driver rs5c348_driver = {

View File

@ -615,6 +615,7 @@ static int rv8803_probe(struct i2c_client *client,
static const struct i2c_device_id rv8803_id[] = {
{ "rv8803", rv_8803 },
{ "rx8803", rv_8803 },
{ "rx8900", rx_8900 },
{ }
};
@ -623,7 +624,11 @@ MODULE_DEVICE_TABLE(i2c, rv8803_id);
static const struct of_device_id rv8803_of_match[] = {
{
.compatible = "microcrystal,rv8803",
.data = (void *)rx_8900
.data = (void *)rv_8803
},
{
.compatible = "epson,rx8803",
.data = (void *)rv_8803
},
{
.compatible = "epson,rx8900",

View File

@ -108,7 +108,7 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
static int s35390a_init(struct s35390a *s35390a)
{
char buf;
u8 buf;
int ret;
unsigned initcount = 0;

View File

@ -129,19 +129,6 @@ static int sprd_rtc_clear_alarm_ints(struct sprd_rtc *rtc)
SPRD_RTC_ALM_INT_MASK);
}
static int sprd_rtc_disable_ints(struct sprd_rtc *rtc)
{
int ret;
ret = regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN,
SPRD_RTC_INT_MASK, 0);
if (ret)
return ret;
return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR,
SPRD_RTC_INT_MASK);
}
static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock)
{
int ret;
@ -172,7 +159,8 @@ static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock)
return ret;
}
return 0;
return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR,
SPRD_RTC_SPG_UPD_EN);
}
static int sprd_rtc_get_secs(struct sprd_rtc *rtc, enum sprd_rtc_reg_types type,
@ -427,10 +415,14 @@ static int sprd_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
u32 val;
/*
* If aie_timer is enabled, we should get the normal alarm time.
* Before RTC device is registered, it will check to see if there is an
* alarm already set in RTC hardware, and we always read the normal
* alarm at this time.
*
* Or if aie_timer is enabled, we should get the normal alarm time.
* Otherwise we should get auxiliary alarm time.
*/
if (rtc->rtc && rtc->rtc->aie_timer.enabled == 0)
if (rtc->rtc && rtc->rtc->registered && rtc->rtc->aie_timer.enabled == 0)
return sprd_rtc_read_aux_alarm(dev, alrm);
ret = sprd_rtc_get_secs(rtc, SPRD_RTC_ALARM, &secs);
@ -575,6 +567,32 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc)
return 0;
}
static int sprd_rtc_check_alarm_int(struct sprd_rtc *rtc)
{
u32 val;
int ret;
ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val);
if (ret)
return ret;
/*
* The SPRD_RTC_INT_EN register is not put in always-power-on region
* supplied by VDDRTC, so we should check if we need enable the alarm
* interrupt when system booting.
*
* If we have set SPRD_RTC_POWEROFF_ALM_FLAG which is saved in
* always-power-on region, that means we have set one alarm last time,
* so we should enable the alarm interrupt to help RTC core to see if
* there is an alarm already set in RTC hardware.
*/
if (!(val & SPRD_RTC_POWEROFF_ALM_FLAG))
return 0;
return regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN,
SPRD_RTC_ALARM_EN, SPRD_RTC_ALARM_EN);
}
static int sprd_rtc_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@ -608,10 +626,10 @@ static int sprd_rtc_probe(struct platform_device *pdev)
rtc->dev = &pdev->dev;
platform_set_drvdata(pdev, rtc);
/* clear all RTC interrupts and disable all RTC interrupts */
ret = sprd_rtc_disable_ints(rtc);
/* check if we need set the alarm interrupt */
ret = sprd_rtc_check_alarm_int(rtc);
if (ret) {
dev_err(&pdev->dev, "failed to disable RTC interrupts\n");
dev_err(&pdev->dev, "failed to check RTC alarm interrupt\n");
return ret;
}
@ -631,16 +649,18 @@ static int sprd_rtc_probe(struct platform_device *pdev)
return ret;
}
device_init_wakeup(&pdev->dev, 1);
rtc->rtc->ops = &sprd_rtc_ops;
rtc->rtc->range_min = 0;
rtc->rtc->range_max = 5662310399LL;
ret = rtc_register_device(rtc->rtc);
if (ret) {
dev_err(&pdev->dev, "failed to register rtc device\n");
device_init_wakeup(&pdev->dev, 0);
return ret;
}
device_init_wakeup(&pdev->dev, 1);
return 0;
}

View File

@ -199,8 +199,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
if (!rtc)
return;
clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2),
GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
if (!clk_data) {
kfree(rtc);
return;

View File

@ -338,8 +338,8 @@ int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
new_cnt = old_cnt + add_cnt + 1;
groups = devm_kcalloc(&rtc->dev, new_cnt, sizeof(*groups), GFP_KERNEL);
if (IS_ERR_OR_NULL(groups))
return PTR_ERR(groups);
if (!groups)
return -ENOMEM;
memcpy(groups, rtc->dev.groups, old_cnt * sizeof(*groups));
memcpy(groups + old_cnt, grps, add_cnt * sizeof(*groups));
groups[old_cnt + add_cnt] = NULL;

View File

@ -322,9 +322,13 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
if (IS_ERR(info->rtc_base))
return PTR_ERR(info->rtc_base);
info->tegra_rtc_irq = platform_get_irq(pdev, 0);
if (info->tegra_rtc_irq <= 0)
return -EBUSY;
ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "failed to get platform IRQ: %d\n", ret);
return ret;
}
info->tegra_rtc_irq = ret;
info->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk))

View File

@ -1,11 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/*
* An RTC test device/driver
* Copyright (C) 2005 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
@ -197,7 +194,7 @@ static void __exit test_exit(void)
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("RTC test driver/device");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
module_init(test_init);
module_exit(test_exit);

View File

@ -253,9 +253,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
struct resource *res;
int irq, ret;
struct nvmem_config nvmem_cfg = {
.name = "rv8803_nvram",
.word_size = 4,
.stride = 4,
.name = "tx4939_nvram",
.size = TX4939_RTC_REG_RAMSIZE,
.reg_read = tx4939_nvram_read,
.reg_write = tx4939_nvram_write,

View File

@ -136,8 +136,7 @@ static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
time64_t epoch_sec, current_sec;
epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
current_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
current_sec = rtc_tm_to_time64(time);
write_elapsed_second(current_sec - epoch_sec);
@ -158,7 +157,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
spin_unlock_irq(&rtc_lock);
rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
rtc_time64_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
return 0;
}
@ -166,10 +165,8 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{
time64_t alarm_sec;
struct rtc_time *time = &wkalrm->time;
alarm_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
alarm_sec = rtc_tm_to_time64(&wkalrm->time);
spin_lock_irq(&rtc_lock);

View File

@ -167,17 +167,12 @@ struct rtc_device {
#define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */
#define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */
extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner);
extern struct rtc_device *devm_rtc_device_register(struct device *dev,
const char *name,
const struct rtc_class_ops *ops,
struct module *owner);
struct rtc_device *devm_rtc_allocate_device(struct device *dev);
int __rtc_register_device(struct module *owner, struct rtc_device *rtc);
extern void rtc_device_unregister(struct rtc_device *rtc);
extern void devm_rtc_device_unregister(struct device *dev,
struct rtc_device *rtc);
@ -277,4 +272,20 @@ static inline int rtc_nvmem_register(struct rtc_device *rtc,
static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {}
#endif
#ifdef CONFIG_RTC_INTF_SYSFS
int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp);
int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps);
#else
static inline
int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
{
return 0;
}
static inline
int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
{
return 0;
}
#endif
#endif /* _LINUX_RTC_H_ */