コード例 #1
0
static void link_pm_reconnect_work(struct work_struct *work)
{
	struct link_pm_data *pm_data =
		container_of(work, struct link_pm_data,
					link_reconnect_work.work);
	struct modem_ctl *mc = if_usb_get_modemctl(pm_data);

	if (!mc || pm_data->usb_ld->if_usb_connected)
		return;

	if (pm_data->usb_ld->ld.com_state != COM_ONLINE)
		return;

	if (pm_data->link_reconnect_cnt--) {
		if (mc->phone_state == STATE_ONLINE &&
						!pm_data->link_reconnect())
			/* try reconnect and check */
			schedule_delayed_work(&pm_data->link_reconnect_work,
							msecs_to_jiffies(500));
		else	/* under cp crash or reset, just return */
			return;
	} else {
		/* try to recover cp */
		mif_err("recover connection: silent reset\n");
		link_pm_change_modem_state(pm_data, STATE_CRASH_RESET);
	}
}
コード例 #2
0
static void link_pm_change_modem_state(struct link_pm_data *pm_data,
						enum modem_state state)
{
	struct modem_ctl *mc = if_usb_get_modemctl(pm_data);

	if (!mc->iod || pm_data->usb_ld->ld.com_state != COM_ONLINE)
		return;

	mif_err("set modem state %d\n", state);
	mc->iod->modem_state_changed(mc->iod, state);
}
コード例 #3
0
static long link_pm_ioctl(struct file *file, unsigned int cmd,
						unsigned long arg)
{
	int value;
	struct link_pm_data *pm_data = file->private_data;
	struct modem_ctl *mc = if_usb_get_modemctl(pm_data);

	mif_info("%x\n", cmd);

	switch (cmd) {
	case IOCTL_LINK_CONTROL_ENABLE:
		if (copy_from_user(&value, (const void __user *)arg,
							sizeof(int)))
			return -EFAULT;
		if (pm_data->link_ldo_enable)
			pm_data->link_ldo_enable(!!value);
		if (pm_data->gpio_link_enable)
			gpio_set_value(pm_data->gpio_link_enable, value);
		break;
	case IOCTL_LINK_CONTROL_ACTIVE:
		if (copy_from_user(&value, (const void __user *)arg,
							sizeof(int)))
			return -EFAULT;
		gpio_set_value(pm_data->gpio_link_active, value);
		break;
	case IOCTL_LINK_GET_HOSTWAKE:
		return !gpio_get_value(pm_data->gpio_link_hostwake);
	case IOCTL_LINK_CONNECTED:
		return pm_data->usb_ld->if_usb_connected;
	case IOCTL_LINK_SET_BIAS_CLEAR:
		if (copy_from_user(&value, (const void __user *)arg,
							sizeof(int)))
			return -EFAULT;
		if (value) {
			gpio_direction_output(pm_data->gpio_link_slavewake, 0);
			gpio_direction_output(pm_data->gpio_link_hostwake, 0);
		} else {
			gpio_direction_output(pm_data->gpio_link_slavewake, 0);
			gpio_direction_input(pm_data->gpio_link_hostwake);
			irq_set_irq_type(pm_data->irq_link_hostwake,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING);
		}
	case IOCTL_LINK_GET_PHONEACTIVE:
		return gpio_get_value(mc->gpio_phone_active);
	default:
		break;
	}

	return 0;
}
コード例 #4
0
static void link_pm_force_cp_dump(struct link_pm_data *pm_data)
{
	struct modem_ctl *mc = if_usb_get_modemctl(pm_data);

	mif_err("Set modem crash ap_dump_int by %pF\n",
		__builtin_return_address(0));

	if (mc->gpio_ap_dump_int) {
		if (gpio_get_value(mc->gpio_ap_dump_int)) {
			gpio_set_value(mc->gpio_ap_dump_int, 0);
			msleep(20);
		}
		gpio_set_value(mc->gpio_ap_dump_int, 1);
		msleep(20);
		mif_err("AP_DUMP_INT(%d)\n",
			gpio_get_value(mc->gpio_ap_dump_int));
		gpio_set_value(mc->gpio_ap_dump_int, 0);
	}
}
コード例 #5
0
	return 0;
}

static const struct file_operations link_pm_fops = {
	.owner = THIS_MODULE,
	.open = link_pm_open,
	.release = link_pm_release,
	.unlocked_ioctl = link_pm_ioctl,
};

static int link_pm_notifier_event(struct notifier_block *this,
				unsigned long event, void *ptr)
{
	struct link_pm_data *pm_data =
			container_of(this, struct link_pm_data,	pm_notifier);
	struct modem_ctl *mc = if_usb_get_modemctl(pm_data);

	switch (event) {
	case PM_SUSPEND_PREPARE:
#ifdef CONFIG_HIBERNATION
	case PM_HIBERNATION_PREPARE:
	case PM_RESTORE_PREPARE:
#endif
		pm_data->dpm_suspending = true;
		/* set PDA Active High if previous state was LPA */
		if (!gpio_get_value(pm_data->gpio_link_active)) {
			mif_info("PDA active High to LPA suspend spot\n");
			gpio_set_value(mc->gpio_pda_active, 1);
		}
		mif_debug("dpm suspending set to true\n");
		return NOTIFY_OK;