static int ss300_off(struct modem_ctl *mc)
{
	struct io_device *iod = mc->iod;
	struct link_device *ld = get_current_link(iod);
	unsigned long flags;
	int i;

	mif_disable_irq(&mc->irq_cp_active);

	mif_info("%s: %s: +++\n", mc->name, FUNC);

	print_mc_state(mc);

	spin_lock_irqsave(&mc->lock, flags);

	if (cp_offline(mc)) {
		spin_unlock_irqrestore(&mc->lock, flags);
		mif_err("%s: %s: OFFLINE already!!!\n", mc->name, FUNC);
		goto exit;
	}

	iod->modem_state_changed(iod, STATE_OFFLINE);

	spin_unlock_irqrestore(&mc->lock, flags);

	if (ld->close_tx)
		ld->close_tx(ld);

#if 0
	wait_for_link_unmount(mc, ld);
#endif

	if (gpio_get_value(mc->gpio_cp_on) == 0) {
		mif_err("%s: cp_on == 0\n", mc->name);
		goto exit;
	}

	/* wait for cp_active for 3 seconds */
	for (i = 0; i < 150; i++) {
		if (gpio_get_value(mc->gpio_phone_active))
			break;
		msleep(20);
	}

	print_mc_state(mc);

	if (ld->off)
		ld->off(ld);

	if (gpio_get_value(mc->gpio_cp_reset)) {
		mif_err("%s: %s: cp_reset -> 0\n", mc->name, FUNC);
		gpio_set_value(mc->gpio_cp_reset, 0);
		print_mc_state(mc);
	}

exit:
	mif_info("%s: %s: ---\n", mc->name, FUNC);
	return 0;
}
Example #2
0
static inline void start_tx_timer(struct mem_link_device *mld,
				  struct hrtimer *timer)
{
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	unsigned long flags;

	spin_lock_irqsave(&mc->lock, flags);

	if (unlikely(cp_offline(mc)))
		goto exit;

	if (!hrtimer_is_queued(timer)) {
		ktime_t ktime = ktime_set(0, tx_timer_ns);
		hrtimer_start(timer, ktime, HRTIMER_MODE_REL);
	}

exit:
	spin_unlock_irqrestore(&mc->lock, flags);
}