diff options
author | Tom Rini <trini@konsulko.com> | 2016-07-27 22:30:20 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-07-27 22:30:20 -0400 |
commit | fe34b6a4845476208ca7d19a35179e56bebf3877 (patch) | |
tree | 05643ac1448012bbb7514dd04526168737c86b58 /drivers | |
parent | c6f086ddcbfb47918b82f6a135c61f432540da42 (diff) | |
parent | 02ebd42cf19e523593d8e4e8f3d02083299fcdbb (diff) |
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'drivers')
28 files changed, 451 insertions, 199 deletions
diff --git a/drivers/core/root.c b/drivers/core/root.c index 158702406ed..33dc9c0b2db 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -218,6 +218,15 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, return ret; } +int dm_scan_fdt_dev(struct udevice *dev) +{ + if (dev->of_offset == -1) + return 0; + + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, + gd->flags & GD_FLG_RELOC ? false : true); +} + int dm_scan_fdt(const void *blob, bool pre_reloc_only) { return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c index 1a9c864ef37..5c955da3346 100644 --- a/drivers/core/simple-bus.c +++ b/drivers/core/simple-bus.c @@ -6,7 +6,6 @@ #include <common.h> #include <dm.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -41,7 +40,7 @@ static int simple_bus_post_bind(struct udevice *dev) plat->size = cell[2]; } - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); + return dm_scan_fdt_dev(dev); } UCLASS_DRIVER(simple_bus) = { diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 20b30ffbeb5..dbd3789747d 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -12,7 +12,6 @@ #include <malloc.h> #include <dm/device-internal.h> #include <dm/lists.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -499,16 +498,6 @@ static int i2c_post_probe(struct udevice *dev) #endif } -static int i2c_post_bind(struct udevice *dev) -{ -#if CONFIG_IS_ENABLED(OF_CONTROL) - /* Scan the bus for devices */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -#else - return 0; -#endif -} - static int i2c_child_post_bind(struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_CONTROL) @@ -527,7 +516,9 @@ UCLASS_DRIVER(i2c) = { .id = UCLASS_I2C, .name = "i2c", .flags = DM_UC_FLAG_SEQ_ALIAS, - .post_bind = i2c_post_bind, +#if CONFIG_IS_ENABLED(OF_CONTROL) + .post_bind = dm_scan_fdt_dev, +#endif .post_probe = i2c_post_probe, .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus), .per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip), diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index 2c84c41643c..4696a1ae62a 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -14,7 +14,6 @@ #include <asm/test.h> #include <dm/lists.h> #include <dm/device-internal.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -33,8 +32,7 @@ static int get_emul(struct udevice *dev, struct udevice **devp, *opsp = NULL; plat = dev_get_parent_platdata(dev); if (!plat->emul) { - ret = dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, - false); + ret = dm_scan_fdt_dev(dev); if (ret) return ret; diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index e3229efed0b..aea8d61f347 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -26,7 +26,6 @@ #include <asm/io.h> #include <asm-generic/gpio.h> #include <dm/device-internal.h> -#include <dm/root.h> #include <dm/uclass-internal.h> #ifdef DEBUG_TRACE @@ -1450,12 +1449,6 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return ret; } -int cros_ec_post_bind(struct udevice *dev) -{ - /* Scan for available EC devices (e.g. I2C tunnel) */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - U_BOOT_CMD( crosec, 6, 1, do_cros_ec, "CROS-EC utility command", @@ -1482,5 +1475,5 @@ UCLASS_DRIVER(cros_ec) = { .id = UCLASS_CROS_EC, .name = "cros_ec", .per_device_auto_alloc_size = sizeof(struct cros_ec_dev), - .post_bind = cros_ec_post_bind, + .post_bind = dm_scan_fdt_dev, }; diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 2cf7bae7923..b58c2824167 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -182,7 +182,7 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host, } #ifdef CONFIG_DM_MMC_OPS -int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, +static int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -195,7 +195,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); int ret = 0, flags = 0, i; - unsigned int timeout = 100000; + unsigned int timeout = 500; u32 retry = 100000; u32 mask, ctrl; ulong start = get_timer(0); @@ -381,7 +381,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) } #ifdef CONFIG_DM_MMC_OPS -int dwmci_set_ios(struct udevice *dev) +static int dwmci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); #else diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 6a0e9719b8a..8a9630208c5 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -22,6 +22,11 @@ static const struct socfpga_clock_manager *clock_manager_base = static const struct socfpga_system_manager *system_manager_base = (void *)SOCFPGA_SYSMGR_ADDRESS; +struct socfpga_dwmci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + /* socfpga implmentation specific driver private data */ struct dwmci_socfpga_priv_data { struct dwmci_host host; @@ -98,21 +103,45 @@ static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev) static int socfpga_dwmmc_probe(struct udevice *dev) { +#ifdef CONFIG_BLK + struct socfpga_dwmci_plat *plat = dev_get_platdata(dev); +#endif struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; + +#ifdef CONFIG_BLK + dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps, + host->bus_hz, 400000); + host->mmc = &plat->mmc; +#else int ret; ret = add_dwmci(host, host->bus_hz, 400000); if (ret) return ret; - +#endif + host->mmc->priv = &priv->host; upriv->mmc = host->mmc; host->mmc->dev = dev; return 0; } +static int socfpga_dwmmc_bind(struct udevice *dev) +{ +#ifdef CONFIG_BLK + struct socfpga_dwmci_plat *plat = dev_get_platdata(dev); + int ret; + + ret = dwmci_bind(dev, &plat->mmc, &plat->cfg); + if (ret) + return ret; +#endif + + return 0; +} + static const struct udevice_id socfpga_dwmmc_ids[] = { { .compatible = "altr,socfpga-dw-mshc" }, { } @@ -123,6 +152,7 @@ U_BOOT_DRIVER(socfpga_dwmmc_drv) = { .id = UCLASS_MMC, .of_match = socfpga_dwmmc_ids, .ofdata_to_platdata = socfpga_dwmmc_ofdata_to_platdata, + .bind = socfpga_dwmmc_bind, .probe = socfpga_dwmmc_probe, .priv_auto_alloc_size = sizeof(struct dwmci_socfpga_priv_data), }; diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index d405929b641..bcd154a7074 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -17,10 +17,18 @@ # define CONFIG_ZYNQ_SDHCI_MIN_FREQ 0 #endif +struct arasan_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + static int arasan_sdhci_probe(struct udevice *dev) { + struct arasan_sdhci_plat *plat = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sdhci_host *host = dev_get_priv(dev); + u32 caps; + int ret; host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; @@ -31,13 +39,19 @@ static int arasan_sdhci_probe(struct udevice *dev) host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - add_sdhci(host, CONFIG_ZYNQ_SDHCI_MAX_FREQ, - CONFIG_ZYNQ_SDHCI_MIN_FREQ); - - upriv->mmc = host->mmc; + caps = sdhci_readl(host, SDHCI_CAPABILITIES); + ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, + caps, CONFIG_ZYNQ_SDHCI_MAX_FREQ, + CONFIG_ZYNQ_SDHCI_MIN_FREQ, host->version, + host->quirks, 0); + host->mmc = &plat->mmc; + if (ret) + return ret; + host->mmc->priv = host; host->mmc->dev = dev; + upriv->mmc = host->mmc; - return 0; + return sdhci_probe(dev); } static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) @@ -50,6 +64,18 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) return 0; } +static int arasan_sdhci_bind(struct udevice *dev) +{ + struct arasan_sdhci_plat *plat = dev_get_platdata(dev); + int ret; + + ret = sdhci_bind(dev, &plat->mmc, &plat->cfg); + if (ret) + return ret; + + return 0; +} + static const struct udevice_id arasan_sdhci_ids[] = { { .compatible = "arasan,sdhci-8.9a" }, { } @@ -60,6 +86,9 @@ U_BOOT_DRIVER(arasan_sdhci_drv) = { .id = UCLASS_MMC, .of_match = arasan_sdhci_ids, .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata, + .ops = &sdhci_ops, + .bind = arasan_sdhci_bind, .probe = arasan_sdhci_probe, .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat), }; diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 58d287bb071..4eeb0f6ede8 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -8,6 +8,7 @@ */ #include <config.h> #include <common.h> +#include <errno.h> #include <phy.h> #define PHY_AUTONEGOTIATE_TIMEOUT 5000 diff --git a/drivers/pch/pch-uclass.c b/drivers/pch/pch-uclass.c index 7216660a24c..af794eb5a12 100644 --- a/drivers/pch/pch-uclass.c +++ b/drivers/pch/pch-uclass.c @@ -8,7 +8,6 @@ #include <common.h> #include <dm.h> #include <pch.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -55,20 +54,8 @@ int pch_get_io_base(struct udevice *dev, u32 *iobasep) return ops->get_io_base(dev, iobasep); } -static int pch_uclass_post_bind(struct udevice *bus) -{ - /* - * Scan the device tree for devices - * - * Before relocation, only bind devices marked for pre-relocation - * use. - */ - return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, - gd->flags & GD_FLG_RELOC ? false : true); -} - UCLASS_DRIVER(pch) = { .id = UCLASS_PCH, .name = "pch", - .post_bind = pch_uclass_post_bind, + .post_bind = dm_scan_fdt_dev, }; diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 32590ce498a..342b78c0c4b 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -13,7 +13,6 @@ #include <pci.h> #include <asm/io.h> #include <dm/lists.h> -#include <dm/root.h> #include <dm/device-internal.h> #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) #include <asm/fsp/fsp_support.h> @@ -753,27 +752,6 @@ error: return ret; } -static int pci_uclass_post_bind(struct udevice *bus) -{ - /* - * If there is no pci device listed in the device tree, - * don't bother scanning the device tree. - */ - if (bus->of_offset == -1) - return 0; - - /* - * Scan the device tree for devices. This does not probe the PCI bus, - * as this is not permitted while binding. It just finds devices - * mentioned in the device tree. - * - * Before relocation, only bind devices marked for pre-relocation - * use. - */ - return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, - gd->flags & GD_FLG_RELOC ? false : true); -} - static int decode_regions(struct pci_controller *hose, const void *blob, int parent_node, int node) { @@ -1254,7 +1232,7 @@ UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", .flags = DM_UC_FLAG_SEQ_ALIAS, - .post_bind = pci_uclass_post_bind, + .post_bind = dm_scan_fdt_dev, .pre_probe = pci_uclass_pre_probe, .post_probe = pci_uclass_post_probe, .child_post_bind = pci_uclass_child_post_bind, diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c index 6de5130c2a8..6a84ee386d7 100644 --- a/drivers/pci/pci_sandbox.c +++ b/drivers/pci/pci_sandbox.c @@ -10,7 +10,6 @@ #include <fdtdec.h> #include <inttypes.h> #include <pci.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -52,12 +51,6 @@ static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn, return ops->read_config(emul, offset, valuep, size); } -static int sandbox_pci_child_post_bind(struct udevice *dev) -{ - /* Attach an emulator if we can */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - static const struct dm_pci_ops sandbox_pci_ops = { .read_config = sandbox_pci_read_config, .write_config = sandbox_pci_write_config, @@ -73,7 +66,9 @@ U_BOOT_DRIVER(pci_sandbox) = { .id = UCLASS_PCI, .of_match = sandbox_pci_ids, .ops = &sandbox_pci_ops, - .child_post_bind = sandbox_pci_child_post_bind, + + /* Attach an emulator if we can */ + .child_post_bind = dm_scan_fdt_dev, .per_child_platdata_auto_alloc_size = sizeof(struct pci_child_platdata), }; diff --git a/drivers/pinctrl/pinctrl_pic32.c b/drivers/pinctrl/pinctrl_pic32.c index 5cf97ecec86..9acac29133c 100644 --- a/drivers/pinctrl/pinctrl_pic32.c +++ b/drivers/pinctrl/pinctrl_pic32.c @@ -10,7 +10,6 @@ #include <errno.h> #include <asm/io.h> #include <dm/pinctrl.h> -#include <dm/root.h> #include <mach/pic32.h> DECLARE_GLOBAL_DATA_PTR; @@ -341,12 +340,6 @@ static int pic32_pinctrl_probe(struct udevice *dev) return 0; } -static int pic32_pinctrl_bind(struct udevice *dev) -{ - /* scan child GPIO banks */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - static const struct udevice_id pic32_pinctrl_ids[] = { { .compatible = "microchip,pic32mzda-pinctrl" }, { } @@ -358,6 +351,6 @@ U_BOOT_DRIVER(pinctrl_pic32) = { .of_match = pic32_pinctrl_ids, .ops = &pic32_pinctrl_ops, .probe = pic32_pinctrl_probe, - .bind = pic32_pinctrl_bind, + .bind = dm_scan_fdt_dev, .priv_auto_alloc_size = sizeof(struct pic32_pinctrl_priv), }; diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3036.c b/drivers/pinctrl/rockchip/pinctrl_rk3036.c index 1f78bf862db..6aea856aa63 100644 --- a/drivers/pinctrl/rockchip/pinctrl_rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl_rk3036.c @@ -15,7 +15,6 @@ #include <asm/arch/hardware.h> #include <asm/arch/periph.h> #include <dm/pinctrl.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -253,12 +252,6 @@ static struct pinctrl_ops rk3036_pinctrl_ops = { .get_periph_id = rk3036_pinctrl_get_periph_id, }; -static int rk3036_pinctrl_bind(struct udevice *dev) -{ - /* scan child GPIO banks */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - static int rk3036_pinctrl_probe(struct udevice *dev) { struct rk3036_pinctrl_priv *priv = dev_get_priv(dev); @@ -279,6 +272,6 @@ U_BOOT_DRIVER(pinctrl_rk3036) = { .of_match = rk3036_pinctrl_ids, .priv_auto_alloc_size = sizeof(struct rk3036_pinctrl_priv), .ops = &rk3036_pinctrl_ops, - .bind = rk3036_pinctrl_bind, + .bind = dm_scan_fdt_dev, .probe = rk3036_pinctrl_probe, }; diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c index 8cb3b8228ed..ae8a4f1fde6 100644 --- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c @@ -17,7 +17,6 @@ #include <asm/arch/periph.h> #include <asm/arch/pmu_rk3288.h> #include <dm/pinctrl.h> -#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -664,16 +663,6 @@ static struct pinctrl_ops rk3288_pinctrl_ops = { .get_periph_id = rk3288_pinctrl_get_periph_id, }; -static int rk3288_pinctrl_bind(struct udevice *dev) -{ -#if CONFIG_IS_ENABLED(OF_PLATDATA) - return 0; -#else - /* scan child GPIO banks */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -#endif -} - #ifndef CONFIG_SPL_BUILD static int rk3288_pinctrl_parse_tables(struct rk3288_pinctrl_priv *priv, struct rockchip_pin_bank *banks, @@ -730,6 +719,8 @@ U_BOOT_DRIVER(pinctrl_rk3288) = { .of_match = rk3288_pinctrl_ids, .priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv), .ops = &rk3288_pinctrl_ops, - .bind = rk3288_pinctrl_bind, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif .probe = rk3288_pinctrl_probe, }; diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 3c441678059..b4227031265 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -1,5 +1,7 @@ menu "Power" +source "drivers/power/domain/Kconfig" + source "drivers/power/pmic/Kconfig" source "drivers/power/regulator/Kconfig" diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig new file mode 100644 index 00000000000..b9040974339 --- /dev/null +++ b/drivers/power/domain/Kconfig @@ -0,0 +1,20 @@ +menu "Power Domain Support" + +config POWER_DOMAIN + bool "Enable power domain support using Driver Model" + depends on DM && OF_CONTROL + help + Enable support for the power domain driver class. Many SoCs allow + power to be applied to or removed from portions of the SoC (power + domains). This may be used to save power. This API provides the + means to control such power management hardware. + +config SANDBOX_POWER_DOMAIN + bool "Enable the sandbox power domain test driver" + depends on POWER_DOMAIN && SANDBOX + help + Enable support for a test power domain driver implementation, which + simply accepts requests to power on/off various HW modules without + actually doing anything beyond a little error checking. + +endmenu diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile new file mode 100644 index 00000000000..c18292f0ec8 --- /dev/null +++ b/drivers/power/domain/Makefile @@ -0,0 +1,7 @@ +# Copyright (c) 2016, NVIDIA CORPORATION. +# +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_POWER_DOMAIN) += power-domain-uclass.o +obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o +obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c new file mode 100644 index 00000000000..1bb6262fa1b --- /dev/null +++ b/drivers/power/domain/power-domain-uclass.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <power-domain.h> +#include <power-domain-uclass.h> + +DECLARE_GLOBAL_DATA_PTR; + +static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev) +{ + return (struct power_domain_ops *)dev->driver->ops; +} + +static int power_domain_of_xlate_default(struct power_domain *power_domain, + struct fdtdec_phandle_args *args) +{ + debug("%s(power_domain=%p)\n", __func__, power_domain); + + if (args->args_count != 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + power_domain->id = args->args[0]; + + return 0; +} + +int power_domain_get(struct udevice *dev, struct power_domain *power_domain) +{ + struct fdtdec_phandle_args args; + int ret; + struct udevice *dev_power_domain; + struct power_domain_ops *ops; + + debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain); + + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, + "power-domains", + "#power-domain-cells", 0, 0, + &args); + if (ret) { + debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", + __func__, ret); + return ret; + } + + ret = uclass_get_device_by_of_offset(UCLASS_POWER_DOMAIN, args.node, + &dev_power_domain); + if (ret) { + debug("%s: uclass_get_device_by_of_offset failed: %d\n", + __func__, ret); + return ret; + } + ops = power_domain_dev_ops(dev_power_domain); + + power_domain->dev = dev_power_domain; + if (ops->of_xlate) + ret = ops->of_xlate(power_domain, &args); + else + ret = power_domain_of_xlate_default(power_domain, &args); + if (ret) { + debug("of_xlate() failed: %d\n", ret); + return ret; + } + + ret = ops->request(power_domain); + if (ret) { + debug("ops->request() failed: %d\n", ret); + return ret; + } + + return 0; +} + +int power_domain_free(struct power_domain *power_domain) +{ + struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); + + debug("%s(power_domain=%p)\n", __func__, power_domain); + + return ops->free(power_domain); +} + +int power_domain_on(struct power_domain *power_domain) +{ + struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); + + debug("%s(power_domain=%p)\n", __func__, power_domain); + + return ops->on(power_domain); +} + +int power_domain_off(struct power_domain *power_domain) +{ + struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); + + debug("%s(power_domain=%p)\n", __func__, power_domain); + + return ops->off(power_domain); +} + +UCLASS_DRIVER(power_domain) = { + .id = UCLASS_POWER_DOMAIN, + .name = "power_domain", +}; diff --git a/drivers/power/domain/sandbox-power-domain-test.c b/drivers/power/domain/sandbox-power-domain-test.c new file mode 100644 index 00000000000..92a3a2a5273 --- /dev/null +++ b/drivers/power/domain/sandbox-power-domain-test.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <power-domain.h> +#include <asm/io.h> +#include <asm/power-domain.h> + +struct sandbox_power_domain_test { + struct power_domain pd; +}; + +int sandbox_power_domain_test_get(struct udevice *dev) +{ + struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); + + return power_domain_get(dev, &sbrt->pd); +} + +int sandbox_power_domain_test_on(struct udevice *dev) +{ + struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); + + return power_domain_on(&sbrt->pd); +} + +int sandbox_power_domain_test_off(struct udevice *dev) +{ + struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); + + return power_domain_off(&sbrt->pd); +} + +int sandbox_power_domain_test_free(struct udevice *dev) +{ + struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); + + return power_domain_free(&sbrt->pd); +} + +static const struct udevice_id sandbox_power_domain_test_ids[] = { + { .compatible = "sandbox,power-domain-test" }, + { } +}; + +U_BOOT_DRIVER(sandbox_power_domain_test) = { + .name = "sandbox_power_domain_test", + .id = UCLASS_MISC, + .of_match = sandbox_power_domain_test_ids, + .priv_auto_alloc_size = sizeof(struct sandbox_power_domain_test), +}; diff --git a/drivers/power/domain/sandbox-power-domain.c b/drivers/power/domain/sandbox-power-domain.c new file mode 100644 index 00000000000..9071346f984 --- /dev/null +++ b/drivers/power/domain/sandbox-power-domain.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <power-domain-uclass.h> +#include <asm/io.h> +#include <asm/power-domain.h> + +#define SANDBOX_POWER_DOMAINS 3 + +struct sandbox_power_domain { + bool on[SANDBOX_POWER_DOMAINS]; +}; + +static int sandbox_power_domain_request(struct power_domain *power_domain) +{ + debug("%s(power_domain=%p)\n", __func__, power_domain); + + if (power_domain->id >= SANDBOX_POWER_DOMAINS) + return -EINVAL; + + return 0; +} + +static int sandbox_power_domain_free(struct power_domain *power_domain) +{ + debug("%s(power_domain=%p)\n", __func__, power_domain); + + return 0; +} + +static int sandbox_power_domain_on(struct power_domain *power_domain) +{ + struct sandbox_power_domain *sbr = dev_get_priv(power_domain->dev); + + debug("%s(power_domain=%p)\n", __func__, power_domain); + + sbr->on[power_domain->id] = true; + + return 0; +} + +static int sandbox_power_domain_off(struct power_domain *power_domain) +{ + struct sandbox_power_domain *sbr = dev_get_priv(power_domain->dev); + + debug("%s(power_domain=%p)\n", __func__, power_domain); + + sbr->on[power_domain->id] = false; + + return 0; +} + +static int sandbox_power_domain_bind(struct udevice *dev) +{ + debug("%s(dev=%p)\n", __func__, dev); + + return 0; +} + +static int sandbox_power_domain_probe(struct udevice *dev) +{ + debug("%s(dev=%p)\n", __func__, dev); + + return 0; +} + +static const struct udevice_id sandbox_power_domain_ids[] = { + { .compatible = "sandbox,power-domain" }, + { } +}; + +struct power_domain_ops sandbox_power_domain_ops = { + .request = sandbox_power_domain_request, + .free = sandbox_power_domain_free, + .on = sandbox_power_domain_on, + .off = sandbox_power_domain_off, +}; + +U_BOOT_DRIVER(sandbox_power_domain) = { + .name = "sandbox_power_domain", + .id = UCLASS_POWER_DOMAIN, + .of_match = sandbox_power_domain_ids, + .bind = sandbox_power_domain_bind, + .probe = sandbox_power_domain_probe, + .priv_auto_alloc_size = sizeof(struct sandbox_power_domain), + .ops = &sandbox_power_domain_ops, +}; + +int sandbox_power_domain_query(struct udevice *dev, unsigned long id) +{ + struct sandbox_power_domain *sbr = dev_get_priv(dev); + + debug("%s(dev=%p, id=%ld)\n", __func__, dev, id); + + if (id >= SANDBOX_POWER_DOMAINS) + return -EINVAL; + + return sbr->on[id]; +} diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pm8916.c index d4c7d4adff1..2b65c697ec9 100644 --- a/drivers/power/pmic/pm8916.c +++ b/drivers/power/pmic/pm8916.c @@ -7,7 +7,6 @@ */ #include <common.h> #include <dm.h> -#include <dm/root.h> #include <power/pmic.h> #include <spmi/spmi.h> @@ -79,17 +78,11 @@ static int pm8916_probe(struct udevice *dev) return 0; } - -static int pm8916_bind(struct udevice *dev) -{ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - U_BOOT_DRIVER(pmic_pm8916) = { .name = "pmic_pm8916", .id = UCLASS_PMIC, .of_match = pm8916_ids, - .bind = pm8916_bind, + .bind = dm_scan_fdt_dev, .probe = pm8916_probe, .ops = &pm8916_ops, .priv_auto_alloc_size = sizeof(struct pm8916_priv), diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 465ff3fda61..17f22dda2bd 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -13,7 +13,7 @@ config DM_REGULATOR - 'drivers/power/pmic/regulator-uclass.c' It's important to call the device_bind() with the proper node offset, when binding the regulator devices. The pmic_bind_childs() can be used - for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node() + for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_dev() otherwise. Detailed information can be found in the header file. config SPL_DM_REGULATOR diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 8003f9bfc86..247abfa72ba 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -12,7 +12,6 @@ #include <spi.h> #include <dm/device-internal.h> #include <dm/uclass-internal.h> -#include <dm/root.h> #include <dm/lists.h> #include <dm/util.h> @@ -109,12 +108,6 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, return dm_spi_xfer(slave->dev, bitlen, dout, din, flags); } -static int spi_post_bind(struct udevice *dev) -{ - /* Scan the bus for devices */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - static int spi_child_post_bind(struct udevice *dev) { struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); @@ -446,7 +439,7 @@ UCLASS_DRIVER(spi) = { .id = UCLASS_SPI, .name = "spi", .flags = DM_UC_FLAG_SEQ_ALIAS, - .post_bind = spi_post_bind, + .post_bind = dm_scan_fdt_dev, .post_probe = spi_post_probe, .child_pre_probe = spi_child_pre_probe, .per_device_auto_alloc_size = sizeof(struct dm_spi_bus), diff --git a/drivers/spmi/spmi-uclass.c b/drivers/spmi/spmi-uclass.c index 4ddd51b556e..6edece23d82 100644 --- a/drivers/spmi/spmi-uclass.c +++ b/drivers/spmi/spmi-uclass.c @@ -9,7 +9,6 @@ #include <common.h> #include <dm.h> #include <errno.h> -#include <dm/root.h> #include <spmi/spmi.h> #include <linux/ctype.h> @@ -36,13 +35,8 @@ int spmi_reg_write(struct udevice *dev, int usid, int pid, int reg, return ops->write(dev, usid, pid, reg, value); } -static int spmi_post_bind(struct udevice *dev) -{ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - UCLASS_DRIVER(spmi) = { .id = UCLASS_SPMI, .name = "spmi", - .post_bind = spmi_post_bind, + .post_bind = dm_scan_fdt_dev, }; diff --git a/drivers/usb/emul/usb-emul-uclass.c b/drivers/usb/emul/usb-emul-uclass.c index ee7ea5ad91c..6e03c1e0d9e 100644 --- a/drivers/usb/emul/usb-emul-uclass.c +++ b/drivers/usb/emul/usb-emul-uclass.c @@ -8,7 +8,6 @@ #include <common.h> #include <dm.h> #include <usb.h> -#include <dm/root.h> #include <dm/device-internal.h> DECLARE_GLOBAL_DATA_PTR; @@ -265,12 +264,6 @@ int usb_emul_setup_device(struct udevice *dev, int maxpacketsize, return 0; } -int usb_emul_post_bind(struct udevice *dev) -{ - /* Scan the bus for devices */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - void usb_emul_reset(struct udevice *dev) { struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); @@ -282,7 +275,7 @@ void usb_emul_reset(struct udevice *dev) UCLASS_DRIVER(usb_emul) = { .id = UCLASS_USB_EMUL, .name = "usb_emul", - .post_bind = usb_emul_post_bind, + .post_bind = dm_scan_fdt_dev, .per_child_auto_alloc_size = sizeof(struct usb_device), .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata), }; diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c index 37a7935b436..76642cdad7d 100644 --- a/drivers/usb/host/ehci-zynq.c +++ b/drivers/usb/host/ehci-zynq.c @@ -7,55 +7,48 @@ */ #include <common.h> +#include <dm.h> +#include <usb.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <usb.h> #include <usb/ehci-ci.h> #include <usb/ulpi.h> #include "ehci.h" -#define ZYNQ_USB_USBCMD_RST 0x0000002 -#define ZYNQ_USB_USBCMD_STOP 0x0000000 -#define ZYNQ_USB_NUM_MIO 12 +struct zynq_ehci_priv { + struct ehci_ctrl ehcictrl; + struct usb_ehci *ehci; +}; -/* - * Create the appropriate control structures to manage - * a new EHCI host controller. - */ -int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, - struct ehci_hcor **hcor) +static int ehci_zynq_ofdata_to_platdata(struct udevice *dev) { - struct usb_ehci *ehci; + struct zynq_ehci_priv *priv = dev_get_priv(dev); + + priv->ehci = (struct usb_ehci *)dev_get_addr_ptr(dev); + if (!priv->ehci) + return -EINVAL; + + return 0; +} + +static int ehci_zynq_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct zynq_ehci_priv *priv = dev_get_priv(dev); + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; struct ulpi_viewport ulpi_vp; - int ret, mio_usb; /* Used for writing the ULPI data address */ struct ulpi_regs *ulpi = (struct ulpi_regs *)0; + int ret; - if (!index) { - mio_usb = zynq_slcr_get_mio_pin_status("usb0"); - if (mio_usb != ZYNQ_USB_NUM_MIO) { - printf("usb0 wrong num MIO: %d, Index %d\n", mio_usb, - index); - return -1; - } - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0; - } else { - mio_usb = zynq_slcr_get_mio_pin_status("usb1"); - if (mio_usb != ZYNQ_USB_NUM_MIO) { - printf("usb1 wrong num MIO: %d, Index %d\n", mio_usb, - index); - return -1; - } - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1; - } - - *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); - *hcor = (struct ehci_hcor *)((uint32_t) *hccr + - HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + hccr = (struct ehci_hccr *)((uint32_t)&priv->ehci->caplength); + hcor = (struct ehci_hcor *)((uint32_t) hccr + + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); - ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint; + ulpi_vp.viewport_addr = (u32)&priv->ehci->ulpi_viewpoint; ulpi_vp.port_num = 0; ret = ulpi_init(&ulpi_vp); @@ -77,28 +70,34 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); - return 0; + return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type); } -/* - * Destroy the appropriate control structures corresponding - * the the EHCI host controller. - */ -int ehci_hcd_stop(int index) +static int ehci_zynq_remove(struct udevice *dev) { - struct usb_ehci *ehci; - - if (!index) - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0; - else - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1; + int ret; - /* Stop controller */ - writel(ZYNQ_USB_USBCMD_STOP, &ehci->usbcmd); - udelay(1000); - - /* Initiate controller reset */ - writel(ZYNQ_USB_USBCMD_RST, &ehci->usbcmd); + ret = ehci_deregister(dev); + if (ret) + return ret; return 0; } + +static const struct udevice_id ehci_zynq_ids[] = { + { .compatible = "xlnx,zynq-usb-2.20a" }, + { } +}; + +U_BOOT_DRIVER(ehci_zynq) = { + .name = "ehci_zynq", + .id = UCLASS_USB, + .of_match = ehci_zynq_ids, + .ofdata_to_platdata = ehci_zynq_ofdata_to_platdata, + .probe = ehci_zynq_probe, + .remove = ehci_zynq_remove, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct zynq_ehci_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 69c9a504ebb..be114fc0771 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -14,7 +14,6 @@ #include <usb.h> #include <dm/device-internal.h> #include <dm/lists.h> -#include <dm/root.h> #include <dm/uclass-internal.h> DECLARE_GLOBAL_DATA_PTR; @@ -349,12 +348,6 @@ struct usb_device *usb_get_dev_index(struct udevice *bus, int index) } #endif -int usb_post_bind(struct udevice *dev) -{ - /* Scan the bus for devices */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp) { struct usb_platdata *plat; @@ -768,7 +761,7 @@ UCLASS_DRIVER(usb) = { .id = UCLASS_USB, .name = "usb", .flags = DM_UC_FLAG_SEQ_ALIAS, - .post_bind = usb_post_bind, + .post_bind = dm_scan_fdt_dev, .priv_auto_alloc_size = sizeof(struct usb_uclass_priv), .per_child_auto_alloc_size = sizeof(struct usb_device), .per_device_auto_alloc_size = sizeof(struct usb_bus_priv), |