greybus: arche-platform: Control usb3613 from arche-platform
authorVaibhav Hiremath <vaibhav.hiremath@linaro.org>
Fri, 12 Feb 2016 20:34:20 +0000 (02:04 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Mon, 15 Feb 2016 21:18:40 +0000 (13:18 -0800)
USB3613 hub driver exports control function, which allows caller
to switch the mode of operation of hub device.
As we know that, we have dependency between HUB3613 and APB's where,
HUB supposed to enter into HUB only after APB's brought out of reset.

Until now, we had all userspace driver sequences to control this,
but now since we are moving all resource management strictly to the
driver, it makes sense (even though it looks hacky) to enable control
of hub3613 from arche-platform driver.

Note that, there is another discussion where, the hub.connect IO pin may
get interfaced with MSM gpio, at that time, we can get rid of this hack
and replace it with gpio control.

Testing Done: Tested on EVT1.2 and DB3.5 platform.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/arche-platform.c

index 1fd806f..591cf9d 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/pm.h>
 #include "arche_platform.h"
 
+#include <linux/usb/usb3613.h>
+
 struct arche_platform_drvdata {
        /* Control GPIO signals to and from AP <=> SVC */
        int svc_reset_gpio;
@@ -121,6 +123,10 @@ static void svc_delayed_work(struct work_struct *work)
 
        /* re-assert wake_detect to confirm SVC WAKE_OUT */
        gpio_direction_output(arche_pdata->wake_detect_gpio, 1);
+
+       /* Enable HUB3613 into HUB mode. */
+       if (usb3613_hub_mode_ctrl(true))
+               dev_warn(arche_pdata->dev, "failed to control hub device\n");
 }
 
 static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata)
@@ -197,6 +203,11 @@ static ssize_t state_store(struct device *dev,
                device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
 
                arche_platform_poweroff_seq(arche_pdata);
+
+               ret = usb3613_hub_mode_ctrl(false);
+               if (ret)
+                       dev_warn(arche_pdata->dev, "failed to control hub device\n");
+                       /* TODO: Should we do anything more here ?? */
        } else if (sysfs_streq(buf, "active")) {
                if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
                        return count;
@@ -219,6 +230,11 @@ static ssize_t state_store(struct device *dev,
 
                arche_platform_poweroff_seq(arche_pdata);
 
+               ret = usb3613_hub_mode_ctrl(false);
+               if (ret)
+                       dev_warn(arche_pdata->dev, "failed to control hub device\n");
+                       /* TODO: Should we do anything more here ?? */
+
                arche_platform_fw_flashing_seq(arche_pdata);
 
                device_for_each_child(arche_pdata->dev, NULL, apb_fw_flashing_state);
@@ -393,6 +409,9 @@ static int arche_platform_remove(struct platform_device *pdev)
        arche_platform_poweroff_seq(arche_pdata);
        platform_set_drvdata(pdev, NULL);
 
+       if (usb3613_hub_mode_ctrl(false))
+               dev_warn(arche_pdata->dev, "failed to control hub device\n");
+               /* TODO: Should we do anything more here ?? */
        return 0;
 }