Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: pcf85063: add RTC_VL_READ/RTC_VL_CLR support

Allow reading the oscillator status bit. Also allow clearing it even if
that makes little sense and can't be done in a race free way.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

+35
+35
drivers/rtc/rtc-pcf85063.c
··· 277 277 return regmap_write(pcf85063->regmap, PCF85063_REG_OFFSET, reg); 278 278 } 279 279 280 + static int pcf85063_ioctl(struct device *dev, unsigned int cmd, 281 + unsigned long arg) 282 + { 283 + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); 284 + int status, ret = 0; 285 + 286 + switch (cmd) { 287 + case RTC_VL_READ: 288 + ret = regmap_read(pcf85063->regmap, PCF85063_REG_SC, &status); 289 + if (ret < 0) 290 + return ret; 291 + 292 + if (status & PCF85063_REG_SC_OS) 293 + dev_warn(&pcf85063->rtc->dev, "Voltage low, data loss detected.\n"); 294 + 295 + status &= PCF85063_REG_SC_OS; 296 + 297 + if (copy_to_user((void __user *)arg, &status, sizeof(int))) 298 + return -EFAULT; 299 + 300 + return 0; 301 + 302 + case RTC_VL_CLR: 303 + ret = regmap_update_bits(pcf85063->regmap, PCF85063_REG_SC, 304 + PCF85063_REG_SC_OS, 0); 305 + 306 + return ret; 307 + 308 + default: 309 + return -ENOIOCTLCMD; 310 + } 311 + } 312 + 280 313 static const struct rtc_class_ops pcf85063_rtc_ops = { 281 314 .read_time = pcf85063_rtc_read_time, 282 315 .set_time = pcf85063_rtc_set_time, 283 316 .read_offset = pcf85063_read_offset, 284 317 .set_offset = pcf85063_set_offset, 318 + .ioctl = pcf85063_ioctl, 285 319 }; 286 320 287 321 static const struct rtc_class_ops pcf85063_rtc_ops_alarm = { ··· 326 292 .read_alarm = pcf85063_rtc_read_alarm, 327 293 .set_alarm = pcf85063_rtc_set_alarm, 328 294 .alarm_irq_enable = pcf85063_rtc_alarm_irq_enable, 295 + .ioctl = pcf85063_ioctl, 329 296 }; 330 297 331 298 static int pcf85063_nvmem_read(void *priv, unsigned int offset,