usb: gadget: Implement remote wakeup in mbim
Implement remote wake up in mbim.
Add required changes in ecm and rndis to comply to
a new structure of data_port in u_bam_data.
CRs-fixed: 396623
Change-Id: I2e182e78ed0fbd8524a3857f104b951ad5bdff4d
Signed-off-by: Anna Perel <aperel@codeaurora.org>
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 6883b78..7a84ca3 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -67,8 +67,8 @@
};
struct f_mbim {
- struct usb_function function;
- struct usb_composite_dev *cdev;
+ struct usb_function function;
+ struct usb_composite_dev *cdev;
atomic_t online;
bool is_open;
@@ -1255,6 +1255,20 @@
pr_info("mbim deactivated\n");
}
+#define MBIM_ACTIVE_PORT 0
+
+static void mbim_suspend(struct usb_function *f)
+{
+ pr_info("mbim suspended\n");
+ bam_data_suspend(MBIM_ACTIVE_PORT);
+}
+
+static void mbim_resume(struct usb_function *f)
+{
+ pr_info("mbim resumed\n");
+ bam_data_resume(MBIM_ACTIVE_PORT);
+}
+
/*---------------------- function driver setup/binding ---------------------*/
static int
@@ -1288,6 +1302,8 @@
mbim_data_intf.bInterfaceNumber = status;
mbim_union_desc.bSlaveInterface0 = status;
+ mbim->bam_port.cdev = cdev;
+
status = -ENODEV;
/* allocate instance-specific endpoints */
@@ -1461,6 +1477,8 @@
mbim->function.get_alt = mbim_get_alt;
mbim->function.setup = mbim_setup;
mbim->function.disable = mbim_disable;
+ mbim->function.suspend = mbim_suspend;
+ mbim->function.resume = mbim_resume;
INIT_LIST_HEAD(&mbim->cpkt_req_q);
INIT_LIST_HEAD(&mbim->cpkt_resp_q);
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 98a29ae..7fedaf6 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -305,7 +305,7 @@
{
int ret;
- ecm_qc_bam_port.func = dev->port.func;
+ ecm_qc_bam_port.cdev = dev->port.func.config->cdev;
ecm_qc_bam_port.in = dev->port.in_ep;
ecm_qc_bam_port.out = dev->port.out_ep;
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index a740d95..60b96fe 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -417,7 +417,7 @@
{
int ret;
- rndis_qc_bam_port.func = dev->port.func;
+ rndis_qc_bam_port.cdev = dev->port.func.config->cdev;
rndis_qc_bam_port.in = dev->port.in_ep;
rndis_qc_bam_port.out = dev->port.out_ep;
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index a105f5d..32f683e 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -35,7 +35,7 @@
#define MSM_VENDOR_ID BIT(16)
struct data_port {
- struct usb_function func;
+ struct usb_composite_dev *cdev;
struct usb_ep *in;
struct usb_ep *out;
};
@@ -326,3 +326,54 @@
return ret;
}
+static int bam_data_wake_cb(void *param)
+{
+ struct bam_data_port *port = (struct bam_data_port *)param;
+ struct data_port *d_port = port->port_usb;
+
+ pr_info("%s: woken up by peer\n", __func__);
+
+ if (!d_port) {
+ pr_err("FAILED: d_port == NULL");
+ return -ENODEV;
+ }
+
+ if (!d_port->cdev) {
+ pr_err("FAILED: d_port->cdev == NULL");
+ return -ENODEV;
+ }
+
+ if (!d_port->cdev->gadget) {
+ pr_err("FAILED: d_port->cdev->gadget == NULL");
+ return -ENODEV;
+ }
+
+ return usb_gadget_wakeup(d_port->cdev->gadget);
+}
+
+void bam_data_suspend(u8 port_num)
+{
+
+ struct bam_data_port *port;
+ struct bam_data_ch_info *d;
+
+ port = bam2bam_data_ports[port_num];
+ d = &port->data_ch;
+
+ pr_info("%s: suspended port %d\n", __func__, port_num);
+ usb_bam_register_wake_cb(d->connection_idx, bam_data_wake_cb, port);
+}
+
+void bam_data_resume(u8 port_num)
+{
+
+ struct bam_data_port *port;
+ struct bam_data_ch_info *d;
+
+ port = bam2bam_data_ports[port_num];
+ d = &port->data_ch;
+
+ pr_info("%s: resumed port %d\n", __func__, port_num);
+ usb_bam_register_wake_cb(d->connection_idx, NULL, NULL);
+}
+