コード例 #1
0
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;
}
コード例 #2
0
static int ss300_on(struct modem_ctl *mc)
{
	struct io_device *iod = mc->iod;
	struct link_device *ld = get_current_link(iod);
	unsigned long flags;

	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);

	iod->modem_state_changed(iod, STATE_OFFLINE);

	gpio_set_value(mc->gpio_pda_active, 1);

	if (mc->wake_lock && !wake_lock_active(mc->wake_lock)) {
		wake_lock(mc->wake_lock);
		mif_err("%s->wake_lock locked\n", mc->name);
	}

	if (ld->ready)
		ld->ready(ld);

	spin_unlock_irqrestore(&mc->lock, flags);

	gpio_set_value(mc->gpio_cp_on, 0);
	msleep(100);

	gpio_set_value(mc->gpio_cp_reset, 0);
	print_mc_state(mc);
	msleep(500);

	gpio_set_value(mc->gpio_cp_on, 1);
	msleep(100);

	if (ld->reset)
		ld->reset(ld);

	if (mc->gpio_ap_dump_int)
		gpio_set_value(mc->gpio_ap_dump_int, 0);

	gpio_set_value(mc->gpio_cp_reset, 1);
	print_mc_state(mc);
	msleep(300);

	mif_info("%s: %s: ---\n", mc->name, FUNC);
	return 0;
}
コード例 #3
0
ファイル: modem_ctrl_ss333.c プロジェクト: myjang0507/a8elte
static int ss333_dump_reset(struct modem_ctl *mc)
{
	struct io_device *iod = mc->iod;
	struct link_device *ld = get_current_link(iod);
	unsigned int gpio_cp_reset = mc->gpio_cp_reset;
	unsigned long flags;

	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);

	iod->modem_state_changed(iod, STATE_CRASH_EXIT);

	if (mc->wake_lock && !wake_lock_active(mc->wake_lock)) {
		wake_lock(mc->wake_lock);
		mif_err("%s->wake_lock locked\n", mc->name);
	}

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

	spin_unlock_irqrestore(&mc->lock, flags);

	gpio_set_value(gpio_cp_reset, 0);
	print_mc_state(mc);
	udelay(200);

	if (ld->reset)
		ld->reset(ld);

	gpio_set_value(gpio_cp_reset, 1);
	print_mc_state(mc);
	msleep(300);

	gpio_set_value(mc->gpio_ap_status, 1);

	mif_info("%s: %s: ---\n", mc->name, FUNC);
	return 0;
}
コード例 #4
0
static irqreturn_t cp_active_handler(int irq, void *arg)
{
	struct modem_ctl *mc = (struct modem_ctl *)arg;
	struct link_device *ld;
	enum modem_state old_state;
	enum modem_state new_state;
	unsigned long flags;

	if (!cp_online(mc))
		goto exit;

	print_mc_state(mc);

	if (gpio_get_value(mc->gpio_cp_reset) == 0)
		goto exit;

	ld = get_current_link(mc->iod);

	spin_lock_irqsave(&mc->lock, flags);

	old_state = mc->phone_state;
	new_state = mc->phone_state;

	if (gpio_get_value(mc->gpio_phone_active) != 0) {
		if (gpio_get_value(mc->gpio_cp_on) == 0) {
			new_state = STATE_OFFLINE;
		} else if (old_state == STATE_ONLINE) {
			new_state = STATE_CRASH_EXIT;
		} else {
			mif_err("%s: %s: don't care!!!\n", mc->name, FUNC);
		}
	}

	if (new_state != old_state) {
		/* Change the modem state for RIL */
		mc->iod->modem_state_changed(mc->iod, new_state);

		/* Change the modem state for CBD */
		mc->bootd->modem_state_changed(mc->bootd, new_state);
	}

	spin_unlock_irqrestore(&mc->lock, flags);

	if ((old_state == STATE_ONLINE) && (new_state == STATE_CRASH_EXIT)) {
		if (timer_pending(&mc->crash_ack_timer))
			del_timer(&mc->crash_ack_timer);

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

exit:
	return IRQ_HANDLED;
}
コード例 #5
0
int ss300_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
{
	int ret = 0;
	unsigned int irq = 0;
	unsigned long flag = 0;
	char name[MAX_NAME_LEN];
	mif_err("+++\n");

	ret = dt_gpio_config(mc, pdata);
	if (ret < 0)
		return ret;

	if (!pdata->gpio_cp_on || !pdata->gpio_cp_reset
	    || !pdata->gpio_pda_active || !pdata->gpio_phone_active
	    || !pdata->gpio_ap_wakeup || !pdata->gpio_ap_status
	    || !pdata->gpio_cp_wakeup || !pdata->gpio_cp_status) {
		mif_err("ERR! no GPIO data\n");
		mif_err("xxx\n");
		return -ENXIO;
	}

	mc->gpio_cp_on = pdata->gpio_cp_on;
	mc->gpio_cp_reset = pdata->gpio_cp_reset;
	mc->gpio_pda_active = pdata->gpio_pda_active;
	mc->gpio_phone_active = pdata->gpio_phone_active;
	mc->gpio_ap_wakeup = pdata->gpio_ap_wakeup;
	mc->gpio_ap_status = pdata->gpio_ap_status;
	mc->gpio_cp_wakeup = pdata->gpio_cp_wakeup;
	mc->gpio_cp_status = pdata->gpio_cp_status;
	mc->gpio_ap_dump_int = pdata->gpio_ap_dump_int;

	gpio_set_value(mc->gpio_cp_reset, 0);
	gpio_set_value(mc->gpio_cp_on, 0);
	print_mc_state(mc);

	ss300_get_ops(mc);
	dev_set_drvdata(mc->dev, mc);

	wake_lock_init(&mc_wake_lock, WAKE_LOCK_SUSPEND, "ss300_wake_lock");
	mc->wake_lock = &mc_wake_lock;

	irq = gpio_to_irq(mc->gpio_phone_active);
	if (!irq) {
		mif_err("ERR! no irq_cp_active\n");
		mif_err("xxx\n");
		return -EINVAL;
	}
	mif_err("PHONE_ACTIVE IRQ# = %d\n", irq);

	mc->event_nfb.notifier_call = modemctl_notify_call;
	register_cp_crash_notifier(&mc->event_nfb);

	flag = IRQF_TRIGGER_RISING | IRQF_NO_THREAD | IRQF_NO_SUSPEND;
	snprintf(name, MAX_NAME_LEN, "%s_active", mc->name);
	mif_init_irq(&mc->irq_cp_active, irq, name, flag);

	ret = mif_request_irq(&mc->irq_cp_active, cp_active_handler, mc);
	if (ret) {
		mif_err("%s: ERR! request_irq(%s#%d) fail (%d)\n",
			mc->name, mc->irq_cp_active.name,
			mc->irq_cp_active.num, ret);
		mif_err("xxx\n");
		return ret;
	}

	mif_err("---\n");
	return 0;
}