Skip to content

Commit

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

Pull RTC updates from Alexandre Belloni:
 "It is now possible to add custom sysfs attributes while avoiding a
  possible race condition. Unused code has been removed resulting in a
  nice reduction of the code base. And more drivers have been switched
  to SPDX by their maintainers.

 Summary:

  Subsystem:
   - new helpers to add custom sysfs attributes
   - struct rtc_task removal along with rtc_irq_[un]register()
   - rtc_irq_set_state and rtc_irq_set_freq are not exported anymore

  Drivers:
   - armada38x: reset after rtc power loss
   - ds1307: now supports m41t11
   - isl1208: now supports isl1219 and tamper detection
   - pcf2127: internal SRAM support"

* tag 'rtc-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (34 commits)
  rtc: ds1307: simplify hwmon config
  rtc: s5m: Add SPDX license identifier
  rtc: maxim: Add SPDX license identifiers
  rtc: isl1219: add device tree documentation
  rtc: isl1208: set ev-evienb bit from device tree
  rtc: isl1208: Add "evdet" interrupt source for isl1219
  rtc: isl1208: add support for isl1219 with tamper detection
  rtc: sysfs: facilitate attribute add to rtc device
  rtc: remove struct rtc_task
  char: rtc: remove task handling
  rtc: pcf85063: preserve control register value between stop and start
  rtc: sh: remove unused variable rtc_dev
  rtc: unexport rtc_irq_set_*
  rtc: simplify rtc_irq_set_state/rtc_irq_set_freq
  rtc: remove irq_task and irq_task_lock
  rtc: remove rtc_irq_register/rtc_irq_unregister
  rtc: sh: remove dead code
  rtc: sa1100: don't set PIE frequency
  rtc: ds1307: support m41t11 variant
  rtc: ds1307: fix data pointer to m41t0
  ...
  • Loading branch information
torvalds committed Aug 20, 2018
2 parents 3933ec7 + 6b583a6 commit bfebeb1
Show file tree
Hide file tree
Showing 28 changed files with 524 additions and 971 deletions.
29 changes: 29 additions & 0 deletions Documentation/devicetree/bindings/rtc/isil,isl1219.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Intersil ISL1219 I2C RTC/Alarm chip with event in

ISL1219 has additional pins EVIN and #EVDET for tamper detection.

Required properties supported by the device:

- "compatible": must be "isil,isl1219"
- "reg": I2C bus address of the device

Optional properties:

- "interrupt-names": list which may contains "irq" and "evdet"
- "interrupts": list of interrupts for "irq" and "evdet"
- "isil,ev-evienb": if present EV.EVIENB bit is set to the specified
value for proper operation.


Example isl1219 node with #IRQ pin connected to SoC gpio1 pin12
and #EVDET pin connected to SoC gpio2 pin 24:

isl1219: rtc@68 {
compatible = "isil,isl1219";
reg = <0x68>;
interrupt-names = "irq", "evdet";
interrupts-extended = <&gpio1 12 IRQ_TYPE_EDGE_FALLING>,
<&gpio2 24 IRQ_TYPE_EDGE_FALLING>;
isil,ev-evienb = <1>;
};

1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Required properties:
"maxim,ds3231",
"st,m41t0",
"st,m41t00",
"st,m41t11",
"microchip,mcp7940x",
"microchip,mcp7941x",
"pericom,pt7c4338",
Expand Down
13 changes: 0 additions & 13 deletions drivers/char/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,6 @@ static unsigned long rtc_freq; /* Current periodic IRQ rate */
static unsigned long rtc_irq_data; /* our output to the world */
static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */

#ifdef RTC_IRQ
/*
* rtc_task_lock nests inside rtc_lock.
*/
static DEFINE_SPINLOCK(rtc_task_lock);
static rtc_task_t *rtc_callback;
#endif

/*
* If this driver ever becomes modularised, it will be really nice
* to make the epoch retain its value across module reload...
Expand Down Expand Up @@ -264,11 +256,6 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id)

spin_unlock(&rtc_lock);

/* Now do the rest of the actions */
spin_lock(&rtc_task_lock);
if (rtc_callback)
rtc_callback->func(rtc_callback->private_data);
spin_unlock(&rtc_task_lock);
wake_up_interruptible(&rtc_wait);

kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
Expand Down
21 changes: 0 additions & 21 deletions drivers/rtc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -244,15 +244,6 @@ config RTC_DRV_DS1307
This driver can also be built as a module. If so, the module
will be called rtc-ds1307.

config RTC_DRV_DS1307_HWMON
bool "HWMON support for rtc-ds1307"
depends on RTC_DRV_DS1307 && HWMON
depends on !(RTC_DRV_DS1307=y && HWMON=m)
default y
help
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
Expand Down Expand Up @@ -1027,18 +1018,6 @@ config RTC_DS1685_PROC_REGS

Unless you are debugging this driver, choose N.

config RTC_DS1685_SYSFS_REGS
bool "SysFS access to RTC register bits"
depends on RTC_DRV_DS1685_FAMILY && SYSFS
help
Enable this to provide access to the RTC control register bits
in /sys. Some of the bits are read-write, others are read-only.

Keep in mind that reading Control C's bits automatically clears
all pending IRQ flags - this can cause lost interrupts.

If you know that you need access to these bits, choose Y, Else N.

config RTC_DRV_DS1742
tristate "Maxim/Dallas DS1742/1743"
depends on HAS_IOMEM
Expand Down
5 changes: 2 additions & 3 deletions drivers/rtc/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static int rtc_suspend(struct device *dev)
return 0;
}

getnstimeofday64(&old_system);
ktime_get_real_ts64(&old_system);
old_rtc.tv_sec = rtc_tm_to_time64(&tm);


Expand Down Expand Up @@ -110,7 +110,7 @@ static int rtc_resume(struct device *dev)
return 0;

/* snapshot the current rtc and system time at resume */
getnstimeofday64(&new_system);
ktime_get_real_ts64(&new_system);
err = rtc_read_time(rtc, &tm);
if (err < 0) {
pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev));
Expand Down Expand Up @@ -172,7 +172,6 @@ static struct rtc_device *rtc_allocate_device(void)

mutex_init(&rtc->ops_lock);
spin_lock_init(&rtc->irq_lock);
spin_lock_init(&rtc->irq_task_lock);
init_waitqueue_head(&rtc->irq_queue);

/* Init timerqueue */
Expand Down
97 changes: 16 additions & 81 deletions drivers/rtc/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,6 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode);
spin_unlock_irqrestore(&rtc->irq_lock, flags);

/* call the task func */
spin_lock_irqsave(&rtc->irq_task_lock, flags);
if (rtc->irq_task)
rtc->irq_task->func(rtc->irq_task->private_data);
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);

wake_up_interruptible(&rtc->irq_queue);
kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
}
Expand Down Expand Up @@ -721,39 +715,6 @@ void rtc_class_close(struct rtc_device *rtc)
}
EXPORT_SYMBOL_GPL(rtc_class_close);

int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
{
int retval = -EBUSY;

if (task == NULL || task->func == NULL)
return -EINVAL;

/* Cannot register while the char dev is in use */
if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
return -EBUSY;

spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == NULL) {
rtc->irq_task = task;
retval = 0;
}
spin_unlock_irq(&rtc->irq_task_lock);

clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);

return retval;
}
EXPORT_SYMBOL_GPL(rtc_irq_register);

void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
{
spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == task)
rtc->irq_task = NULL;
spin_unlock_irq(&rtc->irq_task_lock);
}
EXPORT_SYMBOL_GPL(rtc_irq_unregister);

