diff options
Diffstat (limited to 'drivers/usb/gadget/function/f_diag.c')
| -rw-r--r-- | drivers/usb/gadget/function/f_diag.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/usb/gadget/function/f_diag.c b/drivers/usb/gadget/function/f_diag.c index 3b57ad9c..4aaeb1e5 100644 --- a/drivers/usb/gadget/function/f_diag.c +++ b/drivers/usb/gadget/function/f_diag.c @@ -27,6 +27,13 @@ #include <linux/workqueue.h> #include <linux/debugfs.h> #include <linux/kmemleak.h> +#ifdef CONFIG_DIAG_OVER_TTY +#include <linux/usb/tty_diag.h> +#include <linux/of.h> + +static bool tty_mode; +module_param(tty_mode, bool, S_IRUGO); +#endif static DEFINE_SPINLOCK(ch_lock); static LIST_HEAD(usb_diag_ch_list); @@ -174,6 +181,23 @@ static inline struct diag_context *func_to_diag(struct usb_function *f) return container_of(f, struct diag_context, function); } +#ifdef CONFIG_DIAG_OVER_TTY +static bool factory_cable_present(void) +{ + struct device_node *np; + bool fact_cable; + + np = of_find_node_by_path("/chosen"); + fact_cable = of_property_read_bool(np, "mmi,factory-cable"); + of_node_put(np); + + if (!np || !fact_cable) + return false; + + return true; +} +#endif + /* Called with ctxt->lock held; i.e. only use with kref_put_spinlock_irqsave */ static void diag_context_release(struct kref *kref) { @@ -302,6 +326,17 @@ struct usb_diag_ch *usb_diag_open(const char *name, void *priv, unsigned long flags; int found = 0; +#ifdef CONFIG_DIAG_OVER_TTY + static bool init; + + if (!init) { + init = true; + tty_mode = factory_cable_present(); + } + + if (tty_mode) + return tty_diag_channel_open(name, priv, notify); +#endif spin_lock_irqsave(&ch_lock, flags); /* Check if we already have a channel with this name */ list_for_each_entry(ch, &usb_diag_ch_list, list) { @@ -342,6 +377,10 @@ void usb_diag_close(struct usb_diag_ch *ch) struct diag_context *dev = NULL; unsigned long flags; +#ifdef CONFIG_DIAG_OVER_TTY + if (tty_mode) + return tty_diag_channel_close(ch); +#endif spin_lock_irqsave(&ch_lock, flags); ch->priv = NULL; ch->notify = NULL; @@ -392,6 +431,10 @@ int usb_diag_alloc_req(struct usb_diag_ch *ch, int n_write, int n_read) int i; unsigned long flags; +#ifdef CONFIG_DIAG_OVER_TTY + if (tty_mode) + return 0; +#endif if (!ctxt) return -ENODEV; @@ -437,7 +480,15 @@ EXPORT_SYMBOL(usb_diag_alloc_req); int usb_diag_request_size(struct usb_diag_ch *ch) { struct diag_context *ctxt = ch->priv_usb; - struct usb_composite_dev *cdev = ctxt->cdev; + struct usb_composite_dev *cdev = NULL; + + /* MOT: qcom code need to check if the pointer is null + anyway, we use the default size for tty mode + */ + if (ctxt != NULL && ctxt->cdev != NULL) + cdev = ctxt->cdev; + else + return CI_MAX_REQUEST_SIZE; if (gadget_is_dwc3(cdev->gadget)) return DWC3_MAX_REQUEST_SIZE; @@ -467,6 +518,10 @@ int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req) struct usb_ep *out; static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1); +#ifdef CONFIG_DIAG_OVER_TTY + if (tty_mode) + return tty_diag_channel_read(ch, d_req); +#endif if (!ctxt) return -ENODEV; @@ -544,6 +599,11 @@ int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req) struct usb_ep *in; static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1); +#ifdef CONFIG_DIAG_OVER_TTY + if (tty_mode) + return tty_diag_channel_write(ch, d_req); +#endif + if (!ctxt) return -ENODEV; |
