问题:手机作为otg host时,怎样才能进入待机休眠?

参考高通文档:《80-NF283-1_C_Linux_USB_Implementation_Guide》
section: 7.1.2 Host mode state transition
As shown in Figure 7-1, the USB enters LPM when:
●The USB A-Cable is removed, with or without a B-Device connected.
●USB bus suspend – USB Host mode provides the Autosuspend feature via CONFIG_USB_SUSPEND, defined by default. The host controller driver monitors each device connected on the bus and, if any device is idle for a period more than a predefined timeout, it selectively suspends the device. However, if any one of the drivers corresponding to an interface in the USB device does not support Autosuspend, the device cannot be suspended. The mass storage driver does not support Autosuspend.Hence, if a mass storage device is connected, it is not suspended. The HUB driver supports Autosuspend. More information is available at Documentation/usb/power-management.txt.

高通case回复Answer:
Linux Android USB host driver stack(UHCI&EHCI&XHCI) have support for suspend/power collapse, but most device class drivers do not enabled auto suspend. We need to enable autosuspend for those devices,can call usb_enable_autosuspend() function in the driver device probe routine.

An example for HID device is as below:(如下的例子是一个HID设备休眠的修改)

drivers/hid/usbhid/hid-core.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ff052c8…399d964 100644
— a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1338,6 +1338,9 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
goto err_free;
}

+/* enable suspend/resume support for HID devices. */
+usb_enable_autosuspend(dev);

