usb: gsi: Add debugfs support for remote wakeup on each interface

The new version of the compliance suite expects each
interface that advertises the remote wakeup capability
to generate a remote wakeup event in Superspeed mode.
The compliance suite ensures this by selectively
suspending each interface at a time and then expects
the interface to initiate a remote wakeup.
The current debugfs implementation though initiates
remote wakeup only on the first connected interface.

Hence change the implementation to initiate remote
wakeup by the interface which is selectively suspended
by the host in Superspeed mode. Whereas in Highspeed
mode initiate remote wakeup on the first connected
interface.

Change-Id: I45797e867aee17c5dcc592fe1e08b5a3943b4a8b
Signed-off-by: Sriharsha Allenki <sallenki@codeaurora.org>
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
This commit is contained in:
Sriharsha Allenki 2019-08-26 12:13:44 +05:30 • committed by Mayank Rana
commit 07ac92de11

View file

@ -204,41 +204,30 @@ static void gsi_rw_timer_func(struct timer_list *t)
static struct f_gsi *get_connected_gsi(void)
{
struct f_gsi *connected_gsi;
bool gsi_connected = false;
int i;
for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++) {
if (inst_status[i].opts)
connected_gsi = inst_status[i].opts->gsi;
else
continue;
if (connected_gsi && atomic_read(&connected_gsi->connected)) {
gsi_connected = true;
break;
}
if (connected_gsi && atomic_read(&connected_gsi->connected))
return connected_gsi;
}
if (!gsi_connected)
connected_gsi = NULL;
return connected_gsi;
return NULL;
}
#define DEFAULT_RW_TIMER_INTERVAL 500 /* in ms */
static ssize_t usb_gsi_rw_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
struct f_gsi *gsi;
struct f_gsi *gsi = NULL;
struct usb_function *func;
struct usb_gadget *gadget;
u8 input;
int i;
int ret;
gsi = get_connected_gsi();
if (!gsi) {
log_event_dbg("%s: gsi not connected\n", __func__);
goto err;
}
if (ubuf == NULL) {
log_event_dbg("%s: buffer is Null.\n", __func__);
goto err;
@ -250,23 +239,35 @@ static ssize_t usb_gsi_rw_write(struct file *file,
goto err;
}
if (gsi->debugfs_rw_timer_enable == !!input) {
if (!!input)
log_event_dbg("%s: RW already enabled\n", __func__);
else
log_event_dbg("%s: RW already disabled\n", __func__);
goto err;
}
for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++) {
gsi = NULL;
if (inst_status[i].opts)
gsi = inst_status[i].opts->gsi;
gsi->debugfs_rw_timer_enable = !!input;
if (gsi && atomic_read(&gsi->connected)) {
func = &gsi->function;
gadget = func->config->cdev->gadget;
gsi->debugfs_rw_timer_enable = !!input;
if (gadget->speed >= USB_SPEED_SUPER &&
!gsi->func_is_suspended) {
gsi->debugfs_rw_timer_enable = 0;
del_timer_sync(&gsi->gsi_rw_timer);
continue;
}
if (gsi->debugfs_rw_timer_enable) {
mod_timer(&gsi->gsi_rw_timer, jiffies +
msecs_to_jiffies(gsi->gsi_rw_timer_interval));
log_event_dbg("%s: timer initialized\n", __func__);
} else {
del_timer_sync(&gsi->gsi_rw_timer);
log_event_dbg("%s: timer deleted\n", __func__);
if (gsi->debugfs_rw_timer_enable) {
mod_timer(&gsi->gsi_rw_timer, jiffies +
msecs_to_jiffies(gsi->gsi_rw_timer_interval));
log_event_dbg("%s: timer initialized\n",
__func__);
} else {
del_timer_sync(&gsi->gsi_rw_timer);
log_event_dbg("%s: timer deleted\n", __func__);
}
if (gadget->speed < USB_SPEED_SUPER)
break;
}
}
err:
@ -277,14 +278,19 @@ static int usb_gsi_rw_show(struct seq_file *s, void *unused)
{
struct f_gsi *gsi;
int i;
u8 enable = 0;
gsi = get_connected_gsi();
if (!gsi) {
log_event_dbg("%s: gsi not connected\n", __func__);
return 0;
for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++) {
gsi = NULL;
if (inst_status[i].opts)
gsi = inst_status[i].opts->gsi;
if (gsi && atomic_read(&gsi->connected))
enable |= gsi->debugfs_rw_timer_enable;
}
seq_printf(s, "%d\n", gsi->debugfs_rw_timer_enable);
seq_printf(s, "%d\n", enable);
return 0;
}
@ -306,16 +312,11 @@ static const struct file_operations fops_usb_gsi_rw = {
static ssize_t usb_gsi_rw_timer_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
struct f_gsi *gsi;
struct f_gsi *gsi = NULL;
u16 timer_val;
int i;
int ret;
gsi = get_connected_gsi();
if (!gsi) {
log_event_dbg("%s: gsi not connected\n", __func__);
goto err;
}
if (ubuf == NULL) {
log_event_dbg("%s: buffer is NULL.\n", __func__);
goto err;
@ -332,7 +333,15 @@ static ssize_t usb_gsi_rw_timer_write(struct file *file,
goto err;
}
gsi->gsi_rw_timer_interval = timer_val;
for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++) {
gsi = NULL;
if (inst_status[i].opts)
gsi = inst_status[i].opts->gsi;
if (gsi && atomic_read(&gsi->connected))
gsi->gsi_rw_timer_interval = timer_val;
}
err:
return count;
}