/** * hsi_clocks_disable_channel - virtual wrapper for disabling HSI clocks for * a given channel * @dev - reference to the hsi device. * @channel_number - channel number which requests clock to be disabled * 0xFF means no particular channel * * Note : there is no real HW clock management per HSI channel, this is only * virtual to keep track of active channels and ease debug * * Function to be called with lock */ void hsi_clocks_disable_channel(struct device *dev, u8 channel_number, const char *s) { struct platform_device *pd = to_platform_device(dev); struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd); if (channel_number != HSI_CH_NUMBER_NONE) dev_dbg(dev, "CLK: hsi_clocks_disable for " "channel %d: %s\n", channel_number, s); else dev_dbg(dev, "CLK: hsi_clocks_disable: %s\n", s); if (!hsi_ctrl->clock_enabled) { dev_dbg(dev, "Clocks already disabled, skipping...\n"); return; } if (hsi_is_hsi_controller_busy(hsi_ctrl)) { dev_dbg(dev, "Cannot disable clocks, HSI port busy\n"); return; } if (hsi_is_hst_controller_busy(hsi_ctrl)) dev_warn(dev, "Disabling clocks with HST FSM not IDLE !\n"); #ifdef K3_0_PORTING_HSI_MISSING_FEATURE /* Allow Fclk to change */ if (dpll_cascading_blocker_release(dev) < 0) dev_warn(dev, "Error releasing DPLL cascading constraint\n"); #endif pm_runtime_put_sync_suspend(dev); }
/** * hsi_clocks_disable_channel - virtual wrapper for disabling HSI clocks for * a given channel * @dev - reference to the hsi device. * @channel_number - channel number which requests clock to be disabled * 0xFF means no particular channel * * Note : there is no real HW clock management per HSI channel, this is only * virtual to keep track of active channels and ease debug * * Function to be called with lock */ void hsi_clocks_disable_channel(struct device *dev, u8 channel_number, const char *s) { struct platform_device *pd = to_platform_device(dev); struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd); if (channel_number != HSI_CH_NUMBER_NONE) dev_dbg(dev, "CLK: hsi_clocks_disable for " "channel %d: %s\n", channel_number, s); else dev_dbg(dev, "CLK: hsi_clocks_disable: %s\n", s); if (!hsi_ctrl->clock_enabled) { dev_dbg(dev, "Clocks already disabled, skipping...\n"); return; } if (hsi_is_hsi_controller_busy(hsi_ctrl)) { dev_dbg(dev, "Cannot disable clocks, HSI port busy\n"); return; } if (hsi_is_hst_controller_busy(hsi_ctrl)) dev_warn(dev, "Disabling clocks with HST FSM not IDLE !\n"); #ifndef USE_PM_RUNTIME_FOR_HSI hsi_runtime_suspend(dev); omap_device_idle(pd); #else /* HSI_TODO : this can probably be changed * to return pm_runtime_put(dev); */ pm_runtime_put_sync(dev); #endif }
/** * hsi_clocks_disable_channel - virtual wrapper for disabling HSI clocks for * a given channel * @dev - reference to the hsi device. * @channel_number - channel number which requests clock to be disabled * 0xFF means no particular channel * * Note : there is no real HW clock management per HSI channel, this is only * virtual to keep track of active channels and ease debug * * Function to be called with lock */ void hsi_clocks_disable_channel(struct device *dev, u8 channel_number, const char *s) { struct platform_device *pd = to_platform_device(dev); struct hsi_platform_data *pdata = dev_get_platdata(dev); struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd); int ret; if (channel_number != HSI_CH_NUMBER_NONE) dev_dbg(dev, "CLK: hsi_clocks_disable for " "channel %d: %s\n", channel_number, s); else dev_dbg(dev, "CLK: hsi_clocks_disable: %s\n", s); if (!hsi_ctrl->clock_enabled) { dev_dbg(dev, "Clocks already disabled, skipping...\n"); return; } if (hsi_is_hsi_controller_busy(hsi_ctrl)) { dev_dbg(dev, "Cannot disable clocks, HSI port busy\n"); return; } if (hsi_is_hst_controller_busy(hsi_ctrl)) #if 1 dev_dbg(dev, "Disabling clocks with HST FSM not IDLE !\n"); #endif #ifdef CONFIG_PM /* Allow Fclk to change */ if (dpll_cascading_blocker_release(dev) < 0) dev_warn(dev, "Error releasing DPLL cascading constraint\n"); #endif /* CONFIG_PM */ #ifndef USE_PM_RUNTIME_FOR_HSI hsi_runtime_suspend(dev); ret = pdata->device_idle(pd); if (ret) dev_err(dev, "Failed to idle device: %s %d\n", s, ret); #else /* HSI_TODO : this can probably be changed * to return pm_runtime_put(dev); */ pm_runtime_put_sync(dev); #endif }
/* Based on counters, device appears to be idle. * Check if the device can be suspended. */ static int hsi_runtime_idle(struct device *dev) { struct platform_device *pd = to_platform_device(dev); struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd); dev_dbg(dev, "%s\n", __func__); if (hsi_is_hsi_controller_busy(hsi_ctrl)) { dev_dbg(dev, "hsi_runtime_idle: HSI port busy\n"); return -EBUSY; } if (hsi_is_hst_controller_busy(hsi_ctrl)) { dev_dbg(dev, "hsi_runtime_idle: HST FSM not IDLE !\n"); return -EBUSY; } /* HSI_TODO : check also the interrupt status registers.*/ return 0; }
/** * hsi_clocks_disable_channel - virtual wrapper for disabling HSI clocks for * a given channel * @dev - reference to the hsi device. * @channel_number - channel number which requests clock to be disabled * 0xFF means no particular channel * * Note : there is no real HW clock management per HSI channel, this is only * virtual to keep track of active channels and ease debug * * Function to be called with lock */ void hsi_clocks_disable_channel(struct device *dev, u8 channel_number, const char *s) { struct platform_device *pd = to_platform_device(dev); struct hsi_dev *hsi_ctrl = platform_get_drvdata(pd); /* hnagalla -- for tests ******/ if( (bool)(hsi_ctrl->hsi_port[hsi_ctrl->id].hsi_mode&XMM_HSI_CLK_UNDIS)==true ) {//XMM_HSI_CLK_UNDIS, HSI时钟取消关闭标志; dpr_0("hsi_driver.c:%s. #XMM_HSI_CLK_UNDIS# hsi_ctrl->id=%d,hsi_mode=0x%08X;\n",__func__,hsi_ctrl->id,hsi_ctrl->hsi_port[hsi_ctrl->id].hsi_mode); //Add for Flashless 3HSI dbg return; } if (channel_number != HSI_CH_NUMBER_NONE) dev_dbg(dev, "CLK: hsi_clocks_disable for " "channel %d: %s\n", channel_number, s); else dev_dbg(dev, "CLK: hsi_clocks_disable: %s\n", s); if (!hsi_ctrl->clock_enabled) { dev_dbg(dev, "Clocks already disabled, skipping...\n"); return; } if (hsi_is_hsi_controller_busy(hsi_ctrl)) { dev_dbg(dev, "Cannot disable clocks, HSI port busy\n"); return; } if (hsi_is_hst_controller_busy(hsi_ctrl)) dev_dbg(dev, "Disabling clocks with HST FSM not IDLE !\n"); #ifdef K3_0_PORTING_HSI_MISSING_FEATURE /* Allow Fclk to change */ if (dpll_cascading_blocker_release(dev) < 0) dev_warn(dev, "Error releasing DPLL cascading constraint\n"); #endif pm_runtime_put_sync_suspend(dev); }