Пример #1
0
int smdhsic_reset_resume(struct usb_interface *intf)
{
	unsigned int devid;
	struct str_intf_priv *intfpriv;
	struct device *dev = &g_usbdev.usbdev->dev;

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

	if (!g_usbdev.suspended)
		return 0;

	intfpriv = usb_get_intfdata(intf);
	devid = GET_DEVID(intfpriv->devid);

	if (!usb_runtime_pm_ap_initiated_L2 &&
		atomic_read(&dev->power.usage_count) == 1)
		pm_runtime_get_noresume(dev);

	smdhsic_resume(intf);

	if (devid == CMD_DEV_ID) {
		g_usbdev.hsic->dpm_suspending = false;
		pr_debug("%s : dpm suspending set to false\n", __func__);
	}

	return 0;
}
Пример #2
0
static int smdhsic_resume(struct usb_interface *interface)
{
	int r = 0;
	unsigned int devid;
	struct str_smdipc *smdipc;
	struct str_smdrfs *smdrfs;
	struct str_smdcmd *smdcmd;
	struct str_smdraw *smdraw;
	struct str_intf_priv *intfpriv;

	intfpriv = usb_get_intfdata(interface);
	devid = GET_DEVID(intfpriv->devid);

	switch (devid) {
	case FMT_DEV_ID:
		smdipc = intfpriv->data;
		if (!smdipc->suspended)
			return 0;
		wake_lock(&smdipc->wakelock);
		g_usbdev.suspended--;
		smdipc->suspended = 0;
		r = smdipc_resume(smdipc);
		pr_debug("SMDHSIC RES FMT_DEV(%d)\n", g_usbdev.suspended);
		break;
	case RAW_DEV_ID:
		smdraw = intfpriv->data;
		if (!smdraw->suspended)
			return 0;
		wake_lock(&smdraw->wakelock);
		smdraw->suspended = 0;
		g_usbdev.suspended--;
		r = smdraw_resume(smdraw);
		pr_debug("SMDHSIC RES RAW_DEV(%d)\n", g_usbdev.suspended);
		break;
	case RFS_DEV_ID:
		smdrfs = intfpriv->data;
		if (!smdrfs->suspended)
			return 0;
		wake_lock(&smdrfs->wakelock);
		smdrfs->suspended = 0;
		g_usbdev.suspended--;
		r = smdrfs_resume(smdrfs);
		pr_debug("SMDHSIC RES RFS_DEV(%d)\n", g_usbdev.suspended);
		break;
	case CMD_DEV_ID:
		smdcmd = intfpriv->data;
		if (!smdcmd->suspended)
			return 0;
		wake_lock(&smdcmd->wakelock);
		smdcmd->suspended = 0;
		g_usbdev.suspended--;
		r = smdcmd_resume(smdcmd);
		pr_debug("SMDHSIC RES CMD_DEV(%d)\n", g_usbdev.suspended);
		smdctl_set_pm_status(PM_STATUS_L0);
	default:
		break;
	}
	return r;
}
Пример #3
0
static struct usb_interface *get_usb_intf(struct str_intf_priv *intfpriv)
{
	unsigned int devid = intfpriv->devid;
	struct str_smdipc *smdipc;
	struct str_smd_down *smddown;
	struct str_smdrfs *smdrfs;
	struct str_smdcmd *smdcmd;
	struct str_smdraw *smdraw;

	if (devid & ID_PRI) {
		struct str_hsic *hsic = intfpriv->data;
		return hsic->intf;
	}