return 0;
err_free:
kfree(usbhid);
@@ -1349,11 +1352,13 @@ err:
static void usbhid_disconnect(struct usb_interface *intf)
{
struct hid_device *hid = usb_get_intfdata(intf);
+struct usb_device *dev = interface_to_usbdev(intf);
struct usbhid_device *usbhid;

if (WARN_ON(!hid))
return;

+usb_disable_autosuspend(dev);
usbhid = hid->driver_data;
hid_destroy_device(hid);
kfree(usbhid);
按照上面的修改后,otg侧连上鼠标是可以进入休眠了,主机功耗满足要求;点击鼠标是可以正常唤醒手机的。

注意点1
on 8994/8992, host bus suspend is not supported due to some HW issue.

static int dwc3_otg_start_host(struct usb_otg *otg, int on)
{…
/**
*WORKAROUND: currently host mode suspend isn't working well.
*Disable xHCI's runtime PM for now.
*/
pm_runtime_disable(&dwc->xhci->dev);

注意点2
需要检查设备是否支持remotewakeup,如果不支持的话,autosuspend就不会执行下去的。autosuspend_check函数会去检查设备是否支持remotewakeup:

if (w && !device_can_wakeup(&udev->dev)) {dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n");
return -EOPNOTSUPP;
}

看这个结构体:

static const struct dev_pm_ops usb_device_pm_ops = {.prepare = usb_dev_prepare,.complete = usb_dev_complete,.suspend = usb_dev_suspend,.resume = usb_dev_resume,.freeze = usb_dev_freeze,.thaw =  usb_dev_thaw,.poweroff = usb_dev_poweroff,.restore = usb_dev_restore,.runtime_suspend = usb_runtime_suspend,.runtime_resume = usb_runtime_resume,.runtime_idle =  usb_runtime_idle,
};

在执行suspend的函数usb_runtime_suspend中会去检查设备是否支持remotewakeup :
usb_runtime_suspend -->

 if (autosuspend_check(udev) != 0)return -EAGAIN;

如果不支持remotewakeup ,autosuspend就不会执行。

autosuspend_check -->

if (w && !device_can_wakeup(&udev->dev)) {dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n");return -EOPNOTSUPP;}

device_can_wakeup读取的是设备模型中的成员:can_wakeup
(include/Linux/pm.h文件)

struct dev_pm_info {pm_message_t power_state;
unsigned can_wakeup:1;
#ifdef CONFIG_PM
unsigned should_wakeup:1;
pm_message_t prev_state;
void * saved_state;
struct device * pm_parent;
struct list_head entry;
#endif
};

在配置描述符中,USB设备将是否支持remote wakeup的能力报告给主机。在设备注册时赋值给can_wakeup的。

移远EC20模块的功能说明:

这里说的是如果主机不支持usb remote wakeup就需要RI信号来唤醒主机,因为这样情况下主机的usb控制器, phy都可以进入休眠状态。 关闭相关clock时钟, 甚至断电,必须通过外部中断来唤醒;

如果需要支持usb remote wakeup, 则主机侧不能完全断电, 需要留下部分底电流, 当usb外设发出request wakeup请求后, 能通过usbphy->usb controller->cpu 将整体系统唤醒。 (常见如个人电脑产品, 基本都支持usb鼠标键盘唤醒)

由于设备都是被动响应主机的命令,想要进入suspend状态,就要控制主机不要发数据包以及令牌包。USB在上行总线上监测到一个连续的空闲状态至少持续了3.0ms时,开始转入挂起状态,在总线无活动后的10ms内被真正挂起。主机可以通过停止所有的传输(包括SOF令牌包)来启动全局挂起,或者是通过主机向集线器端口发出SetPortFeature请求来实现选择性挂起。

8953作为otg连接usb modem的休眠
usb modem连接8953注册的是tty设备,对应驱动在:
kernel/msm-4.9/drivers/usb/serial/usb-serial.c
按照高通的修改,需要在probe函数中使能autosuspend。

diff --git a/kernel/msm-4.9/drivers/usb/serial/usb-serial.c b/kernel/msm-4.9/drivers/usb/serial/usb-serial.c
old mode 100644
new mode 100755
index 4a037b4a79..761968f839
--- a/kernel/msm-4.9/drivers/usb/serial/usb-serial.c
+++ b/kernel/msm-4.9/drivers/usb/serial/usb-serial.c
@@ -1080,6 +1080,14 @@ static int usb_serial_probe(struct usb_interface *interface,if (num_ports > 0)usb_serial_console_init(serial->port[0]->minor);
+
+       //stone added
+       /* enable suspend/resume support */
+       if (device_can_wakeup(&dev->dev)) {+               printk(KERN_ERR "-----sy:usb device can remote wakeup------\n");
+       }
+       usb_enable_autosuspend(dev);
+exit:module_put(type->driver.owner);return 0;
@@ -1098,6 +1106,9 @@ static void usb_serial_disconnect(struct usb_interface *interface)struct usb_serial_port *port;struct tty_struct *tty;+       //stone added
+       struct usb_device *usb_dev = interface_to_usbdev(interface);
+usb_serial_console_disconnect(serial);mutex_lock(&serial->disc_mutex);
@@ -1121,6 +1132,9 @@ static void usb_serial_disconnect(struct usb_interface *interface)if (serial->type->disconnect)serial->type->disconnect(serial);+       //stone added
+       usb_disable_autosuspend(usb_dev);
+/* let the last holder of this object cause it to be cleaned up */usb_serial_put(serial);dev_info(dev, "device disconnected\n");

android 9.0上usb otg休眠问题相关推荐

  1. 解决unity 打包在Android 8.0上启动出现黑屏问题(Android权限弹窗问题)

    解决unity 打包在Android 8.0上启动出现黑屏问题 本文链接:https://blog.csdn.net/baidu_34248947/article/details/89377983 我 ...

  2. Android 5.0 上 Failure [INSTALL_FAILED_DUPLICATE_PERMISSION的问题

    今天在新的Android 5.0上调试程序的时候,安装一个程序,出现了Failure [INSTALL_FAILED_DUPLICATE_PERMISSION]的错误,但是在以前的Android4.4 ...

  3. Android手机插上usb能充电但不能识别的一种解决方法

    Android手机插上usb能充电但不能识别的一种解决方法 参考文章: (1)Android手机插上usb能充电但不能识别的一种解决方法 (2)https://www.cnblogs.com/JOUO ...

  4. 通过OTG接口进入Android系统,Android4.0.3 USB OTG底层插入上报过程分析(1)

    下面的两个宏是PM8058的MMP11(R15),MMP12(P15)管脚. #define EXT_CHG_VALID_MPP 10 #define EXT_CHG_VALID_MPP_2 11 s ...

  5. Android4.0.3 USB OTG底层插入上报过程分析(1)

    下面的两个宏是PM8058的MMP11(R15),MMP12(P15)管脚. #define EXT_CHG_VALID_MPP 10 #define EXT_CHG_VALID_MPP_2 11 s ...

  6. android 4.0.4 usb调试,安卓手机4.0怎么打开usb调试?图文详解附视频

    安卓手机更新换代的太快,系统每次升级多少会有点不同 总会有那么点不适应,就连如何调试USB都不知道怎么设置了? 下面就来就讲讲目前主流品牌手机4.0手机USB调试. 大部分Android设备打开&qu ...

  7. [更新]android平板手机 通过usb otg 来充电(以nexus 7 一代为例USB ROM)

    默认的andorid rom一般不支持需要自己打补丁,刷rom.当然大牛都把这样的rom弄好了咱们直接进recovery刷zip文件就ok了.本来我是用nexus 7 dock华硕官方的底座给nexu ...

  8. 教你如何在Android 6.0上创建系统悬浮窗

    郭霖大神的文章:http://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650235949&idx=1&sn=0f7eded ...

  9. 关于 android 6.0 上的 nuplayer 播放时的图像卡顿

    作为一个和 android nuplayer 打了 N年交道, 自以为已经上古司机的老码农, 这一次居然被坑了一个礼拜: 事情描述起来很简单, 测试人员突然发现目前的版本,播放很多视频都卡顿, 由于该 ...

最新文章

  1. class function或class procedure是什么意思
  2. Hadoop运维记录系列(十二)
  3. python可以自学吗-python自学行吗 新手可以自学python吗
  4. 获得程序运行结果的返回值
  5. DM8168_ETV_V1.1开发板mount主机常见问题
  6. html5 实现坦克大战,HTML5实现坦克大战(一)
  7. vb6 combo根据index显示选项内容_按指定次数重复显示,两种方法随意选
  8. 系统起动时加载的过程
  9. SyntaxError: ‘return‘ outside function 在python里面的报错问题
  10. 纯css解决div隐藏浏览器原生滚动条,但保留鼠标滚动效果的问题
  11. LNMP(linux+nginx+mysql+php)服务器环境配置
  12. ODA(Open Design Alliance)介绍
  13. Python对象转json【包括嵌套对象转json,django的model转json】
  14. 杀OSO.EXE和conime.exe过程总结
  15. openoffic+java+spring 多线程 转换doc,ppt,xls - html/pdf
  16. c语言fabs函数的返回值,关于c语言中fabs函数的用法
  17. Batch Normalization详解(原理+实验分析)
  18. C语言关闭终端回显【转】
  19. java编程实现斗地主发牌
  20. PS怎么快速把多个图层形状以中心点缩放

热门文章

  1. 又把她拍丑了?试试蒙太奇风格给照片提高一个逼格吧~
  2. 248-h215 第k大元素
  3. 非接触超声技术用于电池质量检测
  4. http://www.scxp.com/google.htm
  5. Python:浮点数保留小数位数的方法整理
  6. Latex特殊符号输入手册
  7. 小程序上传图片裁剪工具 we-cropper的使用方法
  8. Android recyclerView曝光统计
  9. Adobe推出了PS新功能Generative Fill(创成式填充);生成式 AI 将改变电脑架构;
  10. PDF转Word怎么调整格式?这个方法轻松解决