Exemplo n.º 1
0
static void mdm_image_upgrade(struct mdm_modem_drv *mdm_drv, int type)
{
	switch (type) {
	case APQ_CONTROLLED_UPGRADE:
		pr_debug("%s APQ controlled modem image upgrade\n", __func__);
		mdm_drv->mdm_ready = 0;
		mdm_toggle_soft_reset(mdm_drv);
		break;
	case MDM_CONTROLLED_UPGRADE:
		pr_debug("%s MDM controlled modem image upgrade\n", __func__);
		mdm_drv->mdm_ready = 0;
		/*
		 * If we have no image currently present on the modem, then we
		 * would be in PBL, in which case the status gpio would not go
		 * high.
		 */
		mdm_drv->disable_status_check = 1;
		if (GPIO_IS_VALID(mdm_drv->usb_switch_gpio)) {
			pr_info("%s Switching usb control to MDM\n", __func__);
			gpio_direction_output(mdm_drv->usb_switch_gpio, 1);
		} else
			pr_err("%s usb switch gpio unavailable\n", __func__);
		break;
	default:
		pr_err("%s invalid upgrade type\n", __func__);
	}
}
static void mdm_do_first_power_on(struct mdm_ctrl *mdm)
{
	int i;
	int pblrdy;
	struct device *dev = mdm->dev;

	dev_info(dev, "Powering on modem for the first time\n");
	mdm_toggle_soft_reset(mdm);
	/* Add a delay to allow PON sequence to complete*/
	msleep(50);
	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1);
	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(MDM_GPIO(mdm, MDM2AP_PBLRDY));
		if (pblrdy)
			break;
		usleep_range(5000, 6000);
	}
	dev_info(dev, "pblrdy i:%d\n", i);

	if (pmdata_gpio_host_ready) {
		dev_info(dev, "Set qcom,ap2mdm-hostrdy-gpio to 1\n");
		gpio_direction_output(pmdata_gpio_host_ready, 1);
		gpio_set_value(pmdata_gpio_host_ready, 1);
	}
	else {
		dev_info(dev, "Fail to set gpio pin qcom,ap2mdm-hostrdy-gpio\n");
	}

	msleep(200);
}
Exemplo n.º 3
0
static void mdm_do_soft_power_on(struct mdm_modem_drv *mdm_drv)
{
	int i;
	int pblrdy;

	pr_err("%s: soft resetting mdm modem\n", __func__);
	mdm_peripheral_disconnect(mdm_drv);
	mdm_toggle_soft_reset(mdm_drv);

	if (!GPIO_IS_VALID(mdm_drv->mdm2ap_pblrdy))
		goto start_mdm_peripheral;

	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(mdm_drv->mdm2ap_pblrdy);
		if (pblrdy)
			break;
		usleep_range(5000, 5000);
	}

	pr_debug("%s: i:%d\n", __func__, i);

start_mdm_peripheral:
	mdm_peripheral_connect(mdm_drv);
	msleep(200);
}
Exemplo n.º 4
0
static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
{
	int i;
	int pblrdy;
	int kpd_direction_assert = 1,
		kpd_direction_de_assert = 0;

	if (mdm_drv->pdata->kpd_not_inverted) {
		kpd_direction_assert = 0;
		kpd_direction_de_assert = 1;
	}

	if (mdm_drv->power_on_count != 1) {
		pr_err("%s:id %d: Calling fn when power_on_count != 1\n",
			   __func__, mdm_drv->device_id);
		return;
	}

	pr_err("%s:id %d: Powering on modem for the first time\n",
		   __func__, mdm_drv->device_id);
	mdm_peripheral_disconnect(mdm_drv);

	/* If this is the first power-up after a panic, the modem may still
	 * be in a power-on state, in which case we need to toggle the gpio
	 * instead of just de-asserting it. No harm done if the modem was
	 * powered down.
	 */
	if (!mdm_drv->pdata->no_reset_on_first_powerup)
		mdm_toggle_soft_reset(mdm_drv);

	/* If the device has a kpd pwr gpio then toggle it. */
	if (GPIO_IS_VALID(mdm_drv->ap2mdm_kpdpwr_n_gpio)) {
		/* Pull AP2MDM_KPDPWR gpio high and wait for PS_HOLD to settle,
		 * then	pull it back low.
		 */
		pr_debug("%s:id %d: Pulling AP2MDM_KPDPWR gpio high\n",
				 __func__, mdm_drv->device_id);
		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio,
				kpd_direction_assert);
		msleep(1000);
		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio,
				kpd_direction_de_assert);
	}

	if (!GPIO_IS_VALID(mdm_drv->mdm2ap_pblrdy))
		goto start_mdm_peripheral;

	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(mdm_drv->mdm2ap_pblrdy);
		if (pblrdy)
			break;
		usleep_range(5000, 5000);
	}
	pr_debug("%s: id %d: pblrdy i:%d\n", __func__,
			 mdm_drv->device_id, i);

