The main design flow is the same with msm otg driver, that is the id and
vbus interrupt are handled at core driver, others are handled by
individual drivers.
- At former design, when switch usb role from device-host, it will call
udc_stop, it will remove the gadget driver, so when switch role
from host-device, it can't add gadget driver any more.
At new design, when role switch occurs, the gadget just calls
usb_gadget_vbus_disconnect/usb_gadget_vbus_connect as well as
reset controller, it will not free any device/gadget structure
- Add vbus connect and disconnect to core interrupt handler, it can
notify udc driver by calling usb_gadget_vbus_disconnect
/usb_gadget_vbus_connect.
Signed-off-by: Peter Chen peter.c...@freescale.com
---
Changes for v4:
- Change the otg event flag from the bitmask to bool flag
- Add some otg helper functions
- Move some hardware init to hw_device_init
- Move the otg init to one block
Changes for v3:
- Add prefix CI_ for ID and B_SESS_VALID
- Use new API hw_wait_reg which is alexander sugguested to wait vbus
voltage stable
drivers/usb/chipidea/bits.h | 10 +++
drivers/usb/chipidea/ci.h |8 ++-
drivers/usb/chipidea/core.c | 177 ++
drivers/usb/chipidea/otg.c | 28 +---
drivers/usb/chipidea/otg.h |3 +
drivers/usb/chipidea/udc.c |2 +
6 files changed, 200 insertions(+), 28 deletions(-)
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 050de85..ba9c6ef 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -65,11 +65,21 @@
#define OTGSC_ASVIS BIT(18)
#define OTGSC_BSVIS BIT(19)
#define OTGSC_BSEIS BIT(20)
+#define OTGSC_1MSIS BIT(21)
+#define OTGSC_DPIS BIT(22)
#define OTGSC_IDIE BIT(24)
#define OTGSC_AVVIE BIT(25)
#define OTGSC_ASVIE BIT(26)
#define OTGSC_BSVIE BIT(27)
#define OTGSC_BSEIE BIT(28)
+#define OTGSC_1MSIE BIT(29)
+#define OTGSC_DPIE BIT(30)
+#define OTGSC_INT_EN_BITS (OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \
+ | OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \
+ | OTGSC_DPIE)
+#define OTGSC_INT_STATUS_BITS (OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS \
+ | OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \
+ | OTGSC_DPIS)
/* USBMODE */
#define USBMODE_CM(0x03UL 0)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 8702871..325d790 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -130,6 +130,7 @@ struct hw_bank {
* @transceiver: pointer to USB PHY, if any
* @hcd: pointer to usb_hcd for ehci host driver
* @otg: for otg support
+ * @events: events for otg, and handled at ci_role_work
*/
struct ci13xxx {
struct device *dev;
@@ -140,6 +141,7 @@ struct ci13xxx {
enum ci_rolerole;
boolis_otg;
struct work_struct work;
+ struct delayed_work dwork;
struct workqueue_struct *wq;
struct dma_pool *qh_pool;
@@ -165,7 +167,9 @@ struct ci13xxx {
boolglobal_phy;
struct usb_phy *transceiver;
struct usb_hcd *hcd;
- struct usb_otg otg;
+ struct usb_otg otg;
+ boolid_event;
+ boolb_sess_valid_event;
};
static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
@@ -314,4 +318,6 @@ int hw_port_test_set(struct ci13xxx *ci, u8 mode);
u8 hw_port_test_get(struct ci13xxx *ci);
+void ci_handle_vbus_change(struct ci13xxx *ci);
+
#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index aebf695..f8f8484 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -73,6 +73,7 @@
#include bits.h
#include host.h
#include debug.h
+#include otg.h
/* Controller register map */
static uintptr_t ci_regs_nolpm[] = {
@@ -199,6 +200,14 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem
*base)
if (ci-hw_ep_max ENDPT_MAX)
return -ENODEV;
+ /* Disable all interrupts bits */
+ hw_write(ci, OP_USBINTR, 0x, 0);
+ ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+
+ /* Clear all interrupts status bits*/
+ hw_write(ci, OP_USBSTS, 0x, 0x);
+ ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+
dev_dbg(ci-dev, ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n,
ci-hw_bank.lpm, ci-hw_bank.cap, ci-hw_bank.op);
@@ -265,24 +274,124 @@ static enum ci_role ci_otg_role(struct ci13xxx *ci)
}
/**
- * ci_role_work - perform role changing based on