static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
{
/*
Expand Down Expand Up @@ -785,71 +746,45 @@ static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
* Context: any
*
* Note that rtc_irq_set_freq() should previously have been used to
* specify the desired frequency of periodic IRQ task->func() callbacks.
* specify the desired frequency of periodic IRQ.
*/
int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
int rtc_irq_set_state(struct rtc_device *rtc, int enabled)
{
int err = 0;
unsigned long flags;

retry:
spin_lock_irqsave(&rtc->irq_task_lock, flags);
if (rtc->irq_task != NULL && task == NULL)
err = -EBUSY;
else if (rtc->irq_task != task)
err = -EACCES;
else {
if (rtc_update_hrtimer(rtc, enabled) < 0) {
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
cpu_relax();
goto retry;
}
rtc->pie_enabled = enabled;
}
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
while (rtc_update_hrtimer(rtc, enabled) < 0)
cpu_relax();

rtc->pie_enabled = enabled;

trace_rtc_irq_set_state(enabled, err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_irq_set_state);

/**
* 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 with which task->func() will be called
* @freq: positive frequency
* Context: any
*
* Note that rtc_irq_set_state() is used to enable or disable the
* periodic IRQs.
*/
int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
int rtc_irq_set_freq(struct rtc_device *rtc, int freq)
{
int err = 0;
unsigned long flags;

if (freq <= 0 || freq > RTC_MAX_FREQ)
return -EINVAL;
retry:
spin_lock_irqsave(&rtc->irq_task_lock, flags);
if (rtc->irq_task != NULL && task == NULL)
err = -EBUSY;
else if (rtc->irq_task != task)
err = -EACCES;
else {
rtc->irq_freq = freq;
if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
cpu_relax();
goto retry;
}
}
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);

rtc->irq_freq = freq;
while (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0)
cpu_relax();

trace_rtc_irq_set_freq(freq, err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_irq_set_freq);

/**
* rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue
Expand Down Expand Up @@ -979,8 +914,8 @@ void rtc_timer_do_work(struct work_struct *work)
timerqueue_del(&rtc->timerqueue, &timer->node);
trace_rtc_timer_dequeue(timer);
timer->enabled = 0;
if (timer->task.func)
timer->task.func(timer->task.private_data);
if (timer->func)
timer->func(timer->private_data);

trace_rtc_timer_fired(timer);
/* Re-add/fwd periodic timers */
Expand Down Expand Up @@ -1035,8 +970,8 @@ void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data)
{
timerqueue_init(&timer->node);
timer->enabled = 0;
timer->task.func = f;
timer->task.private_data = data;
timer->func = f;
timer->private_data = data;
}

/* rtc_timer_start - Sets an rtc_timer to fire in the future
Expand Down
23 changes: 23 additions & 0 deletions drivers/rtc/rtc-armada38x.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#define RTC_IRQ_FREQ_1HZ BIT(2)
#define RTC_CCR 0x18
#define RTC_CCR_MODE BIT(15)
#define RTC_CONF_TEST 0x1C
#define RTC_NOMINAL_TIMING BIT(13)

#define RTC_TIME 0xC
#define RTC_ALARM1 0x10
Expand Down Expand Up @@ -75,6 +77,7 @@ struct armada38x_rtc {
void __iomem *regs_soc;
spinlock_t lock;
int irq;
bool initialized;
struct value_to_freq *val_to_freq;
struct armada38x_rtc_data *data;
};
Expand Down Expand Up @@ -226,6 +229,23 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
return 0;
}

static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
{
u32 reg;

reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST);
/* If bits [7:0] are non-zero, assume RTC was uninitialized */
if (reg & 0xff) {
rtc_delayed_write(0, rtc, RTC_CONF_TEST);
msleep(500); /* Oscillator startup time */
rtc_delayed_write(0, rtc, RTC_TIME);
rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc,
RTC_STATUS);
rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR);
}
rtc->initialized = true;
}

static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
Expand All @@ -237,6 +257,9 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (ret)
goto out;

if (!rtc->initialized)
armada38x_rtc_reset(rtc);

spin_lock_irqsave(&rtc->lock, flags);
rtc_delayed_write(time, rtc, RTC_TIME);
spin_unlock_irqrestore(&rtc->lock, flags);
Expand Down
4 changes: 4 additions & 0 deletions drivers/rtc/rtc-bq4802.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ static int bq4802_probe(struct platform_device *pdev)
} else if (p->r->flags & IORESOURCE_MEM) {
p->regs = devm_ioremap(&pdev->dev, p->r->start,
resource_size(p->r));
if (!p->regs){
err = -ENOMEM;
goto out;
}
p->read = bq4802_read_mem;
p->write = bq4802_write_mem;
} else {
Expand Down
14 changes: 14 additions & 0 deletions drivers/rtc/rtc-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,23 @@ 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
Loading

0 comments on commit bfebeb1

Please sign in to comment.