usb: musb: davinci: Convert to use GPIO descriptor

The DaVinci MUSB glue contains an optional GPIO line to
control VBUS power, convert this to use a GPIO descriptor
and augment the EVM board file to provide this descriptor.

I can't get this driver to compile properly and it depends
on broken but when I didn get it to compile brokenly, it
did at least not complain about THIS code being broken so
I don't think I broke the driver any more than what it
already is.

I did away with the ifdefs that do not work with
multiplatform anyway so the day someone decides to
resurrect the code, the path to get it working should be
easier as well since DaVinci is now multiplatform.

Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[b-liu@ti.com: fixed one instance still ref to global variable vbus_state]
Signed-off-by: Bin Liu <b-liu@ti.com>
Link: https://lore.kernel.org/r/20200115132547.364-25-b-liu@ti.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Linus Walleij 2020-01-15 07:25:46 -06:00 committed by Greg Kroah-Hartman
parent 0990366bab
commit 1ea1859f84
2 changed files with 45 additions and 24 deletions

View File

@ -823,6 +823,17 @@ static int davinci_phy_fixup(struct phy_device *phydev)
#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI) #define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
#define GPIO_nVBUS_DRV 160
static struct gpiod_lookup_table dm644evm_usb_gpio_table = {
.dev_id = "musb-davinci",
.table = {
GPIO_LOOKUP("davinci_gpio", GPIO_nVBUS_DRV, NULL,
GPIO_ACTIVE_HIGH),
{ }
},
};
static __init void davinci_evm_init(void) static __init void davinci_evm_init(void)
{ {
int ret; int ret;
@ -875,6 +886,7 @@ static __init void davinci_evm_init(void)
dm644x_init_asp(); dm644x_init_asp();
/* irlml6401 switches over 1A, in under 8 msec */ /* irlml6401 switches over 1A, in under 8 msec */
gpiod_add_lookup_table(&dm644evm_usb_gpio_table);
davinci_setup_usb(1000, 8); davinci_setup_usb(1000, 8);
if (IS_BUILTIN(CONFIG_PHYLIB)) { if (IS_BUILTIN(CONFIG_PHYLIB)) {

View File

@ -13,7 +13,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/usb/usb_phy_generic.h> #include <linux/usb/usb_phy_generic.h>
@ -25,10 +25,6 @@
#include "musb_core.h" #include "musb_core.h"
#ifdef CONFIG_MACH_DAVINCI_EVM
#define GPIO_nVBUS_DRV 160
#endif
#include "davinci.h" #include "davinci.h"
#include "cppi_dma.h" #include "cppi_dma.h"
@ -40,6 +36,9 @@ struct davinci_glue {
struct device *dev; struct device *dev;
struct platform_device *musb; struct platform_device *musb;
struct clk *clk; struct clk *clk;
bool vbus_state;
struct gpio_desc *vbus;
struct work_struct vbus_work;
}; };
/* REVISIT (PM) we should be able to keep the PHY in low power mode most /* REVISIT (PM) we should be able to keep the PHY in low power mode most
@ -135,43 +134,44 @@ static void davinci_musb_disable(struct musb *musb)
* when J10 is out, and TI documents it as handling OTG. * when J10 is out, and TI documents it as handling OTG.
*/ */
#ifdef CONFIG_MACH_DAVINCI_EVM
static int vbus_state = -1;
/* I2C operations are always synchronous, and require a task context. /* I2C operations are always synchronous, and require a task context.
* With unloaded systems, using the shared workqueue seems to suffice * With unloaded systems, using the shared workqueue seems to suffice
* to satisfy the 100msec A_WAIT_VRISE timeout... * to satisfy the 100msec A_WAIT_VRISE timeout...
*/ */
static void evm_deferred_drvvbus(struct work_struct *ignored) static void evm_deferred_drvvbus(struct work_struct *work)
{ {
gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); struct davinci_glue *glue = container_of(work, struct davinci_glue,
vbus_state = !vbus_state; vbus_work);
gpiod_set_value_cansleep(glue->vbus, glue->vbus_state);
glue->vbus_state = !glue->vbus_state;
} }
#endif /* EVM */ static void davinci_musb_source_power(struct musb *musb, int is_on,
int immediate)
static void davinci_musb_source_power(struct musb *musb, int is_on, int immediate)
{ {
#ifdef CONFIG_MACH_DAVINCI_EVM struct davinci_glue *glue = dev_get_drvdata(musb->controller->parent);
/* This GPIO handling is entirely optional */
if (!glue->vbus)
return;
if (is_on) if (is_on)
is_on = 1; is_on = 1;
if (vbus_state == is_on) if (glue->vbus_state == is_on)
return; return;
vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ /* 0/1 vs "-1 == unknown/init" */
glue->vbus_state = !is_on;
if (machine_is_davinci_evm()) { if (machine_is_davinci_evm()) {
static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
if (immediate) if (immediate)
gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); gpiod_set_value_cansleep(glue->vbus, glue->vbus_state);
else else
schedule_work(&evm_vbus_work); schedule_work(&glue->vbus_work);
} }
if (immediate) if (immediate)
vbus_state = is_on; glue->vbus_state = is_on;
#endif
} }
static void davinci_musb_set_vbus(struct musb *musb, int is_on) static void davinci_musb_set_vbus(struct musb *musb, int is_on)
@ -524,6 +524,15 @@ static int davinci_probe(struct platform_device *pdev)
pdata->platform_ops = &davinci_ops; pdata->platform_ops = &davinci_ops;
glue->vbus = devm_gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW);
if (IS_ERR(glue->vbus)) {
ret = PTR_ERR(glue->vbus);
goto err0;
} else {
glue->vbus_state = -1;
INIT_WORK(&glue->vbus_work, evm_deferred_drvvbus);
}
usb_phy_generic_register(); usb_phy_generic_register();
platform_set_drvdata(pdev, glue); platform_set_drvdata(pdev, glue);