start_mdm_peripheral:
	mdm_peripheral_connect(mdm_drv);
	msleep(200);
}
static void mdm_do_soft_power_on(struct mdm_modem_drv *mdm_drv)
{
#ifdef USE_MDM_MODEM
	int i;
	int pblrdy;
#endif

	pr_err("%s: id %d:  soft resetting mdm modem\n",
		   __func__, mdm_drv->device_id);
	mdm_peripheral_disconnect(mdm_drv);
	mdm_toggle_soft_reset(mdm_drv);

#ifdef USE_MDM_MODEM
	if (!GPIO_IS_VALID(MDM_GPIO(MDM2AP_PBLRDY)))
		goto start_mdm_peripheral;

	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(MDM_GPIO(MDM2AP_PBLRDY));
		if (pblrdy)
			break;
		usleep_range(5000, 5000);
	}

	pr_info("%s: id %d: pblrdy i:%d\n", __func__,
			 mdm_drv->device_id, i);


start_mdm_peripheral:
#endif

	mdm_peripheral_connect(mdm_drv);
	msleep(200);
}
Exemplo n.º 6
0
static void mdm_image_upgrade(struct mdm_modem_drv *mdm_drv, int type)
{
	switch (type) {
	case APQ_CONTROLLED_UPGRADE:
		pr_debug("%s: id %d: APQ controlled modem image upgrade\n",
				 __func__, mdm_drv->device_id);
		atomic_set(&mdm_drv->mdm_ready, 0);
		mdm_toggle_soft_reset(mdm_drv);
		break;
	case MDM_CONTROLLED_UPGRADE:
		pr_debug("%s: id %d: MDM controlled modem image upgrade\n",
				 __func__, mdm_drv->device_id);
		atomic_set(&mdm_drv->mdm_ready, 0);
		/*
		 * If we have no image currently present on the modem, then we
		 * would be in PBL, in which case the status gpio would not go
		 * high.
		 */
		mdm_drv->disable_status_check = 1;
		if (GPIO_IS_VALID(MDM_GPIO(USB_SW))) {
			pr_debug("%s: id %d: Switching usb control to MDM\n",
					__func__, mdm_drv->device_id);
			gpio_direction_output(MDM_GPIO(USB_SW), 1);
		} else
			pr_err("%s: id %d: usb switch gpio unavailable\n",
				   __func__, mdm_drv->device_id);
		break;
	default:
		pr_err("%s: id %d: invalid upgrade type\n",
			   __func__, mdm_drv->device_id);
	}
}
Exemplo n.º 7
0
/* This function can be called from atomic context. */
static void mdm_atomic_soft_reset(struct mdm_modem_drv *mdm_drv)
{
	mdm_toggle_soft_reset(mdm_drv);
}
Exemplo n.º 8
0
static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc)
{
	bool status_down;
	uint64_t timeout;
	uint64_t now;
	struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
	struct device *dev = mdm->dev;

	switch (notify) {
	case ESOC_IMG_XFER_DONE:
		dev_info(dev, "%s ESOC_IMG_XFER_DONE\n", __func__);
		if (gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)) ==  0)
			schedule_delayed_work(&mdm->mdm2ap_status_check_work,
				msecs_to_jiffies(MDM2AP_STATUS_TIMEOUT_MS));
		break;
	case ESOC_BOOT_DONE:
		esoc_clink_evt_notify(ESOC_RUN_STATE, esoc);
		break;
	case ESOC_IMG_XFER_RETRY:
		mdm->init = 1;
		mdm_toggle_soft_reset(mdm);
		break;
	case ESOC_IMG_XFER_FAIL:
		esoc_clink_evt_notify(ESOC_BOOT_FAIL, esoc);
		break;
	case ESOC_UPGRADE_AVAILABLE:
		break;
	case ESOC_DEBUG_DONE:
		mdm->debug_fail = false;
		mdm_update_gpio_configs(mdm, GPIO_UPDATE_BOOTING_CONFIG);
		complete(&mdm->debug_done);
		break;
	case ESOC_DEBUG_FAIL:
		mdm->debug_fail = true;
		complete(&mdm->debug_done);
		break;
	case ESOC_PRIMARY_CRASH:
		mdm_disable_irqs(mdm);
		status_down = false;
		dev_info(dev, "signal apq err fatal for graceful restart\n");
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
		timeout = local_clock();
		do_div(timeout, NSEC_PER_MSEC);
		timeout += MDM_MODEM_TIMEOUT;
		do {
			if (gpio_get_value(MDM_GPIO(mdm,
						MDM2AP_STATUS)) == 0) {
				status_down = true;
				break;
			}
			now = local_clock();
			do_div(now, NSEC_PER_MSEC);
		} while (!time_after64(now, timeout));

		if (!status_down) {
			dev_err(mdm->dev, "%s MDM2AP status did not go low\n",
								__func__);
			gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
					      !!mdm->soft_reset_inverted);
			/*
			 * allow PS hold assert to be detected.
			 * pmic requires 6ms for crash reset case.
			 */
			mdelay(6);
			gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
					      !mdm->soft_reset_inverted);
		}
		break;
	case ESOC_PRIMARY_REBOOT:
		dev_info(mdm->dev, "Triggering mdm cold reset");
		mdm->ready = 0;
		gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
				!!mdm->soft_reset_inverted);
		mdelay(300);
		gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
				!mdm->soft_reset_inverted);
		break;
	};
	return;
}
Exemplo n.º 9
0
static int mdm_cmd_exe(enum esoc_cmd cmd, struct esoc_clink *esoc)
{
	int ret;
	unsigned long end_time;
	bool status_down = false;
	struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
	struct device *dev = mdm->dev;

	switch (cmd) {
	case ESOC_PWR_ON:
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
		mdm_enable_irqs(mdm);
		mdm->init = 1;
		mdm_do_first_power_on(mdm);
		break;
	case ESOC_PWR_OFF:
		mdm_disable_irqs(mdm);
		mdm->debug = 0;
		mdm->ready = false;
		ret = sysmon_send_shutdown(mdm->sysmon_subsys_id);
		device_lock(dev);
		if (ret)
			dev_err(mdm->dev, "Graceful shutdown fail, ret = %d\n",
									ret);
		else {
			dev_info(mdm->dev, "Waiting for status gpio go low\n");
			status_down = false;
			end_time = jiffies + msecs_to_jiffies(10000);
			while (time_before(jiffies, end_time)) {
				if (gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS))
									== 0) {
					dev_dbg(dev, "Status went low\n");
					status_down = true;
					break;
				}
				msleep(100);
			}
			if (status_down)
				dev_info(dev, "shutdown successful\n");
			else
				dev_err(mdm->dev, "graceful poff ipc fail\n");
		}
		/*
		 * Force a shutdown of the mdm. This is required in order
		 * to prevent the mdm from immediately powering back on
		 * after the shutdown
		 */
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_STATUS), 0);
		esoc_clink_queue_request(ESOC_REQ_SHUTDOWN, esoc);
		mdm_power_down(mdm);
		mdm_update_gpio_configs(mdm, GPIO_UPDATE_BOOTING_CONFIG);
		device_unlock(dev);
		break;
	case ESOC_RESET:
		mdm_toggle_soft_reset(mdm);
		break;
	case ESOC_PREPARE_DEBUG:
		/*
		 * disable all irqs except request irq (pblrdy)
		 * force a reset of the mdm by signaling
		 * an APQ crash, wait till mdm is ready for ramdumps.
		 */
		mdm->ready = false;
		cancel_delayed_work(&mdm->mdm2ap_status_check_work);
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
		dev_info(mdm->dev, "set ap2mdm errfatal to force reset\n");
		msleep(mdm->ramdump_delay_ms);
		break;
	case ESOC_EXE_DEBUG:
		mdm->debug = 1;
		mdm_toggle_soft_reset(mdm);
		/*
		 * wait for ramdumps to be collected
		 * then power down the mdm and switch gpios to booting
		 * config
		 */
		if (!wait_for_completion_timeout(&mdm->debug_done,
				msecs_to_jiffies(mdm->dump_timeout_ms))) {
			dev_err(mdm->dev, "ramdump collection timedout\n");
			mdm->debug = 0;
			return -ETIMEDOUT;
		}
		if (mdm->debug_fail) {
			dev_err(mdm->dev, "unable to collect ramdumps\n");
			mdm->debug = 0;
			return -EIO;
		}
		dev_dbg(mdm->dev, "ramdump collection done\n");
		mdm->debug = 0;
		init_completion(&mdm->debug_done);
		break;
	case ESOC_EXIT_DEBUG:
		/*
		 * Deassert APQ to mdm err fatal
		 * Power on the mdm
		 */
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0);
		dev_dbg(mdm->dev, "exiting debug state after power on\n");
		mdm->get_restart_reason = true;
	      break;
	default:
	      return -EINVAL;
	};
	return 0;
}
static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc)
{
	bool status_down;
	uint64_t timeout;
	uint64_t now;
	struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
	struct device *dev = mdm->dev;
	int ret;
	int max_spin = 20;

	switch (notify) {
	case ESOC_IMG_XFER_DONE:
		dev_info(dev, "%s ESOC_IMG_XFER_DONE\n", __func__);
		if (gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)) ==  0)
			schedule_delayed_work(&mdm->mdm2ap_status_check_work,
				msecs_to_jiffies(MDM2AP_STATUS_TIMEOUT_MS));
		break;
	case ESOC_BOOT_DONE:
		esoc_clink_evt_notify(ESOC_RUN_STATE, esoc);
		break;
	case ESOC_IMG_XFER_RETRY:
		mdm->init = 1;
		mdm_toggle_soft_reset(mdm);
		break;
	case ESOC_IMG_XFER_FAIL:
		esoc_clink_evt_notify(ESOC_INVALID_STATE, esoc);
		break;
	case ESOC_BOOT_FAIL:
		esoc_clink_evt_notify(ESOC_INVALID_STATE, esoc);
		break;
	case ESOC_UPGRADE_AVAILABLE:
		break;
	case ESOC_DEBUG_DONE:
		mdm->debug_fail = false;
		mdm_update_gpio_configs(mdm, GPIO_UPDATE_BOOTING_CONFIG);
		complete(&mdm->debug_done);
		break;
	case ESOC_DEBUG_FAIL:
		mdm->debug_fail = true;
		complete(&mdm->debug_done);
		break;
	case ESOC_PRIMARY_CRASH:
		mdm_disable_irqs(mdm);
		status_down = false;
		dev_info(dev, "signal apq err fatal for graceful restart\n");
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_VDDMIN), 1);
		timeout = local_clock();
		do_div(timeout, NSEC_PER_MSEC);
		timeout += MDM_MODEM_TIMEOUT;
		do {
			if (gpio_get_value(MDM_GPIO(mdm,
						MDM2AP_STATUS)) == 0) {
				status_down = true;
				break;
			}
			now = local_clock();
			do_div(now, NSEC_PER_MSEC);
		} while (!time_after64(now, timeout));

		if (!status_down) {
			dev_err(mdm->dev, "%s MDM2AP status did not go low\n",
								__func__);
			gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
					      !!mdm->soft_reset_inverted);
			/*
			 * allow PS hold assert to be detected.
			 * pmic requires 6ms for crash reset case.
			 */
			mdelay(6);
			gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
					      !mdm->soft_reset_inverted);
		}
		break;
	case ESOC_PRIMARY_REBOOT:
		exynos_pcie_disable_irq(0);
		mdm_disable_irqs(mdm);
		dev_info(mdm->dev, "Triggering mdm cold reset");
		mdm->ready = 0;
		while (gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)) && max_spin--) {
			msleep(100);
			dev_info(mdm->dev, "gpio_get_value(MDM2AP_STATUS) : %d\n",
					gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)));
		}
		gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
				!!mdm->soft_reset_inverted);
		mdelay(300);
		gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
				!mdm->soft_reset_inverted);
		break;
	case ESOC_DIAG_DISABLE:
		dev_info(mdm->dev, "Send diag_disable noti\n");
		ret = sysmon_send_diag_disable_noti(mdm->sysmon_subsys_id);
		if (ret < 0)
			dev_err(mdm->dev, "sending diag_disable noti is failed, ret = %d\n", ret);
		else
			dev_info(mdm->dev, "sending diag_disable noti is succeed.\n");
		break;
	case ESOC_FORCE_CPCRASH:
		dev_err(mdm->dev, "Force CP Crash\n");
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_VDDMIN), 1);
		break;
	case ESOC_CP_SILENT_RESET:
		dev_err(mdm->dev, "Force CP Silent Reset\n");
		set_silent_reset();
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_VDDMIN), 1);
		break;
	};
	return;
}
Exemplo n.º 11
0
static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
{
	int i;
	int pblrdy;

	if (power_on_count != 1) {
		pr_err("%s: Calling fn when power_on_count != 1\n",
			   __func__);
		return;
	}

	pr_err("%s: Powering on modem for the first time\n", __func__);
	gpio_direction_output(mdm_drv->ap2mdm_wakeup_gpio, 0);
	mdm_peripheral_disconnect(mdm_drv);

	/* If this is the first power-up after a panic, the modem may still
	 * be in a power-on state, in which case we need to toggle the gpio
	 * instead of just de-asserting it. No harm done if the modem was
	 * powered down.
	 */
	mdm_toggle_soft_reset(mdm_drv);

	/* If the device has a kpd pwr gpio then toggle it. */
	if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0) {
		/* Pull AP2MDM_KPDPWR gpio high and wait for PS_HOLD to settle,
		 * then	pull it back low.
		 */
		pr_debug("%s: Pulling AP2MDM_KPDPWR gpio high\n", __func__);
		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
		msleep(1000);
		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
	}

	/* first power charged after 10ms */
	usleep_range(10000, 15000);
	gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);

