[PATCH 4/4] USB: gpio_vbus: avoid consecutive vbus_session calls with the same "is_active"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Basically, ->vbus_session() calls should be served when VBUS session
starts and ends (it's not whenever transciever drivers detect VBUS
_changes_).  Otherwise, if UDC gadget drivers don't want for some
reason ->vbus_session() calls with the same "is_active" value, either
OTG or UDC drivers need to have some protection handlings.

Also, on platforms using this 'gpio_vbus' driver, the driver is only
allowed to check whether VBUS is applied.  There is no kernel-standard
way prepared for UDC gadget drivers to do that.

With this in mind, gpio_vbus should try to prevent unnecessary
consecutive vbus_session calls being served with the same "in_active"
value.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@xxxxxxxxxxx>
---
 drivers/usb/otg/gpio_vbus.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index ac962ac..a190ead 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -38,6 +38,7 @@ struct gpio_vbus_data {
 	int			vbus_draw_enabled;
 	unsigned		mA;
 	struct delayed_work	work;
+	unsigned int		vbus;
 };
 
 
@@ -96,18 +97,24 @@ static void gpio_vbus_work(struct work_struct *work)
 	struct gpio_vbus_data *gpio_vbus =
 		container_of(work, struct gpio_vbus_data, work.work);
 	struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
-	int gpio, status;
+	int gpio, status, vbus;
 
 	if (!gpio_vbus->phy.otg->gadget)
 		return;
 
+	vbus = is_vbus_powered(pdata);
+	if ((vbus ^ gpio_vbus->vbus) == 0)
+		return;
+	gpio_vbus->vbus = vbus;
+
 	/* Peripheral controllers which manage the pullup themselves won't have
 	 * gpio_pullup configured here.  If it's configured here, we'll do what
 	 * isp1301_omap::b_peripheral() does and enable the pullup here... although
 	 * that may complicate usb_gadget_{,dis}connect() support.
 	 */
 	gpio = pdata->gpio_pullup;
-	if (is_vbus_powered(pdata)) {
+
+	if (vbus) {
 		status = USB_EVENT_VBUS;
 		gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL;
 		gpio_vbus->phy.last_event = status;
@@ -195,6 +202,7 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg,
 	dev_dbg(&pdev->dev, "registered gadget '%s'\n", gadget->name);
 
 	/* initialize connection state */
+	gpio_vbus->vbus = 0; /* start with disconnected */
 	gpio_vbus_irq(irq, pdev);
 	return 0;
 }
-- 
1.7.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux