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@xxxxxxxxxxxxxxxx> --- Documentation/devicetree/bindings/rtc/rtc-omap.txt | 24 ++++++++++- drivers/rtc/rtc-omap.c | 46 +++++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/rtc/rtc-omap.txt b/Documentation/devicetree/bindings/rtc/rtc-omap.txt index bf7d11a..1c05311b 100644 --- a/Documentation/devicetree/bindings/rtc/rtc-omap.txt +++ b/Documentation/devicetree/bindings/rtc/rtc-omap.txt @@ -18,8 +18,20 @@ Optional properties: through pmic_power_en - clocks: Any internal or external clocks feeding in to rtc - clock-names: Corresponding names of the clocks +- ti,ext-wakeup-en: Enables ext_wakeup[n] sources. Value determines which + ext_wakeup is enabled by bitwise OR of corresponding bits. + Examples: + <1> - enabled ext_wakeup[0], + <2> - enabled ext_wakeup[1], + <3> - enabled ext_wakeup[0] and enabled ext_wakeup[1], + ... +- ti,ext-wakeup-pol: Sets polarity of ext_wakeup[n] sources, similarly as + above. Set bit means active-low, unset bit means + active-high. Examples: + <1> - only ext_wakeup0 is active-low + <3> - only ext_wakeup0 and ext_wakeup1 are active-low -Example: +Examples: rtc@1c23000 { compatible = "ti,da830-rtc"; @@ -31,3 +43,13 @@ rtc@1c23000 { clocks = <&clk_32k_rtc>, <&clk_32768_ck>; clock-names = "ext-clk", "int-clk"; }; + +rtc@44e3e000 { + compatible = "ti,am3352-rtc", "ti,da830-rtc"; + reg = <0x44e3e000 0x1000>; + interrupts = <75 + 76>; + system-power-controller; + ti,ext-wakeup-en = <1>; + ti,ext-wakeup-pol = <1>; +}; diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index ec2e9c5..1a46f5d 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -114,7 +114,11 @@ #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) /* OMAP_RTC_PMIC bit fields: */ -#define OMAP_RTC_PMIC_POWER_EN_EN BIT(16) +#define OMAP_RTC_PMIC_POWER_EN_EN BIT(16) +#define OMAP_RTC_PMIC_EXT_WAKEUP_EN(x) (x) +#define OMAP_RTC_PMIC_EXT_WAKEUP_POL(x) ((x) << 4) +#define OMAP_RTC_PMIC_EXT_WAKEUP_EN_MASK 0x0F +#define OMAP_RTC_PMIC_EXT_WAKEUP_POL_MASK 0xF0 /* OMAP_RTC_KICKER values */ #define KICK0_VALUE 0x83e70b13 @@ -533,6 +537,11 @@ static int omap_rtc_probe(struct platform_device *pdev) const struct platform_device_id *id_entry; const struct of_device_id *of_id; int ret; + u32 ext_wakeup_en; + u32 ext_wakeup_pol; + bool has_ext_wakeup_en; + bool has_ext_wakeup_pol; + u32 val; rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) @@ -544,6 +553,30 @@ static int omap_rtc_probe(struct platform_device *pdev) rtc->is_pmic_controller = rtc->type->has_pmic_mode && of_property_read_bool(pdev->dev.of_node, "system-power-controller"); + if (of_property_read_u32(pdev->dev.of_node, + "ti,ext-wakeup-en", + &ext_wakeup_en) >= 0) { + if (ext_wakeup_en < BIT(4)) + has_ext_wakeup_en = true; + else + dev_err(&pdev->dev, + "wrong ext-wakeup-en value\n"); + } else { + dev_err(&pdev->dev, + "no ext-wakeup-en\n"); + } + if (of_property_read_u32(pdev->dev.of_node, + "ti,ext-wakeup-pol", + &ext_wakeup_pol) >= 0) { + if (ext_wakeup_pol < BIT(4)) + has_ext_wakeup_pol = true; + else + dev_err(&pdev->dev, + "wrong ext-wakeup-pol value\n"); + } else { + dev_err(&pdev->dev, + "no ext-wakeup-pol\n"); + } } else { id_entry = platform_get_device_id(pdev); rtc->type = (void *)id_entry->driver_data; @@ -650,6 +683,17 @@ static int omap_rtc_probe(struct platform_device *pdev) reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); } + if (has_ext_wakeup_en || has_ext_wakeup_pol) { + val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); + if (has_ext_wakeup_en) + val = (val & ~OMAP_RTC_PMIC_EXT_WAKEUP_EN_MASK) + | OMAP_RTC_PMIC_EXT_WAKEUP_EN(ext_wakeup_en); + if (has_ext_wakeup_pol) + val = (val & ~OMAP_RTC_PMIC_EXT_WAKEUP_POL_MASK) + | OMAP_RTC_PMIC_EXT_WAKEUP_POL(ext_wakeup_pol); + rtc_writel(rtc, OMAP_RTC_PMIC_REG, val); + } + rtc->type->lock(rtc); device_init_wakeup(&pdev->dev, true); -- 2.8.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html