MLK-10102-10 usb: chipidea: otg: Add power lost support for otg fsm mode
authorLi Jun <jun.li@freescale.com>
Thu, 15 Jan 2015 13:27:40 +0000 (21:27 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:46:59 +0000 (14:46 -0500)
This patch adds support of power lost during system sleep in otg fsm mode.

Signed-off-by: Li Jun <b47624@freescale.com>
(cherry picked from commit 493f3c4f04f48240dacc49f84db57e7ecf90161b)

drivers/usb/chipidea/core.c
drivers/usb/chipidea/otg_fsm.c
drivers/usb/chipidea/otg_fsm.h
include/linux/usb/otg-fsm.h

index 284830d..e5fdeb3 100644 (file)
@@ -899,6 +899,8 @@ static void ci_power_lost_work(struct work_struct *work)
        pm_runtime_get_sync(ci->dev);
        if (!ci_otg_is_fsm_mode(ci))
                ci_start_new_role(ci);
+       else
+               ci_hdrc_otg_fsm_restart(ci);
        pm_runtime_put_sync(ci->dev);
        enable_irq(ci->irq);
 }
index bf8a03c..ea1594a 100644 (file)
@@ -31,6 +31,7 @@
 #include "udc.h"
 #include "otg_fsm.h"
 #include "udc.h"
+#include "host.h"
 
 /* Add for otg: interact with user space app */
 static ssize_t
@@ -867,3 +868,39 @@ void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci)
 {
        sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group);
 }
+
+/* Restart OTG fsm if resume from power lost */
+void ci_hdrc_otg_fsm_restart(struct ci_hdrc *ci)
+{
+       struct otg_fsm *fsm = &ci->fsm;
+       int id_status = fsm->id;
+
+       /* Update fsm if power lost in peripheral state */
+       if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) {
+               fsm->b_sess_vld = 0;
+               otg_statemachine(fsm);
+       }
+
+       hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);
+       hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE);
+
+       /* Update fsm variables for restart */
+       fsm->id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
+       if (fsm->id) {
+               fsm->b_ssend_srp =
+                       hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1;
+               fsm->b_sess_vld =
+                       hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0;
+       } else if (fsm->id != id_status) {
+               /* ID changes to be 0 */
+               fsm->a_bus_drop = 0;
+               fsm->a_bus_req = 1;
+               ci->id_event = true;
+       }
+
+       if (ci_hdrc_host_has_device(ci) &&
+                       !hw_read(ci, OP_PORTSC, PORTSC_CCS))
+               fsm->b_conn = 0;
+
+       ci_otg_fsm_work(ci);
+}
index 6366fe3..7be894a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
  *
  * Author: Jun Li
  *
@@ -71,6 +71,7 @@ int ci_otg_fsm_work(struct ci_hdrc *ci);
 irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci);
 void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci);
 void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci);
+void ci_hdrc_otg_fsm_restart(struct ci_hdrc *ci);
 
 #else
 
@@ -99,6 +100,11 @@ static inline void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci)
 
 }
 
+static inline void ci_hdrc_otg_fsm_restart(struct ci_hdrc *ci)
+{
+
+}
+
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_OTG_FSM_H */
index 7a03505..62e6f8c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc.
+/* Copyright (C) 2007-2015 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the