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

soc: ti: pm33xx: Simplify RTC usage to prepare to drop platform data

We must re-enable the RTC module clock enabled in RTC+DDR suspend, and
pm33xx has been using platform data callbacks for that. Looks like for
retention suspend the RTC module clock must not be re-enabled.

To remove the legacy platform data callbacks, and eventually be able to
drop the RTC legacy platform data, let's manage the RTC module clock
and register range directly in pm33xx.

Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>

+42 -33
-25
arch/arm/mach-omap2/pm33xx-core.c
··· 25 25 #include "control.h" 26 26 #include "clockdomain.h" 27 27 #include "iomap.h" 28 - #include "omap_hwmod.h" 29 28 #include "pm.h" 30 29 #include "powerdomain.h" 31 30 #include "prm33xx.h" ··· 35 36 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm; 36 37 static struct clockdomain *gfx_l4ls_clkdm; 37 38 static void __iomem *scu_base; 38 - static struct omap_hwmod *rtc_oh; 39 39 40 40 static int (*idle_fn)(u32 wfi_flags); 41 41 ··· 265 267 return NULL; 266 268 } 267 269 268 - static void __iomem *am43xx_get_rtc_base_addr(void) 269 - { 270 - rtc_oh = omap_hwmod_lookup("rtc"); 271 - 272 - return omap_hwmod_get_mpu_rt_va(rtc_oh); 273 - } 274 - 275 270 static void am43xx_save_context(void) 276 271 { 277 272 } ··· 288 297 writel_relaxed(0x0, AM33XX_L4_WK_IO_ADDRESS(0x44df2e14)); 289 298 } 290 299 291 - static void am43xx_prepare_rtc_suspend(void) 292 - { 293 - omap_hwmod_enable(rtc_oh); 294 - } 295 - 296 - static void am43xx_prepare_rtc_resume(void) 297 - { 298 - omap_hwmod_idle(rtc_oh); 299 - } 300 - 301 300 static struct am33xx_pm_platform_data am33xx_ops = { 302 301 .init = am33xx_suspend_init, 303 302 .deinit = amx3_suspend_deinit, ··· 298 317 .get_sram_addrs = amx3_get_sram_addrs, 299 318 .save_context = am33xx_save_context, 300 319 .restore_context = am33xx_restore_context, 301 - .prepare_rtc_suspend = am43xx_prepare_rtc_suspend, 302 - .prepare_rtc_resume = am43xx_prepare_rtc_resume, 303 320 .check_off_mode_enable = am33xx_check_off_mode_enable, 304 - .get_rtc_base_addr = am43xx_get_rtc_base_addr, 305 321 }; 306 322 307 323 static struct am33xx_pm_platform_data am43xx_ops = { ··· 311 333 .get_sram_addrs = amx3_get_sram_addrs, 312 334 .save_context = am43xx_save_context, 313 335 .restore_context = am43xx_restore_context, 314 - .prepare_rtc_suspend = am43xx_prepare_rtc_suspend, 315 - .prepare_rtc_resume = am43xx_prepare_rtc_resume, 316 336 .check_off_mode_enable = am43xx_check_off_mode_enable, 317 - .get_rtc_base_addr = am43xx_get_rtc_base_addr, 318 337 }; 319 338 320 339 static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
+42 -5
drivers/soc/ti/pm33xx.c
··· 16 16 #include <linux/module.h> 17 17 #include <linux/nvmem-consumer.h> 18 18 #include <linux/of.h> 19 + #include <linux/of_address.h> 19 20 #include <linux/platform_data/pm33xx.h> 20 21 #include <linux/platform_device.h> 21 22 #include <linux/rtc.h> ··· 40 39 #define GIC_INT_SET_PENDING_BASE 0x200 41 40 #define AM43XX_GIC_DIST_BASE 0x48241000 42 41 42 + static void __iomem *rtc_base_virt; 43 + static struct clk *rtc_fck; 43 44 static u32 rtc_magic_val; 44 45 45 46 static int (*am33xx_do_wfi_sram)(unsigned long unused); ··· 93 90 ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data; 94 91 ro_sram_data.amx3_pm_sram_data_phys = 95 92 gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data); 96 - ro_sram_data.rtc_base_virt = pm_ops->get_rtc_base_addr(); 93 + ro_sram_data.rtc_base_virt = rtc_base_virt; 97 94 98 95 /* Save physical address to calculate resume offset during pm init */ 99 96 am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool, ··· 161 158 { 162 159 u32 i; 163 160 164 - i = __raw_readl(pm_ops->get_rtc_base_addr() + 0x44) & 0x40; 161 + i = __raw_readl(rtc_base_virt + 0x44) & 0x40; 165 162 166 163 if (i) { 167 164 retrigger_irq = rtc_alarm_wakeup.irq_nr; ··· 180 177 return 0; 181 178 } 182 179 180 + /* 181 + * Note that the RTC module clock must be re-enabled only for rtc+ddr suspend. 182 + * And looks like the module can stay in SYSC_IDLE_SMART_WKUP mode configured 183 + * by the interconnect code just fine for both rtc+ddr suspend and retention 184 + * suspend. 185 + */ 183 186 static int am33xx_pm_suspend(suspend_state_t suspend_state) 184 187 { 185 188 int i, ret = 0; 186 189 187 190 if (suspend_state == PM_SUSPEND_MEM && 188 191 pm_ops->check_off_mode_enable()) { 189 - pm_ops->prepare_rtc_suspend(); 192 + ret = clk_prepare_enable(rtc_fck); 193 + if (ret) { 194 + dev_err(pm33xx_dev, "Failed to enable clock: %i\n", ret); 195 + return ret; 196 + } 197 + 190 198 pm_ops->save_context(); 191 199 suspend_wfi_flags |= WFI_FLAG_RTC_ONLY; 192 200 clk_save_context(); ··· 250 236 } 251 237 252 238 if (suspend_state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) 253 - pm_ops->prepare_rtc_resume(); 239 + clk_disable_unprepare(rtc_fck); 254 240 255 241 return ret; 256 242 } ··· 439 425 struct device_node *np; 440 426 unsigned long val = 0; 441 427 struct nvmem_device *nvmem; 428 + int error; 442 429 443 430 np = of_find_node_by_name(NULL, "rtc"); 444 431 445 432 if (of_device_is_available(np)) { 433 + /* RTC interconnect target module clock */ 434 + rtc_fck = of_clk_get_by_name(np->parent, "fck"); 435 + if (IS_ERR(rtc_fck)) 436 + return PTR_ERR(rtc_fck); 437 + 438 + rtc_base_virt = of_iomap(np, 0); 439 + if (!rtc_base_virt) { 440 + pr_warn("PM: could not iomap rtc"); 441 + error = -ENODEV; 442 + goto err_clk_put; 443 + } 444 + 446 445 omap_rtc = rtc_class_open("rtc0"); 447 446 if (!omap_rtc) { 448 447 pr_warn("PM: rtc0 not available"); 449 - return -EPROBE_DEFER; 448 + error = -EPROBE_DEFER; 449 + goto err_iounmap; 450 450 } 451 451 452 452 nvmem = devm_nvmem_device_get(&omap_rtc->dev, ··· 482 454 } 483 455 484 456 return 0; 457 + 458 + err_iounmap: 459 + iounmap(rtc_base_virt); 460 + err_clk_put: 461 + clk_put(rtc_fck); 462 + 463 + return error; 485 464 } 486 465 487 466 static int am33xx_pm_probe(struct platform_device *pdev) ··· 579 544 suspend_set_ops(NULL); 580 545 wkup_m3_ipc_put(m3_ipc); 581 546 am33xx_pm_free_sram(); 547 + iounmap(rtc_base_virt); 548 + clk_put(rtc_fck); 582 549 return 0; 583 550 } 584 551
-3
include/linux/platform_data/pm33xx.h
··· 54 54 void (*begin_suspend)(void); 55 55 void (*finish_suspend)(void); 56 56 struct am33xx_pm_sram_addr *(*get_sram_addrs)(void); 57 - void __iomem *(*get_rtc_base_addr)(void); 58 57 void (*save_context)(void); 59 58 void (*restore_context)(void); 60 - void (*prepare_rtc_suspend)(void); 61 - void (*prepare_rtc_resume)(void); 62 59 int (*check_off_mode_enable)(void); 63 60 }; 64 61