From: peter.chen@freescale.com (Peter Chen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 14/14] usb: udc-core: add judgement logic for usb_gadget_connect
Date: Fri, 15 Mar 2013 18:04:08 +0800 [thread overview]
Message-ID: <20130315100408.GG28361@nchen-desktop> (raw)
In-Reply-To: <20130315075128.GF5074@arwen.pp.htv.fi>
On Fri, Mar 15, 2013 at 09:51:29AM +0200, Felipe Balbi wrote:
>
> that's all wrong and needs to be fixed. UDC-core has to be the central
> point for all these details. We start with the easiest way (call connect
> unconditionally after gadget driver is loaded) and optimize it as we go
> (making sure that there is VBUS before connecting pullups); but we can't
> bypass UDC-core and call usb_gadget_connect() directly from UDC driver.
I have an idea that let the gadget driver call usb_gadget_connect/disconnect,
and make a refcount for calling .pullup at usb_gadget_connect/disconnect.
Below is an initial idea for it, I think it can also cover both udc
and uvc case.
drivers/usb/chipidea/udc.c | 6 ++----
drivers/usb/gadget/composite.c | 6 ++++++
include/linux/usb/gadget.h | 21 +++++++++++++++++++--
3 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 81184b9..4b6b2d8 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1386,17 +1386,15 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
pm_runtime_get_sync(&_gadget->dev);
hw_device_reset(ci, USBMODE_CM_DC);
hw_device_state(ci, ci->ep0out->qh.dma);
- ci13xxx_pullup(_gadget, true);
+ ci->driver->connect(&ci->gadget);
dev_dbg(ci->dev, "Connected to host\n");
} else {
- if (ci->driver)
- ci->driver->disconnect(&ci->gadget);
+ ci->driver->disconnect(&ci->gadget);
hw_device_state(ci, 0);
if (ci->platdata->notify_event)
ci->platdata->notify_event(ci,
CI13XXX_CONTROLLER_STOPPED_EVENT);
_gadget_stop_activity(&ci->gadget);
- ci13xxx_pullup(_gadget, false);
pm_runtime_put_sync(&_gadget->dev);
dev_dbg(ci->dev, "Disconnected from host\n");
}
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 7c821de..b7bf5ae 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1479,6 +1479,11 @@ done:
return value;
}
+void composite_connect(struct usb_gadget *gadget)
+{
+ usb_gadget_connect(gadget);
+}
+
void composite_disconnect(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
@@ -1492,6 +1497,7 @@ void composite_disconnect(struct usb_gadget *gadget)
reset_config(cdev);
if (cdev->driver->disconnect)
cdev->driver->disconnect(cdev);
+ usb_gadget_disconnect(gadget);
spin_unlock_irqrestore(&cdev->lock, flags);
}
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 7e373a2..7f7e6bf 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -536,6 +536,7 @@ struct usb_gadget {
struct device dev;
unsigned out_epnum;
unsigned in_epnum;
+ int connection;
};
static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
@@ -722,9 +723,16 @@ static inline int usb_gadget_vbus_disconnect(struct usb_gadget *gadget)
*/
static inline int usb_gadget_connect(struct usb_gadget *gadget)
{
+ int ret = 0;
if (!gadget->ops->pullup)
return -EOPNOTSUPP;
- return gadget->ops->pullup(gadget, 1);
+
+ if (gadget->connection == 0)
+ ret = gadget->ops->pullup(gadget, 1);
+ if (!ret)
+ gadget->connection ++;
+
+ return ret;
}
/**
@@ -744,9 +752,18 @@ static inline int usb_gadget_connect(struct usb_gadget *gadget)
*/
static inline int usb_gadget_disconnect(struct usb_gadget *gadget)
{
+ int ret = 0;
+
if (!gadget->ops->pullup)
return -EOPNOTSUPP;
- return gadget->ops->pullup(gadget, 0);
+
+ if (gadget->connection == 1)
+ ret = gadget->ops->pullup(gadget, 0);
+
+ if (!ret)
+ gadget->connection --;
+
+ return ret;
}
> >
> > In that case, the pullup will not be called, it will check if gadget
> > module is loaded.
>
> I don't see that in your patch.
At each udc driver, it makes sure it, maybe we can move it to usb_gaget_connect
/usb_gadget_disconnect or its abstract layer.
> >
> > I am not familiar with SRP, but I think vbus is pre-condition.
>
> hehe, google SRP.
>
> Nah, I'll save you the trouble. SRP is a mechanism for the USB
> peripheral to ask the host to enable VBUS. This means that we can keep
> the VBUS charge pump disabled, and thus save power, until peripheral
> requests for a session.
Thanks.
>
> --
> balbi
--
Best Regards,
Peter Chen
next prev parent reply other threads:[~2013-03-15 10:04 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-14 5:50 [PATCH 00/14] Add vbus status to udc-core Peter Chen
2013-03-14 5:50 ` [PATCH 01/14] usb: udc-core: introduce vbus_active for struct usb_gadget Peter Chen
2013-03-14 5:50 ` [PATCH 02/14] usb: chipidea: using common vbus_active Peter Chen
2013-03-14 5:50 ` [PATCH 03/14] usb: at91_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 04/14] usb: fsl_udc_core: " Peter Chen
2013-03-14 5:50 ` [PATCH 05/14] usb: lpc32xx_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 06/14] usb: mv_u3d_core: " Peter Chen
2013-03-14 5:50 ` [PATCH 07/14] usb: mv_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 08/14] usb: omap_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 09/14] usb: pch_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 10/14] usb: pxa25x_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 11/14] usb: pxa27x_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 12/14] usb: s3c2410_udc: " Peter Chen
2013-03-14 5:50 ` [PATCH 13/14] usb: udc-core: small cleanup for udc->gadget Peter Chen
2013-03-14 5:50 ` [PATCH 14/14] usb: udc-core: add judgement logic for usb_gadget_connect Peter Chen
2013-03-14 9:00 ` Felipe Balbi
2013-03-14 9:24 ` Peter Chen
2013-03-14 10:19 ` Felipe Balbi
2013-03-15 6:06 ` Peter Chen
2013-03-15 7:51 ` Felipe Balbi
2013-03-15 10:04 ` Peter Chen [this message]
2013-03-15 10:37 ` Felipe Balbi
2013-03-15 12:26 ` Peter Chen
2013-03-18 6:52 ` Peter Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130315100408.GG28361@nchen-desktop \
--to=peter.chen@freescale.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.