aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-pm8xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-pm8xxx.c')
-rw-r--r--drivers/rtc/rtc-pm8xxx.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 91ac2e346aea..6e3cd345379d 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -9,7 +9,7 @@
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details. 10 * GNU General Public License for more details.
11 */ 11 */
12 12#include <linux/of.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
@@ -19,9 +19,6 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21 21
22#include <linux/mfd/pm8xxx/rtc.h>
23
24
25/* RTC Register offsets from RTC CTRL REG */ 22/* RTC Register offsets from RTC CTRL REG */
26#define PM8XXX_ALARM_CTRL_OFFSET 0x01 23#define PM8XXX_ALARM_CTRL_OFFSET 0x01
27#define PM8XXX_RTC_WRITE_OFFSET 0x02 24#define PM8XXX_RTC_WRITE_OFFSET 0x02
@@ -39,6 +36,7 @@
39 * struct pm8xxx_rtc - rtc driver internal structure 36 * struct pm8xxx_rtc - rtc driver internal structure
40 * @rtc: rtc device for this driver. 37 * @rtc: rtc device for this driver.
41 * @regmap: regmap used to access RTC registers 38 * @regmap: regmap used to access RTC registers
39 * @allow_set_time: indicates whether writing to the RTC is allowed
42 * @rtc_alarm_irq: rtc alarm irq number. 40 * @rtc_alarm_irq: rtc alarm irq number.
43 * @rtc_base: address of rtc control register. 41 * @rtc_base: address of rtc control register.
44 * @rtc_read_base: base address of read registers. 42 * @rtc_read_base: base address of read registers.
@@ -51,6 +49,7 @@
51struct pm8xxx_rtc { 49struct pm8xxx_rtc {
52 struct rtc_device *rtc; 50 struct rtc_device *rtc;
53 struct regmap *regmap; 51 struct regmap *regmap;
52 bool allow_set_time;
54 int rtc_alarm_irq; 53 int rtc_alarm_irq;
55 int rtc_base; 54 int rtc_base;
56 int rtc_read_base; 55 int rtc_read_base;
@@ -75,6 +74,9 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
75 u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, ctrl_reg; 74 u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, ctrl_reg;
76 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); 75 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
77 76
77 if (!rtc_dd->allow_set_time)
78 return -EACCES;
79
78 rtc_tm_to_time(tm, &secs); 80 rtc_tm_to_time(tm, &secs);
79 81
80 for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { 82 for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) {
@@ -298,8 +300,9 @@ rtc_rw_fail:
298 return rc; 300 return rc;
299} 301}
300 302
301static struct rtc_class_ops pm8xxx_rtc_ops = { 303static const struct rtc_class_ops pm8xxx_rtc_ops = {
302 .read_time = pm8xxx_rtc_read_time, 304 .read_time = pm8xxx_rtc_read_time,
305 .set_time = pm8xxx_rtc_set_time,
303 .set_alarm = pm8xxx_rtc_set_alarm, 306 .set_alarm = pm8xxx_rtc_set_alarm,
304 .read_alarm = pm8xxx_rtc_read_alarm, 307 .read_alarm = pm8xxx_rtc_read_alarm,
305 .alarm_irq_enable = pm8xxx_rtc_alarm_irq_enable, 308 .alarm_irq_enable = pm8xxx_rtc_alarm_irq_enable,
@@ -353,18 +356,26 @@ rtc_alarm_handled:
353 return IRQ_HANDLED; 356 return IRQ_HANDLED;
354} 357}
355 358
359/*
360 * Hardcoded RTC bases until IORESOURCE_REG mapping is figured out
361 */
362static const struct of_device_id pm8xxx_id_table[] = {
363 { .compatible = "qcom,pm8921-rtc", .data = (void *) 0x11D },
364 { .compatible = "qcom,pm8058-rtc", .data = (void *) 0x1E8 },
365 { },
366};
367MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
368
356static int pm8xxx_rtc_probe(struct platform_device *pdev) 369static int pm8xxx_rtc_probe(struct platform_device *pdev)
357{ 370{
358 int rc; 371 int rc;
359 unsigned int ctrl_reg; 372 unsigned int ctrl_reg;
360 bool rtc_write_enable = false;
361 struct pm8xxx_rtc *rtc_dd; 373 struct pm8xxx_rtc *rtc_dd;
362 struct resource *rtc_resource; 374 const struct of_device_id *match;
363 const struct pm8xxx_rtc_platform_data *pdata =
364 dev_get_platdata(&pdev->dev);
365 375
366 if (pdata != NULL) 376 match = of_match_node(pm8xxx_id_table, pdev->dev.of_node);
367 rtc_write_enable = pdata->rtc_write_enable; 377 if (!match)
378 return -ENXIO;
368 379
369 rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL); 380 rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL);
370 if (rtc_dd == NULL) 381 if (rtc_dd == NULL)
@@ -385,14 +396,10 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
385 return -ENXIO; 396 return -ENXIO;
386 } 397 }
387 398
388 rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO, 399 rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node,
389 "pmic_rtc_base"); 400 "allow-set-time");
390 if (!(rtc_resource && rtc_resource->start)) {
391 dev_err(&pdev->dev, "RTC IO resource absent!\n");
392 return -ENXIO;
393 }
394 401
395 rtc_dd->rtc_base = rtc_resource->start; 402 rtc_dd->rtc_base = (long) match->data;
396 403
397 /* Setup RTC register addresses */ 404 /* Setup RTC register addresses */
398 rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET; 405 rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET;
@@ -419,8 +426,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
419 } 426 }
420 427
421 rtc_dd->ctrl_reg = ctrl_reg; 428 rtc_dd->ctrl_reg = ctrl_reg;
422 if (rtc_write_enable)
423 pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time;
424 429
425 platform_set_drvdata(pdev, rtc_dd); 430 platform_set_drvdata(pdev, rtc_dd);
426 431
@@ -479,9 +484,10 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops,
479static struct platform_driver pm8xxx_rtc_driver = { 484static struct platform_driver pm8xxx_rtc_driver = {
480 .probe = pm8xxx_rtc_probe, 485 .probe = pm8xxx_rtc_probe,
481 .driver = { 486 .driver = {
482 .name = PM8XXX_RTC_DEV_NAME, 487 .name = "rtc-pm8xxx",
483 .owner = THIS_MODULE, 488 .owner = THIS_MODULE,
484 .pm = &pm8xxx_rtc_pm_ops, 489 .pm = &pm8xxx_rtc_pm_ops,
490 .of_match_table = pm8xxx_id_table,
485 }, 491 },
486}; 492};
487 493