diff options
author | Olof Johansson <olof@lixom.net> | 2019-04-29 08:07:37 +0200 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2019-04-29 08:07:37 +0200 |
commit | 56e49cd668b76d6b8568083c2127464cdb3c1584 (patch) | |
tree | 4dc904eb1765293b91eee9acba771f6f51294cbb | |
parent | Merge tag 'pxa-for-5.2' of https://github.com/rjarzmik/linux into arm/soc (diff) | |
parent | usb: ohci-da8xx: drop the vbus GPIO (diff) | |
download | linux-56e49cd668b76d6b8568083c2127464cdb3c1584.tar.xz linux-56e49cd668b76d6b8568083c2127464cdb3c1584.zip |
Merge tag 'davinci-for-v5.2/soc' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into arm/soc
This update for DaVinci SoC support simplifies the VBUS enable
and overcurrent handling code in DA8XX OHCI driver by modeling
vbus GPIO as a regulator. This unifies code for all users, device
tree and non-device-tree.
The OHCI driver patches have been acked by its maintainer.
* tag 'davinci-for-v5.2/soc' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci:
usb: ohci-da8xx: drop the vbus GPIO
ARM: davinci: da830-evm: add a fixed regulator for ohci-da8xx
ARM: davinci: omapl138-hawk: add a fixed regulator for ohci-da8xx
usb: ohci-da8xx: disable the regulator if the overcurrent irq fired
usb: ohci-da8xx: let the regulator framework keep track of use count
ARM: davinci: add missing sentinels to GPIO lookup tables
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/mach-davinci/board-da830-evm.c | 51 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-da850-evm.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-dm355-evm.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-dm644x-evm.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-omapl138-hawk.c | 50 | ||||
-rw-r--r-- | drivers/usb/host/ohci-da8xx.c | 42 |
6 files changed, 112 insertions, 34 deletions
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index ff097ecfa451..51a892702e27 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -29,6 +29,7 @@ #include <linux/platform_data/spi-davinci.h> #include <linux/platform_data/usb-davinci.h> #include <linux/platform_data/ti-aemif.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/nvmem-provider.h> @@ -53,14 +54,50 @@ static const short da830_evm_usb11_pins[] = { -1 }; -static struct gpiod_lookup_table da830_evm_usb_gpio_lookup = { +static struct regulator_consumer_supply da830_evm_usb_supplies[] = { + REGULATOR_SUPPLY("vbus", NULL), +}; + +static struct regulator_init_data da830_evm_usb_vbus_data = { + .consumer_supplies = da830_evm_usb_supplies, + .num_consumer_supplies = ARRAY_SIZE(da830_evm_usb_supplies), +}; + +static struct fixed_voltage_config da830_evm_usb_vbus = { + .supply_name = "vbus", + .microvolts = 33000000, + .init_data = &da830_evm_usb_vbus_data, +}; + +static struct platform_device da830_evm_usb_vbus_device = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &da830_evm_usb_vbus, + }, +}; + +static struct gpiod_lookup_table da830_evm_usb_oc_gpio_lookup = { .dev_id = "ohci-da8xx", .table = { - GPIO_LOOKUP("davinci_gpio", ON_BD_USB_DRV, "vbus", 0), GPIO_LOOKUP("davinci_gpio", ON_BD_USB_OVC, "oc", 0), + { } }, }; +static struct gpiod_lookup_table da830_evm_usb_vbus_gpio_lookup = { + .dev_id = "reg-fixed-voltage.0", + .table = { + GPIO_LOOKUP("davinci_gpio", ON_BD_USB_DRV, "vbus", 0), + { } + }, +}; + +static struct gpiod_lookup_table *da830_evm_usb_gpio_lookups[] = { + &da830_evm_usb_oc_gpio_lookup, + &da830_evm_usb_vbus_gpio_lookup, +}; + static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = { /* TPS2065 switch @ 5V */ .potpgt = (3 + 1) / 2, /* 3 ms max */ @@ -75,6 +112,9 @@ static __init void da830_evm_usb_init(void) pr_warn("%s: USB PHY CLK registration failed: %d\n", __func__, ret); + gpiod_add_lookup_tables(da830_evm_usb_gpio_lookups, + ARRAY_SIZE(da830_evm_usb_gpio_lookups)); + ret = da8xx_register_usb_phy(); if (ret) pr_warn("%s: USB PHY registration failed: %d\n", @@ -100,7 +140,11 @@ static __init void da830_evm_usb_init(void) return; } - gpiod_add_lookup_table(&da830_evm_usb_gpio_lookup); + ret = platform_device_register(&da830_evm_usb_vbus_device); + if (ret) { + pr_warn("%s: Unable to register the vbus supply\n", __func__); + return; + } ret = da8xx_register_usb11(&da830_evm_usb11_pdata); if (ret) @@ -156,6 +200,7 @@ static struct gpiod_lookup_table mmc_gpios_table = { GPIO_ACTIVE_LOW), GPIO_LOOKUP("davinci_gpio", DA830_MMCSD_WP_PIN, "wp", GPIO_ACTIVE_LOW), + { } }, }; diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 1fdc9283a8c5..4ee65a8a3b80 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -784,6 +784,7 @@ static struct gpiod_lookup_table mmc_gpios_table = { GPIO_ACTIVE_LOW), GPIO_LOOKUP("davinci_gpio", DA850_MMCSD_WP_PIN, "wp", GPIO_ACTIVE_HIGH), + { } }, }; diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 64d81fc86f14..5113273fda69 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -121,6 +121,7 @@ static struct gpiod_lookup_table i2c_recovery_gpiod_table = { GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), GPIO_LOOKUP("davinci_gpio", DM355_I2C_SCL_PIN, "scl", GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + { } }, }; diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index de15f782816e..9d87d4e440ea 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -663,6 +663,7 @@ static struct gpiod_lookup_table i2c_recovery_gpiod_table = { GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), GPIO_LOOKUP("davinci_gpio", DM644X_I2C_SCL_PIN, "scl", GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + { } }, }; diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 0896af2bed24..db177a6a7e48 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -21,6 +21,7 @@ #include <linux/platform_data/mtd-davinci.h> #include <linux/platform_data/mtd-davinci-aemif.h> #include <linux/platform_data/ti-aemif.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <asm/mach-types.h> @@ -298,14 +299,50 @@ static const short da850_hawk_usb11_pins[] = { -1 }; -static struct gpiod_lookup_table hawk_usb_gpio_lookup = { +static struct regulator_consumer_supply hawk_usb_supplies[] = { + REGULATOR_SUPPLY("vbus", NULL), +}; + +static struct regulator_init_data hawk_usb_vbus_data = { + .consumer_supplies = hawk_usb_supplies, + .num_consumer_supplies = ARRAY_SIZE(hawk_usb_supplies), +}; + +static struct fixed_voltage_config hawk_usb_vbus = { + .supply_name = "vbus", + .microvolts = 3300000, + .init_data = &hawk_usb_vbus_data, +}; + +static struct platform_device hawk_usb_vbus_device = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &hawk_usb_vbus, + }, +}; + +static struct gpiod_lookup_table hawk_usb_oc_gpio_lookup = { .dev_id = "ohci-da8xx", .table = { - GPIO_LOOKUP("davinci_gpio", DA850_USB1_VBUS_PIN, "vbus", 0), GPIO_LOOKUP("davinci_gpio", DA850_USB1_OC_PIN, "oc", 0), + { } }, }; +static struct gpiod_lookup_table hawk_usb_vbus_gpio_lookup = { + .dev_id = "reg-fixed-voltage.0", + .table = { + GPIO_LOOKUP("davinci_gpio", DA850_USB1_VBUS_PIN, NULL, 0), + { } + }, +}; + +static struct gpiod_lookup_table *hawk_usb_gpio_lookups[] = { + &hawk_usb_oc_gpio_lookup, + &hawk_usb_vbus_gpio_lookup, +}; + static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { /* TPS2087 switch @ 5V */ .potpgt = (3 + 1) / 2, /* 3 ms max */ @@ -326,12 +363,19 @@ static __init void omapl138_hawk_usb_init(void) pr_warn("%s: USB PHY CLK registration failed: %d\n", __func__, ret); + gpiod_add_lookup_tables(hawk_usb_gpio_lookups, + ARRAY_SIZE(hawk_usb_gpio_lookups)); + ret = da8xx_register_usb_phy(); if (ret) pr_warn("%s: USB PHY registration failed: %d\n", __func__, ret); - gpiod_add_lookup_table(&hawk_usb_gpio_lookup); + ret = platform_device_register(&hawk_usb_vbus_device); + if (ret) { + pr_warn("%s: Unable to register the vbus supply\n", __func__); + return; + } ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); if (ret) diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index ca8a94f15ac0..38183ac438c6 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -40,8 +40,6 @@ struct da8xx_ohci_hcd { struct phy *usb11_phy; struct regulator *vbus_reg; struct notifier_block nb; - unsigned int reg_enabled; - struct gpio_desc *vbus_gpio; struct gpio_desc *oc_gpio; }; @@ -92,29 +90,21 @@ static int ohci_da8xx_set_power(struct usb_hcd *hcd, int on) struct device *dev = hcd->self.controller; int ret; - if (da8xx_ohci->vbus_gpio) { - gpiod_set_value_cansleep(da8xx_ohci->vbus_gpio, on); - return 0; - } - if (!da8xx_ohci->vbus_reg) return 0; - if (on && !da8xx_ohci->reg_enabled) { + if (on) { ret = regulator_enable(da8xx_ohci->vbus_reg); if (ret) { dev_err(dev, "Failed to enable regulator: %d\n", ret); return ret; } - da8xx_ohci->reg_enabled = 1; - - } else if (!on && da8xx_ohci->reg_enabled) { + } else { ret = regulator_disable(da8xx_ohci->vbus_reg); if (ret) { dev_err(dev, "Failed to disable regulator: %d\n", ret); return ret; } - da8xx_ohci->reg_enabled = 0; } return 0; @@ -124,9 +114,6 @@ static int ohci_da8xx_get_power(struct usb_hcd *hcd) { struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd); - if (da8xx_ohci->vbus_gpio) - return gpiod_get_value_cansleep(da8xx_ohci->vbus_gpio); - if (da8xx_ohci->vbus_reg) return regulator_is_enabled(da8xx_ohci->vbus_reg); @@ -159,9 +146,6 @@ static int ohci_da8xx_has_set_power(struct usb_hcd *hcd) { struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd); - if (da8xx_ohci->vbus_gpio) - return 1; - if (da8xx_ohci->vbus_reg) return 1; @@ -206,12 +190,18 @@ static int ohci_da8xx_regulator_event(struct notifier_block *nb, return 0; } -static irqreturn_t ohci_da8xx_oc_handler(int irq, void *data) +static irqreturn_t ohci_da8xx_oc_thread(int irq, void *data) { struct da8xx_ohci_hcd *da8xx_ohci = data; + struct device *dev = da8xx_ohci->hcd->self.controller; + int ret; - if (gpiod_get_value(da8xx_ohci->oc_gpio)) - gpiod_set_value(da8xx_ohci->vbus_gpio, 0); + if (gpiod_get_value_cansleep(da8xx_ohci->oc_gpio) && + da8xx_ohci->vbus_reg) { + ret = regulator_disable(da8xx_ohci->vbus_reg); + if (ret) + dev_err(dev, "Failed to disable regulator: %d\n", ret); + } return IRQ_HANDLED; } @@ -424,11 +414,6 @@ static int ohci_da8xx_probe(struct platform_device *pdev) } } - da8xx_ohci->vbus_gpio = devm_gpiod_get_optional(dev, "vbus", - GPIOD_OUT_HIGH); - if (IS_ERR(da8xx_ohci->vbus_gpio)) - goto err; - da8xx_ohci->oc_gpio = devm_gpiod_get_optional(dev, "oc", GPIOD_IN); if (IS_ERR(da8xx_ohci->oc_gpio)) goto err; @@ -438,8 +423,9 @@ static int ohci_da8xx_probe(struct platform_device *pdev) if (oc_irq < 0) goto err; - error = devm_request_irq(dev, oc_irq, ohci_da8xx_oc_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + error = devm_request_threaded_irq(dev, oc_irq, NULL, + ohci_da8xx_oc_thread, IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "OHCI over-current indicator", da8xx_ohci); if (error) goto err; |