aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorMarcin Niestroj <m.niestroj@grinn-global.com>2016-09-16 05:26:28 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-09-21 15:46:04 -0400
commit97ea1906b3c2201273ea6bb40c43c611c056ddb3 (patch)
tree71548d748629fe2f6b63e2ea9b92b007a6bbdeb9 /drivers/rtc
parent970fc7f4afd52d638d88aeda985ea03ccd33acee (diff)
rtc: omap: Support ext_wakeup configuration
Support configuration of ext_wakeup sources. This patch makes it possible to enable ext_wakeup and set it's polarity, depending on board configuration. AM335x's dedicated PMIC (tps65217) uses ext_wakeup to notify about power-button presses. Handling power-button presses enables to recover from RTC-only power states correctly. Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig3
-rw-r--r--drivers/rtc/rtc-omap.c168
2 files changed, 163 insertions, 8 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 896302a0d4b9..531343a260f8 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1245,6 +1245,9 @@ config RTC_DRV_IMXDI
1245config RTC_DRV_OMAP 1245config RTC_DRV_OMAP
1246 tristate "TI OMAP Real Time Clock" 1246 tristate "TI OMAP Real Time Clock"
1247 depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST 1247 depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
1248 depends on OF
1249 depends on PINCTRL
1250 select GENERIC_PINCONF
1248 help 1251 help
1249 Say "yes" here to support the on chip real time clock 1252 Say "yes" here to support the on chip real time clock
1250 present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. 1253 present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx.
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index cadac8e2aa6b..b04ea9b5ae67 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -13,19 +13,23 @@
13 * 2 of the License, or (at your option) any later version. 13 * 2 of the License, or (at your option) any later version.
14 */ 14 */
15 15
16#include <linux/kernel.h> 16#include <dt-bindings/gpio/gpio.h>
17#include <linux/bcd.h>
18#include <linux/clk.h>
19#include <linux/delay.h>
17#include <linux/init.h> 20#include <linux/init.h>
18#include <linux/module.h> 21#include <linux/io.h>
19#include <linux/ioport.h> 22#include <linux/ioport.h>
20#include <linux/delay.h> 23#include <linux/kernel.h>
21#include <linux/rtc.h> 24#include <linux/module.h>
22#include <linux/bcd.h>
23#include <linux/platform_device.h>
24#include <linux/of.h> 25#include <linux/of.h>
25#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/pinctrl/pinctrl.h>
28#include <linux/pinctrl/pinconf.h>
29#include <linux/pinctrl/pinconf-generic.h>
30#include <linux/platform_device.h>
26#include <linux/pm_runtime.h> 31#include <linux/pm_runtime.h>
27#include <linux/io.h> 32#include <linux/rtc.h>
28#include <linux/clk.h>
29 33
30/* 34/*
31 * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock 35 * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
@@ -115,6 +119,8 @@
115 119
116/* OMAP_RTC_PMIC bit fields: */ 120/* OMAP_RTC_PMIC bit fields: */
117#define OMAP_RTC_PMIC_POWER_EN_EN BIT(16) 121#define OMAP_RTC_PMIC_POWER_EN_EN BIT(16)
122#define OMAP_RTC_PMIC_EXT_WKUP_EN(x) BIT(x)
123#define OMAP_RTC_PMIC_EXT_WKUP_POL(x) BIT(4 + x)
118 124
119/* OMAP_RTC_KICKER values */ 125/* OMAP_RTC_KICKER values */
120#define KICK0_VALUE 0x83e70b13 126#define KICK0_VALUE 0x83e70b13
@@ -141,6 +147,7 @@ struct omap_rtc {
141 bool is_pmic_controller; 147 bool is_pmic_controller;
142 bool has_ext_clk; 148 bool has_ext_clk;
143 const struct omap_rtc_device_type *type; 149 const struct omap_rtc_device_type *type;
150 struct pinctrl_dev *pctldev;
144}; 151};
145 152
146static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg) 153static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg)
@@ -525,6 +532,139 @@ static const struct of_device_id omap_rtc_of_match[] = {
525}; 532};
526MODULE_DEVICE_TABLE(of, omap_rtc_of_match); 533MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
527 534
535static const struct pinctrl_pin_desc rtc_pins_desc[] = {
536 PINCTRL_PIN(0, "ext_wakeup0"),
537 PINCTRL_PIN(1, "ext_wakeup1"),
538 PINCTRL_PIN(2, "ext_wakeup2"),
539 PINCTRL_PIN(3, "ext_wakeup3"),
540};
541
542static int rtc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
543{
544 return 0;
545}
546
547static const char *rtc_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
548 unsigned int group)
549{
550 return NULL;
551}
552
553static const struct pinctrl_ops rtc_pinctrl_ops = {
554 .get_groups_count = rtc_pinctrl_get_groups_count,
555 .get_group_name = rtc_pinctrl_get_group_name,
556 .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
557 .dt_free_map = pinconf_generic_dt_free_map,
558};
559
560enum rtc_pin_config_param {
561 PIN_CONFIG_ACTIVE_HIGH = PIN_CONFIG_END + 1,
562};
563
564static const struct pinconf_generic_params rtc_params[] = {
565 {"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
566};
567
568#ifdef CONFIG_DEBUG_FS
569static const struct pin_config_item rtc_conf_items[ARRAY_SIZE(rtc_params)] = {
570 PCONFDUMP(PIN_CONFIG_ACTIVE_HIGH, "input active high", NULL, false),
571};
572#endif
573
574static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
575 unsigned int pin, unsigned long *config)
576{
577 struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
578 unsigned int param = pinconf_to_config_param(*config);
579 u32 val;
580 u16 arg = 0;
581
582 rtc->type->unlock(rtc);
583 val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
584 rtc->type->lock(rtc);
585
586 switch (param) {
587 case PIN_CONFIG_INPUT_ENABLE:
588 if (!(val & OMAP_RTC_PMIC_EXT_WKUP_EN(pin)))
589 return -EINVAL;
590 break;
591 case PIN_CONFIG_ACTIVE_HIGH:
592 if (val & OMAP_RTC_PMIC_EXT_WKUP_POL(pin))
593 return -EINVAL;
594 break;
595 default:
596 return -ENOTSUPP;
597 };
598
599 *config = pinconf_to_config_packed(param, arg);
600
601 return 0;
602}
603
604static int rtc_pinconf_set(struct pinctrl_dev *pctldev,
605 unsigned int pin, unsigned long *configs,
606 unsigned int num_configs)
607{
608 struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
609 u32 val;
610 unsigned int param;
611 u16 param_val;
612 int i;
613
614 rtc->type->unlock(rtc);
615 val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
616 rtc->type->lock(rtc);
617
618 /* active low by default */
619 val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
620
621 for (i = 0; i < num_configs; i++) {
622 param = pinconf_to_config_param(configs[i]);
623 param_val = pinconf_to_config_argument(configs[i]);
624
625 switch (param) {
626 case PIN_CONFIG_INPUT_ENABLE:
627 if (param_val)
628 val |= OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
629 else
630 val &= ~OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
631 break;
632 case PIN_CONFIG_ACTIVE_HIGH:
633 val &= ~OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
634 break;
635 default:
636 dev_err(&rtc->rtc->dev, "Property %u not supported\n",
637 param);
638 return -ENOTSUPP;
639 }
640 }
641
642 rtc->type->unlock(rtc);
643 rtc_writel(rtc, OMAP_RTC_PMIC_REG, val);
644 rtc->type->lock(rtc);
645
646 return 0;
647}
648
649static const struct pinconf_ops rtc_pinconf_ops = {
650 .is_generic = true,
651 .pin_config_get = rtc_pinconf_get,
652 .pin_config_set = rtc_pinconf_set,
653};
654
655static struct pinctrl_desc rtc_pinctrl_desc = {
656 .pins = rtc_pins_desc,
657 .npins = ARRAY_SIZE(rtc_pins_desc),
658 .pctlops = &rtc_pinctrl_ops,
659 .confops = &rtc_pinconf_ops,
660 .custom_params = rtc_params,
661 .num_custom_params = ARRAY_SIZE(rtc_params),
662#ifdef CONFIG_DEBUG_FS
663 .custom_conf_items = rtc_conf_items,
664#endif
665 .owner = THIS_MODULE,
666};
667
528static int omap_rtc_probe(struct platform_device *pdev) 668static int omap_rtc_probe(struct platform_device *pdev)
529{ 669{
530 struct omap_rtc *rtc; 670 struct omap_rtc *rtc;
@@ -681,6 +821,15 @@ static int omap_rtc_probe(struct platform_device *pdev)
681 } 821 }
682 } 822 }
683 823
824 /* Support ext_wakeup pinconf */
825 rtc_pinctrl_desc.name = dev_name(&pdev->dev);
826
827 rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc);
828 if (IS_ERR(rtc->pctldev)) {
829 dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
830 return PTR_ERR(rtc->pctldev);
831 }
832
684 return 0; 833 return 0;
685 834
686err: 835err:
@@ -724,6 +873,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
724 pm_runtime_put_sync(&pdev->dev); 873 pm_runtime_put_sync(&pdev->dev);
725 pm_runtime_disable(&pdev->dev); 874 pm_runtime_disable(&pdev->dev);
726 875
876 /* Remove ext_wakeup pinconf */
877 pinctrl_unregister(rtc->pctldev);
878
727 return 0; 879 return 0;
728} 880}
729 881