Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Linus Walleij and committed by
Greg Kroah-Hartman
1ea1859f 0990366b

+45 -24
+12
arch/arm/mach-davinci/board-dm644x-evm.c
··· 823 823 824 824 #define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI) 825 825 826 + #define GPIO_nVBUS_DRV 160 827 + 828 + static struct gpiod_lookup_table dm644evm_usb_gpio_table = { 829 + .dev_id = "musb-davinci", 830 + .table = { 831 + GPIO_LOOKUP("davinci_gpio", GPIO_nVBUS_DRV, NULL, 832 + GPIO_ACTIVE_HIGH), 833 + { } 834 + }, 835 + }; 836 + 826 837 static __init void davinci_evm_init(void) 827 838 { 828 839 int ret; ··· 886 875 dm644x_init_asp(); 887 876 888 877 /* irlml6401 switches over 1A, in under 8 msec */ 878 + gpiod_add_lookup_table(&dm644evm_usb_gpio_table); 889 879 davinci_setup_usb(1000, 8); 890 880 891 881 if (IS_BUILTIN(CONFIG_PHYLIB)) {
+33 -24
drivers/usb/musb/davinci.c
··· 13 13 #include <linux/clk.h> 14 14 #include <linux/err.h> 15 15 #include <linux/io.h> 16 - #include <linux/gpio.h> 16 + #include <linux/gpio/consumer.h> 17 17 #include <linux/platform_device.h> 18 18 #include <linux/dma-mapping.h> 19 19 #include <linux/usb/usb_phy_generic.h> ··· 24 24 #include <asm/mach-types.h> 25 25 26 26 #include "musb_core.h" 27 - 28 - #ifdef CONFIG_MACH_DAVINCI_EVM 29 - #define GPIO_nVBUS_DRV 160 30 - #endif 31 27 32 28 #include "davinci.h" 33 29 #include "cppi_dma.h" ··· 36 40 struct device *dev; 37 41 struct platform_device *musb; 38 42 struct clk *clk; 43 + bool vbus_state; 44 + struct gpio_desc *vbus; 45 + struct work_struct vbus_work; 39 46 }; 40 47 41 48 /* REVISIT (PM) we should be able to keep the PHY in low power mode most ··· 134 135 * when J10 is out, and TI documents it as handling OTG. 135 136 */ 136 137 137 - #ifdef CONFIG_MACH_DAVINCI_EVM 138 - 139 - static int vbus_state = -1; 140 - 141 138 /* I2C operations are always synchronous, and require a task context. 142 139 * With unloaded systems, using the shared workqueue seems to suffice 143 140 * to satisfy the 100msec A_WAIT_VRISE timeout... 144 141 */ 145 - static void evm_deferred_drvvbus(struct work_struct *ignored) 142 + static void evm_deferred_drvvbus(struct work_struct *work) 146 143 { 147 - gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); 148 - vbus_state = !vbus_state; 144 + struct davinci_glue *glue = container_of(work, struct davinci_glue, 145 + vbus_work); 146 + 147 + gpiod_set_value_cansleep(glue->vbus, glue->vbus_state); 148 + glue->vbus_state = !glue->vbus_state; 149 149 } 150 150 151 - #endif /* EVM */ 152 - 153 - static void davinci_musb_source_power(struct musb *musb, int is_on, int immediate) 151 + static void davinci_musb_source_power(struct musb *musb, int is_on, 152 + int immediate) 154 153 { 155 - #ifdef CONFIG_MACH_DAVINCI_EVM 154 + struct davinci_glue *glue = dev_get_drvdata(musb->controller->parent); 155 + 156 + /* This GPIO handling is entirely optional */ 157 + if (!glue->vbus) 158 + return; 159 + 156 160 if (is_on) 157 161 is_on = 1; 158 162 159 - if (vbus_state == is_on) 163 + if (glue->vbus_state == is_on) 160 164 return; 161 - vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ 165 + /* 0/1 vs "-1 == unknown/init" */ 166 + glue->vbus_state = !is_on; 162 167 163 168 if (machine_is_davinci_evm()) { 164 - static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); 165 - 166 169 if (immediate) 167 - gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); 170 + gpiod_set_value_cansleep(glue->vbus, glue->vbus_state); 168 171 else 169 - schedule_work(&evm_vbus_work); 172 + schedule_work(&glue->vbus_work); 170 173 } 171 174 if (immediate) 172 - vbus_state = is_on; 173 - #endif 175 + glue->vbus_state = is_on; 174 176 } 175 177 176 178 static void davinci_musb_set_vbus(struct musb *musb, int is_on) ··· 523 523 glue->clk = clk; 524 524 525 525 pdata->platform_ops = &davinci_ops; 526 + 527 + glue->vbus = devm_gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW); 528 + if (IS_ERR(glue->vbus)) { 529 + ret = PTR_ERR(glue->vbus); 530 + goto err0; 531 + } else { 532 + glue->vbus_state = -1; 533 + INIT_WORK(&glue->vbus_work, evm_deferred_drvvbus); 534 + } 526 535 527 536 usb_phy_generic_register(); 528 537 platform_set_drvdata(pdev, glue);