#ifdef CONFIG_HSIC_EURONLY_APPLY
	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(mdm_drv->mdm2ap_pblrdy);
		if (pblrdy)
			break;
		usleep_range(5000, 5000);
	}

	pr_err("%s: i:%d\n", __func__, i);
#else
	if (!mdm_drv->mdm2ap_pblrdy)
		goto start_mdm_peripheral;

	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(mdm_drv->mdm2ap_pblrdy);
		if (pblrdy)
			break;
		usleep_range(5000, 5000);
	}

	pr_debug("%s: i:%d\n", __func__, i);
#endif

start_mdm_peripheral:
	mdm_peripheral_connect(mdm_drv);
	msleep(200);
}
Exemplo n.º 12
0
static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
{
#ifdef USE_MDM_MODEM
	int i;
	int pblrdy;
#endif
	gpio_direction_output(MDM_GPIO(AP2MDM_SOFT_RESET), 0);
	gpio_direction_output(MDM_GPIO(AP2MDM_PMIC_PWR_EN), 1);
	msleep(10);

	if (mdm_drv->power_on_count != 1) {
		pr_debug("%s:id %d: Calling fn when power_on_count != 1\n",
			   __func__, mdm_drv->device_id);
		return;
	}
	pr_err("%s \n", __func__);

	pr_err("%s:id %d: Powering on modem for the first time\n",
		   __func__, mdm_drv->device_id);
	mdm_peripheral_disconnect(mdm_drv);

	/* If this is the first power-up after a panic, the modem may still
	 * be in a power-on state, in which case we need to toggle the gpio
	 * instead of just de-asserting it. No harm done if the modem was
	 * powered down.
	 */

	if (!mdm_drv->pdata->no_reset_on_first_powerup)
		mdm_toggle_soft_reset(mdm_drv);

	/* If the device has a kpd pwr gpio then toggle it. */
	if (GPIO_IS_VALID(MDM_GPIO(AP2MDM_KPDPWR))) { // HSLEE qsc en
		/* Pull AP2MDM_KPDPWR gpio high and wait for PS_HOLD to settle,
		 * then	pull it back low.
		 */
		pr_err("%s:id %d: Pulling AP2MDM_KPDPWR gpio high\n",
				 __func__, mdm_drv->device_id);
		gpio_direction_output(MDM_GPIO(AP2MDM_KPDPWR), 1);
		//gpio_direction_output(MDM_GPIO(AP2MDM_STATUS), 1);
		msleep(1000);
		gpio_direction_output(MDM_GPIO(AP2MDM_KPDPWR), 0);
	}//else

		gpio_direction_output(MDM_GPIO(AP2MDM_STATUS), 1);

	msleep(5000);
	if (!gpio_get_value(MDM_GPIO(MDM2AP_STATUS)))	{
		pr_err("%s: QSC failed. reboot\n", __func__);

		gpio_direction_output(MDM_GPIO(AP2MDM_STATUS), 0);
		gpio_direction_output(MDM_GPIO(AP2MDM_PMIC_PWR_EN), 0);
		msleep(5000);
		gpio_direction_output(MDM_GPIO(AP2MDM_PMIC_PWR_EN), 1);
		msleep(10);
		gpio_direction_output(MDM_GPIO(AP2MDM_KPDPWR), 1);
		msleep(1000);
		gpio_direction_output(MDM_GPIO(AP2MDM_KPDPWR), 0);
		gpio_direction_output(MDM_GPIO(AP2MDM_STATUS), 1);
	}

	/* check if qsc is in dload mode */
	if (gpio_get_value(MDM_GPIO(MDM2AP_ERRFATAL)))	{
		pr_err("%s: QSC is in dload. reset\n", __func__);
		gpio_direction_output(MDM_GPIO(AP2MDM_SOFT_RESET), 1);
		mdelay(10);
		gpio_direction_output(MDM_GPIO(AP2MDM_SOFT_RESET), 0);
	}

#ifdef USE_MDM_MODEM
	if (!GPIO_IS_VALID(MDM_GPIO(MDM2AP_PBLRDY)))
		goto start_mdm_peripheral;

	for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
		pblrdy = gpio_get_value(MDM_GPIO(MDM2AP_PBLRDY));
		if (pblrdy)
			break;
		usleep_range(5000, 5000);
	}
	pr_info("%s: id %d: pblrdy i:%d\n", __func__,
			 mdm_drv->device_id, i);


start_mdm_peripheral:
#endif
	pr_err("%s %d\n", __func__,__LINE__);
	mdm_peripheral_connect(mdm_drv);
	msleep(200);
}