usb: dwc3-msm: Add external client ID event notification

Some peripherals share the USB connector, such as MHL, in which the ID
pin is queried for voltage level determining the type of cable
connected. Support this by allowing these peripherals to act as clients
that can register for ID event notification.

The registered callback is called upon ID state change, and when it
returns 0, USB assumes the client is now handling the connection from
this point. When the client is done, it will call the USB callback
(passed as function parameter) indicating offline, at which point USB
can continue to assume a USB connection.

Change-Id: I4abe2c8ba9610ffa28895dfeb641fb625ada7c51
Signed-off-by: Jack Pham <jackp@codeaurora.org>
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index f2eda50..bcbdec4 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -483,12 +483,35 @@
 	MAX_BAMS,
 };
 
+/**
+ * struct usb_ext_notification: event notification structure
+ * @notify: pointer to client function to call when ID event is detected.
+ *          The last parameter is provided by driver to be called back when
+ *          external client indicates it is done using the USB. This function
+ *          should return 0 if handled successfully, otherise an error code.
+ * @ctxt: client-specific context pointer
+ *
+ * This structure should be used by clients wishing to register (via
+ * msm_register_usb_ext_notification) for event notification whenever a USB
+ * cable is plugged in and ID pin status changes. Clients must provide a
+ * callback function pointer. If this callback returns 0, the USB driver will
+ * assume the client is "taking over" the connection, and will relinquish any
+ * further processing until its callback (passed via the third parameter) is
+ * called with the online parameter set to false.
+ */
+struct usb_ext_notification {
+	int (*notify)(void *, int, void (*)(int online));
+	void *ctxt;
+};
+
 #ifdef CONFIG_USB_DWC3_MSM
 int msm_ep_config(struct usb_ep *ep);
 int msm_ep_unconfig(struct usb_ep *ep);
 int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size,
 	u8 dst_pipe_idx);
 
+int msm_register_usb_ext_notification(struct usb_ext_notification *info);
+
 #else
 static inline int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size,
 	u8 dst_pipe_idx)
@@ -505,5 +528,11 @@
 {
 	return -ENODEV;
 }
+
+static inline int msm_register_usb_ext_notification(
+					struct usb_ext_notification *info)
+{
+	return -ENODEV;
+}
 #endif
 #endif