	switch (GET_DEVID(devid)) {
	case FMT_DEV_ID:
		smdipc = (struct str_smdipc *)intfpriv->data;
		return smdipc->hsic.intf;
	case RAW_DEV_ID:
		smdraw = (struct str_smdraw *)intfpriv->data;
		return smdraw->hsic.intf;
	case RFS_DEV_ID:
		smdrfs = (struct str_smdrfs *)intfpriv->data;
		return smdrfs->hsic.intf;
	case CMD_DEV_ID:
		smdcmd = (struct str_smdcmd *)intfpriv->data;
		return smdcmd->hsic.intf;
	case DOWN_DEV_ID:
		smddown = (struct str_smd_down *)intfpriv->data;
		return smddown->hsic.intf;
	default:
		pr_err("%s:Undefined DEVID: %d\n", __func__,
		       GET_DEVID(devid));
	}

	return NULL;
}
Пример #4
0
static int smdhsic_suspend(struct usb_interface *interface,
			   pm_message_t message)
{
	int r = 0;
	unsigned int devid;
	struct str_smdipc *smdipc;
	struct str_smdrfs *smdrfs;
	struct str_smdcmd *smdcmd;
	struct str_smdraw *smdraw;
	struct str_intf_priv *intfpriv;

	intfpriv = usb_get_intfdata(interface);
	devid = GET_DEVID(intfpriv->devid);

	switch (devid) {
	case FMT_DEV_ID:
		smdipc = intfpriv->data;
		if (smdipc->suspended)
			return 0;
		r = smdipc_suspend(smdipc);
		pr_debug("SMDHSIC SUS FMT_DEV(%d)\n", g_usbdev.suspended);
		wake_unlock(&smdipc->wakelock);
		smdipc->suspended = 1;
		g_usbdev.suspended++;
		smdctl_set_pm_status(PM_STATUS_L2);
		break;
	case RAW_DEV_ID:
		smdraw = intfpriv->data;
		if (smdraw->suspended)
			return 0;
		r = smdraw_suspend(smdraw);
		pr_debug("SMDHSIC SUS RAW_DEV(%d)\n", g_usbdev.suspended);
		wake_unlock(&smdraw->wakelock);
		smdraw->suspended = 1;
		g_usbdev.suspended++;
		break;
	case RFS_DEV_ID:
		smdrfs = intfpriv->data;
		if (smdrfs->suspended)
			return 0;
		r = smdrfs_suspend(smdrfs);
		pr_debug("SMDHSIC SUS RFS_DEV(%d)\n", g_usbdev.suspended);
		wake_unlock(&smdrfs->wakelock);
		smdrfs->suspended = 1;
		g_usbdev.suspended++;
		break;
	case CMD_DEV_ID:
		smdcmd = intfpriv->data;
		if (smdcmd->suspended)
			return 0;
		r = smdcmd_suspend(smdcmd);
		pr_debug("SMDHSIC SUS CMD_DEV(%d)\n", g_usbdev.suspended);
		wake_unlock(&smdcmd->wakelock);
		smdcmd->suspended = 1;
		g_usbdev.suspended++;
	default:
		/* fall through */
		break;
	}

	return r;
}
Пример #5
0
static void smdhsic_disconnect(struct usb_interface *intf)
{
	int devid;
	struct usb_interface *smd_intf;
	struct str_intf_priv *intfpriv;
	struct usb_device *device = NULL;

	pr_info("%s: Called\n", __func__);

	intfpriv = usb_get_intfdata(intf);
	if (!intfpriv) {
		pr_err("%s: intfpriv is NULL\n", __func__);
		goto err_get_intfdata;
	}
	device = get_usb_device(intfpriv);
	devid = GET_DEVID(intfpriv->devid);
	pr_debug("%s : devid : %d\n", __func__, devid);

	smd_intf = get_usb_intf(intfpriv);
	if (!smd_intf) {
		pr_err("smd_intf is NULL\n");
		goto err_get_usb_intf;
	}

	if (smd_intf != intf) {
		pr_err("smd_intf is not same intf\n");
		goto err_mismatched_intf;
	}

	usb_driver_release_interface(get_usb_driver(intf), smd_intf);

	if (!device)
		usb_put_dev(device);

	pm_runtime_disable(&device->dev);
	if (g_usbdev.hsic)
		cancel_delayed_work(&g_usbdev.hsic->pm_runtime_work);

	switch (devid) {
	case FMT_DEV_ID:
		flush_txurb(&g_usbdev.ipc_urbq);
		flush_txurb(&g_usbdev.data_urbq);
		smdctl_request_connection_recover(true);
	case RAW_DEV_ID:
	case RFS_DEV_ID:
	case CMD_DEV_ID:
	case DOWN_DEV_ID:
		if (emu_discon_func[devid])
			emu_discon_func[devid](g_usbdev.smd_device[devid]);
		else
			kfree(intfpriv->data);
		break;
	default:
		pr_warn("%s:Undefined Callback Function\n",
		       __func__);
	}
	/* to prevent sleep at connection recover
	* when, usb suspend and recover routine overlap
	* it makes huge delay on modem reset
	*/
	wake_lock_timeout(&g_usbdev.txwake, 20*HZ);
	kfree(intfpriv);
	usb_set_intfdata(intf, NULL);
	g_usbdev.usbdev = NULL;
	g_usbdev.suspended = 0;
	g_usbdev.hsic = NULL;
	return;

err_mismatched_intf:
err_get_usb_intf:
	if (!device)
		usb_put_dev(device);
err_get_intfdata:
	pr_err("release(2) : %p\n", intf);
	usb_driver_release_interface(get_usb_driver(intf), intf);
	return;
}
Пример #6
0
static void smdhsic_disconnect(struct usb_interface *intf)
{
	int devid;
	struct usb_interface *smd_intf;
	struct str_intf_priv *intfpriv;
	struct usb_device *device = NULL;

	pr_info("%s: Called\n", __func__);

	intfpriv = usb_get_intfdata(intf);
	if (!intfpriv) {
		pr_err("%s: intfpriv is NULL\n", __func__);
		goto err_get_intfdata;
	}
	device = get_usb_device(intfpriv);
	devid = GET_DEVID(intfpriv->devid);
	pr_debug("%s : devid : %d\n", __func__, devid);

	smd_intf = get_usb_intf(intfpriv);
	if (!smd_intf) {
		pr_err("smd_intf is NULL\n");
		goto err_get_usb_intf;
	}

	if (smd_intf != intf) {
		pr_err("smd_intf is not same intf\n");
		goto err_mismatched_intf;
	}

	usb_driver_release_interface(get_usb_driver(intf), smd_intf);

	if (!device)
		usb_put_dev(device);

	switch (devid) {
	case FMT_DEV_ID:
		pm_runtime_disable(&device->dev);
		if (g_usbdev.hsic)
			cancel_delayed_work(&g_usbdev.hsic->pm_runtime_work);

		smdctl_request_connection_recover(true);
	case RAW_DEV_ID:
	case RFS_DEV_ID:
	case CMD_DEV_ID:
	case DOWN_DEV_ID:
		if (emu_discon_func[devid])
			emu_discon_func[devid](g_usbdev.smd_device[devid]);
		else
			kfree(intfpriv->data);
		break;
	default:
		pr_warn("%s:Undefined Callback Function\n",
		       __func__);
	}

	/* Power on/off kernel-panic workaround,
	 * if USB suspend cmd was queued in power.work before disconnect,
	 * reset the runtime PM request value to PM_REQ_NONE
	 */
	device->dev.power.request = RPM_REQ_NONE;

	kfree(intfpriv);
	usb_set_intfdata(intf, NULL);
	g_usbdev.usbdev = NULL;
	g_usbdev.suspended = 0;
	g_usbdev.hsic = NULL;
	return;

err_mismatched_intf:
err_get_usb_intf:
	if (device)
		usb_put_dev(device);
err_get_intfdata:
	pr_err("release(2) : %p\n", intf);
	usb_driver_release_interface(get_usb_driver(intf), intf);
	return;
}