diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/Kconfig | 2 | ||||
-rw-r--r-- | drivers/Makefile | 1 | ||||
-rw-r--r-- | drivers/cache/Kconfig | 25 | ||||
-rw-r--r-- | drivers/cache/Makefile | 4 | ||||
-rw-r--r-- | drivers/cache/cache-l2x0.c | 76 | ||||
-rw-r--r-- | drivers/cache/cache-uclass.c | 24 | ||||
-rw-r--r-- | drivers/cache/sandbox_cache.c | 34 | ||||
-rw-r--r-- | drivers/gpio/gpio-rcar.c | 15 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-core.c | 27 | ||||
-rw-r--r-- | drivers/net/ravb.c | 13 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-uclass.c | 96 | ||||
-rw-r--r-- | drivers/pinctrl/renesas/pfc.c | 45 | ||||
-rw-r--r-- | drivers/pinctrl/renesas/sh_pfc.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 5 | ||||
-rw-r--r-- | drivers/usb/host/ohci-da8xx.c | 138 |
15 files changed, 471 insertions, 35 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index e6702ec..96ff4f5 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -14,6 +14,8 @@ source "drivers/block/Kconfig" source "drivers/bootcount/Kconfig" +source "drivers/cache/Kconfig" + source "drivers/clk/Kconfig" source "drivers/cpu/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index e501ae8..6635dab 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_BIOSEMU) += bios_emulator/ obj-y += block/ obj-y += board/ obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/ +obj-y += cache/ obj-$(CONFIG_CPU) += cpu/ obj-y += crypto/ obj-$(CONFIG_FASTBOOT) += fastboot/ diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig new file mode 100644 index 0000000..24def7a --- /dev/null +++ b/drivers/cache/Kconfig @@ -0,0 +1,25 @@ +# +# Cache controllers +# + +menu "Cache Controller drivers" + +config CACHE + bool "Enable Driver Model for Cache controllers" + depends on DM + help + Enable driver model for cache controllers that are found on + most CPU's. Cache is memory that the CPU can access directly and + is usually located on the same chip. This uclass can be used for + configuring settings that be found from a device tree file. + +config L2X0_CACHE + tristate "PL310 cache driver" + select CACHE + depends on ARM + help + This driver is for the PL310 cache controller commonly found on + ARMv7(32-bit) devices. The driver configures the cache settings + found in the device tree. + +endmenu diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile new file mode 100644 index 0000000..9deb961 --- /dev/null +++ b/drivers/cache/Makefile @@ -0,0 +1,4 @@ + +obj-$(CONFIG_CACHE) += cache-uclass.o +obj-$(CONFIG_SANDBOX) += sandbox_cache.o +obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o diff --git a/drivers/cache/cache-l2x0.c b/drivers/cache/cache-l2x0.c new file mode 100644 index 0000000..67c752d --- /dev/null +++ b/drivers/cache/cache-l2x0.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ +#include <common.h> +#include <command.h> +#include <dm.h> + +#include <asm/io.h> +#include <asm/pl310.h> + +static void l2c310_of_parse_and_init(struct udevice *dev) +{ + u32 tag[3] = { 0, 0, 0 }; + u32 saved_reg, prefetch; + struct pl310_regs *regs = (struct pl310_regs *)dev_read_addr(dev); + + /* Disable the L2 Cache */ + clrbits_le32(®s->pl310_ctrl, L2X0_CTRL_EN); + + saved_reg = readl(®s->pl310_aux_ctrl); + if (!dev_read_u32(dev, "prefetch-data", &prefetch)) { + if (prefetch) + saved_reg |= L310_AUX_CTRL_DATA_PREFETCH_MASK; + else + saved_reg &= ~L310_AUX_CTRL_DATA_PREFETCH_MASK; + } + + if (!dev_read_u32(dev, "prefetch-instr", &prefetch)) { + if (prefetch) + saved_reg |= L310_AUX_CTRL_INST_PREFETCH_MASK; + else + saved_reg &= ~L310_AUX_CTRL_INST_PREFETCH_MASK; + } + + saved_reg |= dev_read_bool(dev, "arm,shared-override"); + writel(saved_reg, ®s->pl310_aux_ctrl); + + saved_reg = readl(®s->pl310_tag_latency_ctrl); + if (!dev_read_u32_array(dev, "arm,tag-latency", tag, 3)) + saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) | + L310_LATENCY_CTRL_WR(tag[1] - 1) | + L310_LATENCY_CTRL_SETUP(tag[2] - 1); + writel(saved_reg, ®s->pl310_tag_latency_ctrl); + + saved_reg = readl(®s->pl310_data_latency_ctrl); + if (!dev_read_u32_array(dev, "arm,data-latency", tag, 3)) + saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) | + L310_LATENCY_CTRL_WR(tag[1] - 1) | + L310_LATENCY_CTRL_SETUP(tag[2] - 1); + writel(saved_reg, ®s->pl310_data_latency_ctrl); + + /* Enable the L2 cache */ + setbits_le32(®s->pl310_ctrl, L2X0_CTRL_EN); +} + +static int l2x0_probe(struct udevice *dev) +{ + l2c310_of_parse_and_init(dev); + + return 0; +} + + +static const struct udevice_id l2x0_ids[] = { + { .compatible = "arm,pl310-cache" }, + {} +}; + +U_BOOT_DRIVER(pl310_cache) = { + .name = "pl310_cache", + .id = UCLASS_CACHE, + .of_match = l2x0_ids, + .probe = l2x0_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/cache/cache-uclass.c b/drivers/cache/cache-uclass.c new file mode 100644 index 0000000..97ce024 --- /dev/null +++ b/drivers/cache/cache-uclass.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <common.h> +#include <cache.h> +#include <dm.h> + +int cache_get_info(struct udevice *dev, struct cache_info *info) +{ + struct cache_ops *ops = cache_get_ops(dev); + + if (!ops->get_info) + return -ENOSYS; + + return ops->get_info(dev, info); +} + +UCLASS_DRIVER(cache) = { + .id = UCLASS_CACHE, + .name = "cache", + .post_bind = dm_scan_fdt_dev, +}; diff --git a/drivers/cache/sandbox_cache.c b/drivers/cache/sandbox_cache.c new file mode 100644 index 0000000..14cc6b0 --- /dev/null +++ b/drivers/cache/sandbox_cache.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <common.h> +#include <cache.h> +#include <dm.h> +#include <errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_get_info(struct udevice *dev, struct cache_info *info) +{ + info->base = 0x11223344; + + return 0; +} + +static const struct cache_ops sandbox_cache_ops = { + .get_info = sandbox_get_info, +}; + +static const struct udevice_id sandbox_cache_ids[] = { + { .compatible = "sandbox,cache" }, + { } +}; + +U_BOOT_DRIVER(cache_sandbox) = { + .name = "cache_sandbox", + .id = UCLASS_CACHE, + .of_match = sandbox_cache_ids, + .ops = &sandbox_cache_ops, +}; diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 6fd1270..594e0a4 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -6,6 +6,7 @@ #include <common.h> #include <clk.h> #include <dm.h> +#include <dm/pinctrl.h> #include <errno.h> #include <asm/gpio.h> #include <asm/io.h> @@ -117,19 +118,17 @@ static int rcar_gpio_get_function(struct udevice *dev, unsigned offset) static int rcar_gpio_request(struct udevice *dev, unsigned offset, const char *label) { - struct rcar_gpio_priv *priv = dev_get_priv(dev); - struct udevice *pctldev; - int ret; - - ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev); - if (ret) - return ret; + return pinctrl_gpio_request(dev, offset); +} - return sh_pfc_config_mux_for_gpio(pctldev, priv->pfc_offset + offset); +static int rcar_gpio_free(struct udevice *dev, unsigned offset) +{ + return pinctrl_gpio_free(dev, offset); } static const struct dm_gpio_ops rcar_gpio_ops = { .request = rcar_gpio_request, + .free = rcar_gpio_free, .direction_input = rcar_gpio_direction_input, .direction_output = rcar_gpio_direction_output, .get_value = rcar_gpio_get_value, diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index c4e2f6a..1acff74 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -116,7 +116,6 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, SPI_MEM_OP_ADDR(nor->addr_width, to, 1), SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(len, buf, 1)); - size_t remaining = len; int ret; /* get transfer protocols. */ @@ -127,22 +126,16 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) op.addr.nbytes = 0; - while (remaining) { - op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX; - ret = spi_mem_adjust_op_size(nor->spi, &op); - if (ret) - return ret; - - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; + ret = spi_mem_adjust_op_size(nor->spi, &op); + if (ret) + return ret; + op.data.nbytes = len < op.data.nbytes ? len : op.data.nbytes; - op.addr.val += op.data.nbytes; - remaining -= op.data.nbytes; - op.data.buf.out += op.data.nbytes; - } + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; - return len; + return op.data.nbytes; } /* @@ -1101,10 +1094,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, goto write_err; *retlen += written; i += written; - if (written != page_remain) { - ret = -EIO; - goto write_err; - } } write_err: diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c index 749562d..11abe5e 100644 --- a/drivers/net/ravb.c +++ b/drivers/net/ravb.c @@ -46,6 +46,8 @@ #define CSR_OPS 0x0000000F #define CSR_OPS_CONFIG BIT(1) +#define APSR_TDM BIT(14) + #define TCCR_TSRQ0 BIT(0) #define RFLR_RFL_MIN 0x05EE @@ -389,9 +391,14 @@ static int ravb_dmac_init(struct udevice *dev) /* FIFO size set */ writel(0x00222210, eth->iobase + RAVB_REG_TGC); - /* Delay CLK: 2ns */ - if (pdata->max_speed == 1000) - writel(BIT(14), eth->iobase + RAVB_REG_APSR); + /* Delay CLK: 2ns (not applicable on R-Car E3/D3) */ + if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77990) || + (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77995)) + return 0; + + if ((pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) || + (pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)) + writel(APSR_TDM, eth->iobase + RAVB_REG_APSR); return 0; } diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index f01bc77..5b1cd29 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -172,6 +172,102 @@ static int pinconfig_post_bind(struct udevice *dev) } #endif +static int +pinctrl_gpio_get_pinctrl_and_offset(struct udevice *dev, unsigned offset, + struct udevice **pctldev, + unsigned int *pin_selector) +{ + struct ofnode_phandle_args args; + unsigned gpio_offset, pfc_base, pfc_pins; + int ret; + + ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, + 0, &args); + if (ret) { + dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n", + __func__, ret); + return ret; + } + + ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL, + args.node, pctldev); + if (ret) { + dev_dbg(dev, + "%s: uclass_get_device_by_of_offset failed: err=%d\n", + __func__, ret); + return ret; + } + + gpio_offset = args.args[0]; + pfc_base = args.args[1]; + pfc_pins = args.args[2]; + + if (offset < gpio_offset || offset > gpio_offset + pfc_pins) { + dev_dbg(dev, + "%s: GPIO can not be mapped to pincontrol pin\n", + __func__); + return -EINVAL; + } + + offset -= gpio_offset; + offset += pfc_base; + *pin_selector = offset; + + return 0; +} + +/** + * pinctrl_gpio_request() - request a single pin to be used as GPIO + * + * @dev: GPIO peripheral device + * @offset: the GPIO pin offset from the GPIO controller + * @return: 0 on success, or negative error code on failure + */ +int pinctrl_gpio_request(struct udevice *dev, unsigned offset) +{ + const struct pinctrl_ops *ops; + struct udevice *pctldev; + unsigned int pin_selector; + int ret; + + ret = pinctrl_gpio_get_pinctrl_and_offset(dev, offset, + &pctldev, &pin_selector); + if (ret) + return ret; + + ops = pinctrl_get_ops(pctldev); + if (!ops || !ops->gpio_request_enable) + return -ENOTSUPP; + + return ops->gpio_request_enable(pctldev, pin_selector); +} + +/** + * pinctrl_gpio_free() - free a single pin used as GPIO + * + * @dev: GPIO peripheral device + * @offset: the GPIO pin offset from the GPIO controller + * @return: 0 on success, or negative error code on failure + */ +int pinctrl_gpio_free(struct udevice *dev, unsigned offset) +{ + const struct pinctrl_ops *ops; + struct udevice *pctldev; + unsigned int pin_selector; + int ret; + + ret = pinctrl_gpio_get_pinctrl_and_offset(dev, offset, + &pctldev, &pin_selector); + if (ret) + return ret; + + ops = pinctrl_get_ops(pctldev); + if (!ops || !ops->gpio_disable_free) + return -ENOTSUPP; + + return ops->gpio_disable_free(pctldev, pin_selector); +} + /** * pinctrl_select_state_simple() - simple implementation of pinctrl_select_state * diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c index 0635950..d1271da 100644 --- a/drivers/pinctrl/renesas/pfc.c +++ b/drivers/pinctrl/renesas/pfc.c @@ -459,14 +459,15 @@ static const char *sh_pfc_pinctrl_get_function_name(struct udevice *dev, return priv->pfc.info->functions[selector].name; } -int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector) +static int sh_pfc_gpio_request_enable(struct udevice *dev, + unsigned pin_selector) { struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); struct sh_pfc_pinctrl *pmx = &priv->pmx; struct sh_pfc *pfc = &priv->pfc; struct sh_pfc_pin_config *cfg; const struct sh_pfc_pin *pin = NULL; - int i, idx; + int i, ret, idx; for (i = 1; i < pfc->info->nr_pins; i++) { if (priv->pfc.info->pins[i].pin != pin_selector) @@ -485,7 +486,42 @@ int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector) if (cfg->type != PINMUX_TYPE_NONE) return -EBUSY; - return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO); + ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO); + if (ret) + return ret; + + cfg->type = PINMUX_TYPE_GPIO; + + return 0; +} + +static int sh_pfc_gpio_disable_free(struct udevice *dev, + unsigned pin_selector) +{ + struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); + struct sh_pfc_pinctrl *pmx = &priv->pmx; + struct sh_pfc *pfc = &priv->pfc; + struct sh_pfc_pin_config *cfg; + const struct sh_pfc_pin *pin = NULL; + int i, idx; + + for (i = 1; i < pfc->info->nr_pins; i++) { + if (priv->pfc.info->pins[i].pin != pin_selector) + continue; + + pin = &priv->pfc.info->pins[i]; + break; + } + + if (!pin) + return -EINVAL; + + idx = sh_pfc_get_pin_index(pfc, pin->pin); + cfg = &pmx->configs[idx]; + + cfg->type = PINMUX_TYPE_NONE; + + return 0; } static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector, @@ -746,6 +782,9 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = { .pinmux_set = sh_pfc_pinctrl_pin_set, .pinmux_group_set = sh_pfc_pinctrl_group_set, .set_state = pinctrl_generic_set_state, + + .gpio_request_enable = sh_pfc_gpio_request_enable, + .gpio_disable_free = sh_pfc_gpio_disable_free, }; static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 09e11d3..6629e1f 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -275,7 +275,6 @@ void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data); const struct pinmux_bias_reg * sh_pfc_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, unsigned int *bit); -int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector); extern const struct sh_pfc_soc_info r8a7790_pinmux_info; extern const struct sh_pfc_soc_info r8a7791_pinmux_info; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1c2212f..b1188bc 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -246,6 +246,11 @@ config USB_OHCI_GENERIC ---help--- Enables support for generic OHCI controller. +config USB_OHCI_DA8XX + bool "Support for da850 OHCI USB controller" + help + Enable support for the da850 USB controller. + endif # USB_OHCI_HCD config USB_UHCI_HCD diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 47ad3f3..e8a495f 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -4,9 +4,54 @@ */ #include <common.h> - +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/ofnode.h> +#include <generic-phy.h> +#include <reset.h> +#include "ohci.h" #include <asm/arch/da8xx-usb.h> +struct da8xx_ohci { + ohci_t ohci; + struct clk *clocks; /* clock list */ + struct phy phy; + int clock_count; /* number of clock in clock list */ +}; + +static int usb_phy_on(void) +{ + unsigned long timeout; + + clrsetbits_le32(&davinci_syscfg_regs->cfgchip2, + (CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | + CFGCHIP2_OTGPWRDN | CFGCHIP2_OTGMODE | + CFGCHIP2_REFFREQ | CFGCHIP2_USB1PHYCLKMUX), + (CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN | + CFGCHIP2_PHY_PLLON | CFGCHIP2_REFFREQ_24MHZ | + CFGCHIP2_USB2PHYCLKMUX | CFGCHIP2_USB1SUSPENDM)); + + /* wait until the usb phy pll locks */ + timeout = get_timer(0); + while (get_timer(timeout) < 10) { + if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD) + return 1; + } + + /* USB phy was not turned on */ + return 0; +} + +static void usb_phy_off(void) +{ + /* Power down the on-chip PHY. */ + clrsetbits_le32(&davinci_syscfg_regs->cfgchip2, + CFGCHIP2_PHY_PLLON | CFGCHIP2_USB1SUSPENDM, + CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN | + CFGCHIP2_RESET); +} + int usb_cpu_init(void) { /* enable psc for usb2.0 */ @@ -37,3 +82,94 @@ int usb_cpu_init_fail(void) { return usb_cpu_stop(); } + +#if CONFIG_IS_ENABLED(DM_USB) +static int ohci_da8xx_probe(struct udevice *dev) +{ + struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev); + struct da8xx_ohci *priv = dev_get_priv(dev); + int i, err, ret, clock_nb; + + err = 0; + priv->clock_count = 0; + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + if (clock_nb > 0) { + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), + GFP_KERNEL); + if (!priv->clocks) + return -ENOMEM; + + for (i = 0; i < clock_nb; i++) { + err = clk_get_by_index(dev, i, &priv->clocks[i]); + if (err < 0) + break; + + err = clk_enable(&priv->clocks[i]); + if (err) { + dev_err(dev, "failed to enable clock %d\n", i); + clk_free(&priv->clocks[i]); + goto clk_err; + } + priv->clock_count++; + } + } else if (clock_nb != -ENOENT) { + dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb); + return clock_nb; + } + + err = usb_cpu_init(); + + if (err) + goto clk_err; + + err = ohci_register(dev, regs); + if (err) + goto phy_err; + + return 0; + +phy_err: + ret = usb_cpu_stop(); + if (ret) + dev_err(dev, "failed to shutdown usb phy\n"); + +clk_err: + ret = clk_release_all(priv->clocks, priv->clock_count); + if (ret) + dev_err(dev, "failed to disable all clocks\n"); + + return err; +} + +static int ohci_da8xx_remove(struct udevice *dev) +{ + struct da8xx_ohci *priv = dev_get_priv(dev); + int ret; + + ret = ohci_deregister(dev); + if (ret) + return ret; + + ret = usb_cpu_stop(); + if (ret) + return ret; + + return clk_release_all(priv->clocks, priv->clock_count); +} + +static const struct udevice_id da8xx_ohci_ids[] = { + { .compatible = "ti,da830-ohci" }, + { } +}; + +U_BOOT_DRIVER(ohci_generic) = { + .name = "ohci-da8xx", + .id = UCLASS_USB, + .of_match = da8xx_ohci_ids, + .probe = ohci_da8xx_probe, + .remove = ohci_da8xx_remove, + .ops = &ohci_usb_ops, + .priv_auto_alloc_size = sizeof(struct da8xx_ohci), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif |