diff options
Diffstat (limited to 'drivers/rtc/rtc-omap.c')
| -rw-r--r-- | drivers/rtc/rtc-omap.c | 38 | 
1 files changed, 30 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index b04ea9b5ae67..51e52446eacb 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -113,6 +113,7 @@  /* OMAP_RTC_OSC_REG bit fields: */  #define OMAP_RTC_OSC_32KCLK_EN		BIT(6)  #define OMAP_RTC_OSC_SEL_32KCLK_SRC	BIT(3) +#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE	BIT(4)  /* OMAP_RTC_IRQWAKEEN bit fields: */  #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN	BIT(1) @@ -146,6 +147,7 @@ struct omap_rtc {  	u8 interrupts_reg;  	bool is_pmic_controller;  	bool has_ext_clk; +	bool is_suspending;  	const struct omap_rtc_device_type *type;  	struct pinctrl_dev *pctldev;  }; @@ -786,8 +788,9 @@ static int omap_rtc_probe(struct platform_device *pdev)  	 */  	if (rtc->has_ext_clk) {  		reg = rtc_read(rtc, OMAP_RTC_OSC_REG); -		rtc_write(rtc, OMAP_RTC_OSC_REG, -			  reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); +		reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE; +		reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC; +		rtc_writel(rtc, OMAP_RTC_OSC_REG, reg);  	}  	rtc->type->lock(rtc); @@ -898,8 +901,7 @@ static int omap_rtc_suspend(struct device *dev)  		rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);  	rtc->type->lock(rtc); -	/* Disable the clock/module */ -	pm_runtime_put_sync(dev); +	rtc->is_suspending = true;  	return 0;  } @@ -908,9 +910,6 @@ static int omap_rtc_resume(struct device *dev)  {  	struct omap_rtc *rtc = dev_get_drvdata(dev); -	/* Enable the clock/module so that we can access the registers */ -	pm_runtime_get_sync(dev); -  	rtc->type->unlock(rtc);  	if (device_may_wakeup(dev))  		disable_irq_wake(rtc->irq_alarm); @@ -918,11 +917,34 @@ static int omap_rtc_resume(struct device *dev)  		rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg);  	rtc->type->lock(rtc); +	rtc->is_suspending = false; +  	return 0;  }  #endif -static SIMPLE_DEV_PM_OPS(omap_rtc_pm_ops, omap_rtc_suspend, omap_rtc_resume); +#ifdef CONFIG_PM +static int omap_rtc_runtime_suspend(struct device *dev) +{ +	struct omap_rtc *rtc = dev_get_drvdata(dev); + +	if (rtc->is_suspending && !rtc->has_ext_clk) +		return -EBUSY; + +	return 0; +} + +static int omap_rtc_runtime_resume(struct device *dev) +{ +	return 0; +} +#endif + +static const struct dev_pm_ops omap_rtc_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(omap_rtc_suspend, omap_rtc_resume) +	SET_RUNTIME_PM_OPS(omap_rtc_runtime_suspend, +			   omap_rtc_runtime_resume, NULL) +};  static void omap_rtc_shutdown(struct platform_device *pdev)  {  | 
