static int am33xx_pm_suspend(void) { int state, ret = 0; struct omap_hwmod *cpgmac_oh, *gpmc_oh, *usb_oh; cpgmac_oh = omap_hwmod_lookup("cpgmac0"); usb_oh = omap_hwmod_lookup("usb_otg_hs"); gpmc_oh = omap_hwmod_lookup("gpmc"); omap_hwmod_enable(cpgmac_oh); omap_hwmod_enable(usb_oh); omap_hwmod_enable(gpmc_oh); omap_hwmod_idle(cpgmac_oh); omap_hwmod_idle(usb_oh); omap_hwmod_idle(gpmc_oh); if (gfx_l3_clkdm && gfx_l4ls_clkdm) { clkdm_sleep(gfx_l3_clkdm); clkdm_sleep(gfx_l4ls_clkdm); } /* Try to put GFX to sleep */ if (gfx_pwrdm) pwrdm_set_next_pwrst(gfx_pwrdm, PWRDM_POWER_OFF); else pr_err("Could not program GFX to low power state\n"); writel(0x0, AM33XX_CM_MPU_MPU_CLKCTRL); ret = cpu_suspend(0, am33xx_do_sram_idle); writel(0x2, AM33XX_CM_MPU_MPU_CLKCTRL); if (gfx_pwrdm) { state = pwrdm_read_pwrst(gfx_pwrdm); if (state != PWRDM_POWER_OFF) pr_err("GFX domain did not transition to low power state\n"); else pr_info("GFX domain entered low power state\n"); } /* XXX: Why do we need to wakeup the clockdomains? */ if(gfx_l3_clkdm && gfx_l4ls_clkdm) { clkdm_wakeup(gfx_l3_clkdm); clkdm_wakeup(gfx_l4ls_clkdm); } core_suspend_stat = ret; return ret; }
int omap_rproc_activate(struct omap_device *od) { int i, ret = 0; struct rproc *rproc = platform_get_drvdata(&od->pdev); struct device *dev = rproc->dev; struct omap_rproc_pdata *pdata = dev->platform_data; struct omap_rproc_timers_info *timers = pdata->timers; struct omap_rproc_priv *rpp = rproc->priv; #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND struct iommu *iommu; if (!rpp->iommu) { iommu = iommu_get(pdata->iommu_name); if (IS_ERR(iommu)) { dev_err(dev, "iommu_get error: %ld\n", PTR_ERR(iommu)); return PTR_ERR(iommu); } rpp->iommu = iommu; } if (!rpp->mbox) rpp->mbox = omap_mbox_get(pdata->sus_mbox_name, NULL); #endif /** * explicitly configure a boot address from which remoteproc * starts executing code when taken out of reset. */ _load_boot_addr(rproc, rpp->bootaddr); /** * Domain is in HW SUP thus in hw_auto but * since remoteproc will be enabled clkdm * needs to be in sw_sup (Do not let it idle). */ if (pdata->clkdm) clkdm_wakeup(pdata->clkdm); for (i = 0; i < pdata->timers_cnt; i++) omap_dm_timer_start(timers[i].odt); for (i = 0; i < od->hwmods_cnt; i++) { ret = omap_hwmod_enable(od->hwmods[i]); if (ret) { for (i = 0; i < pdata->timers_cnt; i++) omap_dm_timer_stop(timers[i].odt); break; } } /** * Domain is in force_wkup but since remoteproc * was enabled it is safe now to switch clkdm * to hw_auto (let it idle). */ if (pdata->clkdm) clkdm_allow_idle(pdata->clkdm); return ret; }
/* Setup free-running counter for clocksource */ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) { int ret; struct device_node *np = NULL; struct omap_hwmod *oh; void __iomem *vbase; const char *oh_name = "counter_32k"; /* * If device-tree is present, then search the DT blob * to see if the 32kHz counter is supported. */ if (of_have_populated_dt()) { np = omap_get_timer_dt(omap_counter_match, NULL); if (!np) return -ENODEV; of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); if (!oh_name) return -ENODEV; } /* * First check hwmod data is available for sync32k counter */ oh = omap_hwmod_lookup(oh_name); if (!oh || oh->slaves_cnt == 0) return -ENODEV; omap_hwmod_setup_one(oh_name); if (np) { vbase = of_iomap(np, 0); of_node_put(np); } else { vbase = omap_hwmod_get_mpu_rt_va(oh); } if (!vbase) { pr_warn("%s: failed to get counter_32k resource\n", __func__); return -ENXIO; } ret = omap_hwmod_enable(oh); if (ret) { pr_warn("%s: failed to enable counter_32k module (%d)\n", __func__, ret); return ret; } ret = omap_init_clocksource_32k(vbase); if (ret) { pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n", __func__, ret); omap_hwmod_idle(oh); } return ret; }
static int ti_sysc_enable_module(struct device *dev, const struct ti_sysc_cookie *cookie) { if (!cookie->data) return -EINVAL; return omap_hwmod_enable(cookie->data); }
static void omap_clkevt_resume(struct clock_event_device *unused) { if (!clockevent_gpt_hwmod) return; omap_hwmod_enable(clockevent_gpt_hwmod); __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); }
/** * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods * @od: struct omap_device *od * * Enable all underlying hwmods. Returns 0. */ static int _omap_device_enable_hwmods(struct omap_device *od) { int ret = 0; int i; for (i = 0; i < od->hwmods_cnt; i++) ret |= omap_hwmod_enable(od->hwmods[i]); return ret; }
/** * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods * @od: struct omap_device *od * * Enable all underlying hwmods. Returns 0. */ int omap_device_enable_hwmods(struct omap_device *od) { int i; for (i = 0; i < od->hwmods_cnt; i++) omap_hwmod_enable(od->hwmods[i]); /* XXX pass along return value here? */ return 0; }
static void omap_clkevt_resume(struct clock_event_device *unused) { struct omap_hwmod *oh; oh = omap_hwmod_lookup(clockevent_gpt.name); if (!oh) return; omap_hwmod_enable(oh); __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); }
/** * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods * @od: struct omap_device *od * * Enable all underlying hwmods. Returns 0. */ int omap_device_enable_hwmods(struct omap_device *od) { struct omap_hwmod *oh; int i; for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) omap_hwmod_enable(oh); /* XXX pass along return value here? */ return 0; }
static void omap2_gptimer_clksrc_resume(struct clocksource *unused) { struct omap_hwmod *oh; oh = omap_hwmod_lookup(clocksource_gpt.name); if (!oh) return; omap_hwmod_enable(oh); __omap_dm_timer_load_start(&clksrc, OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, omap2_gptimer_clksrc_load, OMAP_TIMER_NONPOSTED); }
static void save_secure_all(void) { u32 ret; omap_hwmod_enable(l3_main_3_oh); ret = omap_secure_dispatcher(secure_hal_save_all_api_index, FLAG_START_CRITICAL, 1, omap_secure_ram_mempool_base(), 0, 0, 0); omap_hwmod_idle(l3_main_3_oh); if (ret != API_HAL_RET_VALUE_OK) pr_err("Secure all context save failed\n"); }
static int omap2_disable_wdt(struct omap_hwmod *oh, void *unused) { void __iomem *base; int ret; if (!oh) { pr_err("%s: Could not look up wdtimer_hwmod\n", __func__); return -EINVAL; } base = omap_hwmod_get_mpu_rt_va(oh); if (!base) { pr_err("%s: Could not get the base address for %s\n", oh->name, __func__); return -EINVAL; } /* Enable the clocks before accessing the WDT registers */ ret = omap_hwmod_enable(oh); if (ret) { pr_err("%s: Could not enable clocks for %s\n", oh->name, __func__); return ret; } /* sequence required to disable watchdog */ __raw_writel(0xAAAA, base + OMAP_WDT_SPR); while (__raw_readl(base + OMAP_WDT_WPS) & 0x10) cpu_relax(); __raw_writel(0x5555, base + OMAP_WDT_SPR); while (__raw_readl(base + OMAP_WDT_WPS) & 0x10) cpu_relax(); ret = omap_hwmod_idle(oh); if (ret) pr_err("%s: Could not disable clocks for %s\n", oh->name, __func__); return ret; }
/* Setup free-running counter for clocksource */ static int __init omap2_sync32k_clocksource_init(void) { int ret; struct omap_hwmod *oh; void __iomem *vbase; const char *oh_name = "counter_32k"; /* * First check hwmod data is available for sync32k counter */ oh = omap_hwmod_lookup(oh_name); if (!oh || oh->slaves_cnt == 0) return -ENODEV; omap_hwmod_setup_one(oh_name); vbase = omap_hwmod_get_mpu_rt_va(oh); if (!vbase) { pr_warn("%s: failed to get counter_32k resource\n", __func__); return -ENXIO; } ret = omap_hwmod_enable(oh); if (ret) { pr_warn("%s: failed to enable counter_32k module (%d)\n", __func__, ret); return ret; } ret = omap_init_clocksource_32k(vbase); if (ret) { pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n", __func__, ret); omap_hwmod_idle(oh); } return ret; }
static int _omap_mstandby_pm_notifier(struct notifier_block *self, unsigned long action, void *dev) { struct omap_hwmod_list *oh_list_item = NULL; struct platform_device *pdev; struct omap_device *od; switch (action) { case PM_POST_SUSPEND: list_for_each_entry(oh_list_item, omap_hwmod_force_mstandby_list_get(), oh_list) { pdev = to_platform_device( omap_device_get_by_hwmod_name( oh_list_item->oh->name)); od = to_omap_device(pdev); if (od && od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { omap_hwmod_enable(oh_list_item->oh); omap_hwmod_idle(oh_list_item->oh); } } }
static int am33xx_pm_suspend(void) { int state, ret = 0; struct omap_hwmod *gpmc_oh, *usb_oh, *gpio1_oh; usb_oh = omap_hwmod_lookup("usb_otg_hs"); gpmc_oh = omap_hwmod_lookup("gpmc"); gpio1_oh = omap_hwmod_lookup("gpio1"); /* WKUP domain GPIO */ omap_hwmod_enable(usb_oh); omap_hwmod_enable(gpmc_oh); /* * Keep USB module enabled during standby * to enable USB remote wakeup * Note: This will result in hard-coding USB state * during standby */ if (suspend_state != PM_SUSPEND_STANDBY) omap_hwmod_idle(usb_oh); omap_hwmod_idle(gpmc_oh); /* * Disable the GPIO module. This ensure that * only sWAKEUP interrupts to Cortex-M3 get generated * * XXX: EVM_SK uses a GPIO0 pin for VTP control * in suspend and hence we can't do this for EVM_SK * alone. The side-effect of this is that GPIO wakeup * might have issues. Refer to commit 672639b for the * details */ /* * Keep GPIO0 module enabled during standby to * support wakeup via GPIO0 keys. */ if ((suspend_cfg_param_list[EVM_ID] != EVM_SK) && (suspend_state != PM_SUSPEND_STANDBY)) omap_hwmod_idle(gpio1_oh); /* * Update Suspend_State value to be used in sleep33xx.S to keep * GPIO0 module enabled during standby for EVM-SK */ if (suspend_state == PM_SUSPEND_STANDBY) suspend_cfg_param_list[SUSPEND_STATE] = PM_STANDBY; else suspend_cfg_param_list[SUSPEND_STATE] = PM_DS0; /* * Keep Touchscreen module enabled during standby * to enable wakeup from standby. */ if (suspend_state == PM_SUSPEND_STANDBY) writel(0x2, AM33XX_CM_WKUP_ADC_TSC_CLKCTRL); if (gfx_l3_clkdm && gfx_l4ls_clkdm) { clkdm_sleep(gfx_l3_clkdm); clkdm_sleep(gfx_l4ls_clkdm); } /* Try to put GFX to sleep */ if (gfx_pwrdm) pwrdm_set_next_pwrst(gfx_pwrdm, PWRDM_POWER_OFF); else pr_err("Could not program GFX to low power state\n"); omap3_intc_suspend(); writel(0x0, AM33XX_CM_MPU_MPU_CLKCTRL); ret = cpu_suspend(0, am33xx_do_sram_idle); writel(0x2, AM33XX_CM_MPU_MPU_CLKCTRL); if (gfx_pwrdm) { state = pwrdm_read_pwrst(gfx_pwrdm); if (state != PWRDM_POWER_OFF) pr_err("GFX domain did not transition to low power state\n"); else pr_info("GFX domain entered low power state\n"); } /* XXX: Why do we need to wakeup the clockdomains? */ if(gfx_l3_clkdm && gfx_l4ls_clkdm) { clkdm_wakeup(gfx_l3_clkdm); clkdm_wakeup(gfx_l4ls_clkdm); } /* * Touchscreen module was enabled during standby * Disable it here. */ if (suspend_state == PM_SUSPEND_STANDBY) writel(0x0, AM33XX_CM_WKUP_ADC_TSC_CLKCTRL); /* * Put USB module to idle on resume from standby */ if (suspend_state == PM_SUSPEND_STANDBY) omap_hwmod_idle(usb_oh); ret = am33xx_verify_lp_state(ret); /* * Enable the GPIO module. Once the driver is * fully adapted to runtime PM this will go away */ /* * During standby, GPIO was not disabled. Hence no * need to enable it here. */ if ((suspend_cfg_param_list[EVM_ID] != EVM_SK) && (suspend_state != PM_SUSPEND_STANDBY)) omap_hwmod_enable(gpio1_oh); return ret; }
static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, int gptimer_id, const char *fck_source) { char name[10]; /* 10 = sizeof("gptXX_Xck0") */ struct omap_hwmod *oh; struct resource irq_rsrc, mem_rsrc; size_t size; int res = 0; int r; sprintf(name, "timer%d", gptimer_id); omap_hwmod_setup_one(name); oh = omap_hwmod_lookup(name); if (!oh) return -ENODEV; r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, &irq_rsrc); if (r) return -ENXIO; timer->irq = irq_rsrc.start; r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, &mem_rsrc); if (r) return -ENXIO; timer->phys_base = mem_rsrc.start; size = mem_rsrc.end - mem_rsrc.start; /* Static mapping, never released */ timer->io_base = ioremap(timer->phys_base, size); if (!timer->io_base) return -ENXIO; /* After the dmtimer is using hwmod these clocks won't be needed */ timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); if (IS_ERR(timer->fclk)) return -ENODEV; omap_hwmod_enable(oh); if (omap_dm_timer_reserve_systimer(gptimer_id)) return -ENODEV; if (gptimer_id != 12) { struct clk *src; src = clk_get(NULL, fck_source); if (IS_ERR(src)) { res = -EINVAL; } else { res = __omap_dm_timer_set_source(timer->fclk, src); if (IS_ERR_VALUE(res)) pr_warning("%s: timer%i cannot set source\n", __func__, gptimer_id); clk_put(src); } } __omap_dm_timer_init_regs(timer); __omap_dm_timer_reset(timer, 1, 1); timer->posted = 1; timer->rate = clk_get_rate(timer->fclk); timer->reserved = 1; return res; }
static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, const char *fck_source, const char *property, const char **timer_name, int posted) { char name[10]; /* 10 = sizeof("gptXX_Xck0") */ const char *oh_name = NULL; struct device_node *np; struct omap_hwmod *oh; struct resource irq, mem; struct clk *src; int r = 0; if (of_have_populated_dt()) { np = omap_get_timer_dt(omap_timer_match, property); if (!np) return -ENODEV; of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); if (!oh_name) return -ENODEV; timer->irq = irq_of_parse_and_map(np, 0); if (!timer->irq) return -ENXIO; timer->io_base = of_iomap(np, 0); of_node_put(np); } else { if (omap_dm_timer_reserve_systimer(timer->id)) return -ENODEV; sprintf(name, "timer%d", timer->id); oh_name = name; } oh = omap_hwmod_lookup(oh_name); if (!oh) return -ENODEV; *timer_name = oh->name; if (!of_have_populated_dt()) { r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, &irq); if (r) return -ENXIO; timer->irq = irq.start; r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, &mem); if (r) return -ENXIO; /* Static mapping, never released */ timer->io_base = ioremap(mem.start, mem.end - mem.start); } if (!timer->io_base) return -ENXIO; /* After the dmtimer is using hwmod these clocks won't be needed */ timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); if (IS_ERR(timer->fclk)) return PTR_ERR(timer->fclk); src = clk_get(NULL, fck_source); if (IS_ERR(src)) return PTR_ERR(src); if (clk_get_parent(timer->fclk) != src) { r = clk_set_parent(timer->fclk, src); if (r < 0) { pr_warn("%s: %s cannot set source\n", __func__, oh->name); clk_put(src); return r; } } clk_put(src); omap_hwmod_setup_one(oh_name); omap_hwmod_enable(oh); __omap_dm_timer_init_regs(timer); if (posted) __omap_dm_timer_enable_posted(timer); /* Check that the intended posted configuration matches the actual */ if (posted != timer->posted) return -EINVAL; timer->rate = clk_get_rate(timer->fclk); timer->reserved = 1; return r; }
static int uart_enable_hwmod(struct omap_device *od) { omap_hwmod_enable(od->hwmods[0]); return 0; }