int fimc_is_start_firmware(struct fimc_is *is) { struct device *dev = &is->pdev->dev; int ret; memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size); wmb(); ret = fimc_is_cpu_set_power(is, 1); if (ret < 0) return ret; ret = fimc_is_wait_event(is, IS_ST_A5_PWR_ON, 1, msecs_to_jiffies(FIMC_IS_FW_LOAD_TIMEOUT)); if (ret < 0) dev_err(dev, "FIMC-IS CPU power on failed\n"); return ret; }
static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on) { struct fimc_isp *isp = v4l2_get_subdevdata(sd); struct fimc_is *is = fimc_isp_to_is(isp); int ret = 0; pr_debug("on: %d\n", on); if (on) { ret = pm_runtime_get_sync(&is->pdev->dev); if (ret < 0) return ret; set_bit(IS_ST_PWR_ON, &is->state); ret = fimc_is_start_firmware(is); if (ret < 0) { v4l2_err(sd, "firmware booting failed\n"); pm_runtime_put(&is->pdev->dev); return ret; } set_bit(IS_ST_PWR_SUBIP_ON, &is->state); ret = fimc_is_hw_initialize(is); } else { /* Close sensor */ if (!test_bit(IS_ST_PWR_ON, &is->state)) { fimc_is_hw_close_sensor(is, 0); ret = fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 0, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { v4l2_err(sd, "sensor close timeout\n"); return ret; } } /* SUB IP power off */ if (test_bit(IS_ST_PWR_SUBIP_ON, &is->state)) { fimc_is_hw_subip_power_off(is); ret = fimc_is_wait_event(is, IS_ST_PWR_SUBIP_ON, 0, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { v4l2_err(sd, "sub-IP power off timeout\n"); return ret; } } fimc_is_cpu_set_power(is, 0); pm_runtime_put_sync(&is->pdev->dev); clear_bit(IS_ST_PWR_ON, &is->state); clear_bit(IS_ST_INIT_DONE, &is->state); is->state = 0; is->config[is->config_index].p_region_index[0] = 0; is->config[is->config_index].p_region_index[1] = 0; set_bit(IS_ST_IDLE, &is->state); wmb(); } return ret; }