]> git.sur5r.net Git - u-boot/commitdiff
Merge git://git.denx.de/u-boot-dm
authorTom Rini <trini@konsulko.com>
Thu, 28 Jul 2016 02:30:20 +0000 (22:30 -0400)
committerTom Rini <trini@konsulko.com>
Thu, 28 Jul 2016 02:30:20 +0000 (22:30 -0400)
51 files changed:
Makefile
arch/arm/Kconfig
arch/arm/cpu/armv8/zynqmp/Kconfig
arch/arm/mach-zynq/Kconfig
arch/sandbox/dts/test.dts
arch/sandbox/include/asm/power-domain.h [new file with mode: 0644]
arch/x86/lib/lpc-uclass.c
cmd/bdinfo.c
cmd/usb_mass_storage.c
common/spl/spl_mmc.c
common/usb_hub.c
configs/sandbox_defconfig
drivers/core/root.c
drivers/core/simple-bus.c
drivers/i2c/i2c-uclass.c
drivers/i2c/sandbox_i2c.c
drivers/misc/cros_ec.c
drivers/mmc/dw_mmc.c
drivers/mmc/socfpga_dw_mmc.c
drivers/mmc/zynq_sdhci.c
drivers/net/phy/marvell.c
drivers/pch/pch-uclass.c
drivers/pci/pci-uclass.c
drivers/pci/pci_sandbox.c
drivers/pinctrl/pinctrl_pic32.c
drivers/pinctrl/rockchip/pinctrl_rk3036.c
drivers/pinctrl/rockchip/pinctrl_rk3288.c
drivers/power/Kconfig
drivers/power/domain/Kconfig [new file with mode: 0644]
drivers/power/domain/Makefile [new file with mode: 0644]
drivers/power/domain/power-domain-uclass.c [new file with mode: 0644]
drivers/power/domain/sandbox-power-domain-test.c [new file with mode: 0644]
drivers/power/domain/sandbox-power-domain.c [new file with mode: 0644]
drivers/power/pmic/pm8916.c
drivers/power/regulator/Kconfig
drivers/spi/spi-uclass.c
drivers/spmi/spmi-uclass.c
drivers/usb/emul/usb-emul-uclass.c
drivers/usb/host/ehci-zynq.c
drivers/usb/host/usb-uclass.c
include/dm/device.h
include/dm/uclass-id.h
include/dwmmc.h
include/power-domain-uclass.h [new file with mode: 0644]
include/power-domain.h [new file with mode: 0644]
include/power/regulator.h
test/dm/Makefile
test/dm/bus.c
test/dm/i2c.c
test/dm/power-domain.c [new file with mode: 0644]
test/dm/spi.c

index bccfbaa11db76c4d85d70b34db1ed8a1ab69774c..99cc8cf2f701b4f3782dc7835127f3c3813a0674 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -638,6 +638,7 @@ libs-y += drivers/net/
 libs-y += drivers/net/phy/
 libs-y += drivers/pci/
 libs-y += drivers/power/ \
+       drivers/power/domain/ \
        drivers/power/fuel_gauge/ \
        drivers/power/mfd/ \
        drivers/power/pmic/ \
index 4a62d4b1083dd21c7bf120a00548c5923f1a670f..6de734f8f20f04b604294d45bc3f68bfbc89e513 100644 (file)
@@ -657,10 +657,13 @@ config ARCH_ZYNQ
        select DM_GPIO
        select SPL_DM if SPL
        select DM_MMC
+       select DM_MMC_OPS
        select DM_SPI
        select DM_SERIAL
        select DM_SPI_FLASH
        select SPL_SEPARATE_BSS if SPL
+       select DM_USB if USB
+       select BLK
 
 config ARCH_ZYNQMP
        bool "Support Xilinx ZynqMP Platform"
@@ -671,6 +674,10 @@ config ARCH_ZYNQMP
        select SUPPORT_SPL
        select CLK
        select SPL_CLK
+       select DM_USB if USB
+       select DM_MMC
+       select DM_MMC_OPS
+       select BLK
 
 config TEGRA
        bool "NVIDIA Tegra"
index 6c71d7840eb5428778660cb29633f91823dd3180..ed3305d71821f3421f403eceddd4420ec045bc61 100644 (file)
@@ -20,4 +20,8 @@ config SYS_CONFIG_NAME
 config ZYNQMP_USB
        bool "Configure ZynqMP USB"
 
+config SYS_MALLOC_F_LEN
+       default 0x600
+
+
 endif
index db3c5792939e837d9445de839e5e6867d75e50b3..a98232097b2830dfce95e17d56752a7ec9f24537 100644 (file)
@@ -17,4 +17,7 @@ config SYS_CONFIG_NAME
          Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
          will be used for board configuration.
 
+config SYS_MALLOC_F_LEN
+       default 0x600
+
 endif
index 9e46f9e815a6628b16669fb427b7f178b1bd5808..fff175d1b7a2da54a1d636b02c51a36571e55275 100644 (file)
                };
        };
 
+       pwrdom: power-domain {
+               compatible = "sandbox,power-domain";
+               #power-domain-cells = <1>;
+       };
+
+       power-domain-test {
+               compatible = "sandbox,power-domain-test";
+               power-domains = <&pwrdom 2>;
+       };
+
        ram {
                compatible = "sandbox,ram";
        };
diff --git a/arch/sandbox/include/asm/power-domain.h b/arch/sandbox/include/asm/power-domain.h
new file mode 100644 (file)
index 0000000..cad3885
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __SANDBOX_POWER_DOMAIN_H
+#define __SANDBOX_POWER_DOMAIN_H
+
+#include <common.h>
+
+struct udevice;
+
+int sandbox_power_domain_query(struct udevice *dev, unsigned long id);
+
+int sandbox_power_domain_test_get(struct udevice *dev);
+int sandbox_power_domain_test_on(struct udevice *dev);
+int sandbox_power_domain_test_off(struct udevice *dev);
+int sandbox_power_domain_test_free(struct udevice *dev);
+
+#endif
index c6e8f73d2254934497e9938bb8938188fd750d81..eb033e6b3f6312fc0ea82a054af9ac57383941b8 100644 (file)
@@ -7,24 +7,11 @@
 
 #include <common.h>
 #include <dm.h>
-#include <dm/root.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static int lpc_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(lpc) = {
        .id             = UCLASS_LPC,
        .name           = "lpc",
-       .post_bind      = lpc_uclass_post_bind,
+       .post_bind      = dm_scan_fdt_dev,
 };
index f2435ab7e52e51e8969787257dfdd1b1386906fc..1fb66c49174ad63b05f74e21f15e3b9f4db09505 100644 (file)
@@ -416,6 +416,11 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc,
 #ifdef CONFIG_BOARD_TYPES
        printf("Board Type  = %ld\n", gd->board_type);
 #endif
+#ifdef CONFIG_SYS_MALLOC_F
+       printf("Early malloc usage: %lx / %x\n", gd->malloc_ptr,
+              CONFIG_SYS_MALLOC_F_LEN);
+#endif
+
        return 0;
 }
 
index b05913ac34464903bbc285f52b7a129843bbf5cf..86398fc24e8bf799887d46a60fb4b2b091cba98f 100644 (file)
@@ -22,7 +22,7 @@ static int ums_read_sector(struct ums *ums_dev,
        struct blk_desc *block_dev = &ums_dev->block_dev;
        lbaint_t blkstart = start + ums_dev->start_sector;
 
-       return block_dev->block_read(block_dev, blkstart, blkcnt, buf);
+       return blk_dread(block_dev, blkstart, blkcnt, buf);
 }
 
 static int ums_write_sector(struct ums *ums_dev,
@@ -31,7 +31,7 @@ static int ums_write_sector(struct ums *ums_dev,
        struct blk_desc *block_dev = &ums_dev->block_dev;
        lbaint_t blkstart = start + ums_dev->start_sector;
 
-       return block_dev->block_write(block_dev, blkstart, blkcnt, buf);
+       return blk_dwrite(block_dev, blkstart, blkcnt, buf);
 }
 
 static struct ums *ums;
index 6b3e9e4a17a0e6be63179c9a944fb98313d3d76e..7c7f32959b224a44b789bc8b4642c60b2e28655f 100644 (file)
@@ -155,7 +155,7 @@ static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
        disk_partition_t info;
        int err;
 
-       err = part_get_info(&mmc->block_dev, partition, &info);
+       err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                puts("spl: partition error\n");
index 0f39c9faf7ea4248cd8e60da5fc1b6446208ebf7..ff9cd50eab7c4f7a335572f0e226f53bb285c04c 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/state.h>
 #endif
 #include <asm/unaligned.h>
-#include <dm/root.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -755,12 +754,6 @@ int usb_hub_scan(struct udevice *hub)
        return usb_hub_configure(udev);
 }
 
-static int usb_hub_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 usb_hub_post_probe(struct udevice *dev)
 {
        debug("%s\n", __func__);
@@ -782,7 +775,7 @@ U_BOOT_DRIVER(usb_generic_hub) = {
 UCLASS_DRIVER(usb_hub) = {
        .id             = UCLASS_USB_HUB,
        .name           = "usb_hub",
-       .post_bind      = usb_hub_post_bind,
+       .post_bind      = dm_scan_fdt_dev,
        .post_probe     = usb_hub_post_probe,
        .child_pre_probe        = usb_child_pre_probe,
        .per_child_auto_alloc_size = sizeof(struct usb_device),
index 29e6d85bd4c44de25f5dcb4e41782b8ab142ad35..887d83acfd5e35d164c9d8c2af5e531aa77cc6ce 100644 (file)
@@ -176,3 +176,5 @@ CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
 CONFIG_UT_ENV=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_SANDBOX_POWER_DOMAIN=y
index 158702406ed19e617307de370a9ba4d6ab6b1565..33dc9c0b2db5acd8b2a7c1bd4be1b762eab70e48 100644 (file)
@@ -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);
index 1a9c864ef377e65334f0cf50a1e83e49be8675a2..5c955da3346b2c1ff665060100b2f875a87cbe50 100644 (file)
@@ -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) = {
index 20b30ffbeb5197217c382a84fa37f5b87c6b96e9..dbd3789747dfdacc1ca2fc013203ff8d4f416e05 100644 (file)
@@ -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),
index 2c84c41643c8b442dea3634ac36367b97903b917..4696a1ae62a96650192e3234e7e4453513583101 100644 (file)
@@ -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;
 
index e3229efed0bb44529653b662765705949e852b13..aea8d61f347df8bceb15450174ab249490da0e59 100644 (file)
@@ -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,
 };
index 2cf7bae79232dac03f45ca30e293097179537870..b58c2824167328151357035b39202f2b78167ea7 100644 (file)
@@ -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
index 6a0e9719b8a49cb354b46ed711350e2bb47a2293..8a9630208c5b5f27b70c884864b8aefad53e7348 100644 (file)
@@ -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),
 };
index d405929b64140fa4355bf7c399850ab76a3da645..bcd154a70745e6f2b43ea4a524b23fa181167a10 100644 (file)
 # 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),
 };
index 58d287bb071eed5ce1af2ce037625b17fbc183d6..4eeb0f6ede8c88e82ed5bb859976d0e328d31423 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <config.h>
 #include <common.h>
+#include <errno.h>
 #include <phy.h>
 
 #define PHY_AUTONEGOTIATE_TIMEOUT 5000
index 7216660a24c773e5910e2c3658a9d540d74135fc..af794eb5a128e845b84bd6fe996544b01feb43dd 100644 (file)
@@ -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,
 };
index 32590ce498a7505971faaefe4324d0205d581f16..342b78c0c4ba566518284fe04d5e64468e921c72 100644 (file)
@@ -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,
index 6de5130c2a89748a87a683c1e35614ed1b9d0aed..6a84ee386d796e3422325824b02f357898bb0b44 100644 (file)
@@ -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),
 };
index 5cf97ecec86fce1d3d4808a527d359ca1badaec5..9acac29133cb900259eab828c7aa90a771060dbe 100644 (file)
@@ -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),
 };
index 1f78bf862dbc6f0255c07d347dc12e72fb6a0d92..6aea856aa63f119b816ac62ac0879e7e711411f1 100644 (file)
@@ -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,
 };
index 8cb3b8228ed3aa4f61e68d8684e045448505a2d3..ae8a4f1fde681b44ff4545805338e683a531245e 100644 (file)
@@ -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,
 };
index 3c4416780591e6cc1a47a595b49d52e709eb3684..b4227031265077a0c1e7fdb03e4a7266dfa164f9 100644 (file)
@@ -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 (file)
index 0000000..b904097
--- /dev/null
@@ -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 (file)
index 0000000..c18292f
--- /dev/null
@@ -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 (file)
index 0000000..1bb6262
--- /dev/null
@@ -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 (file)
index 0000000..92a3a2a
--- /dev/null
@@ -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 (file)
index 0000000..9071346
--- /dev/null
@@ -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];
+}
index d4c7d4adff1fd53fb1db33ec495ac175a84f4a81..2b65c697ec9431a87497b29011638464fcef628e 100644 (file)
@@ -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),
index 465ff3fda616055daf964ca15bf2797b058c4695..17f22dda2bdd21158853b1724cfb96e9d801bcc8 100644 (file)
@@ -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
index 8003f9bfc8635cb32d0f7808f7c5a3e11bf2c2ed..247abfa72ba1c28f904bd8df846df2e17464e441 100644 (file)
@@ -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),
index 4ddd51b556ec1e3092ffe82dcd23ca1c2ea0db87..6edece23d82bf991d0cf0d484cbd60c2b2142475 100644 (file)
@@ -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,
 };
index ee7ea5ad91cf2b9238c470a823cdf547e915bded..6e03c1e0d9e7f1273990fd2967e77a17c2efa862 100644 (file)
@@ -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),
 };
index 37a7935b436d52877097bab4f98a7ba4b97bbae4..76642cdad7de1b05b740cd3a505b62f7e4f803eb 100644 (file)
@@ -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,
+};
index 69c9a504ebb8ad8489523868b8991d871115c3d4..be114fc07715b3a900551cc1a55ba2da5198ecdb 100644 (file)
@@ -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),
index 705849b228c648b427a2b1c2d58d7b3e19867380..babf8ac8f078c97e7f9e6c081dc7f1a68214dc36 100644 (file)
@@ -612,6 +612,22 @@ static inline bool device_is_on_pci_bus(struct udevice *dev)
 #define device_foreach_child_safe(pos, next, parent)   \
        list_for_each_entry_safe(pos, next, &parent->child_head, sibling_node)
 
+/**
+ * dm_scan_fdt_dev() - Bind child device in a the device tree
+ *
+ * This handles device which have sub-nodes in the device tree. It scans all
+ * sub-nodes and binds drivers for each node where a driver can be found.
+ *
+ * If this is called prior to relocation, only pre-relocation devices will be
+ * bound (those marked with u-boot,dm-pre-reloc in the device tree, or where
+ * the driver has the DM_FLAG_PRE_RELOC flag set). Otherwise, all devices will
+ * be bound.
+ *
+ * @dev:       Device to scan
+ * @return 0 if OK, -ve on error
+ */
+int dm_scan_fdt_dev(struct udevice *dev);
+
 /* device resource management */
 typedef void (*dr_release_t)(struct udevice *dev, void *res);
 typedef int (*dr_match_t)(struct udevice *dev, void *res, void *match_data);
index c5cdfc79d101103f153cdc039e01c739818cbd17..eb78c4dac485ac7a5bbe901b83b009ff827db278 100644 (file)
@@ -59,6 +59,7 @@ enum uclass_id {
        UCLASS_PINCTRL,         /* Pinctrl (pin muxing/configuration) device */
        UCLASS_PMIC,            /* PMIC I/O device */
        UCLASS_PWM,             /* Pulse-width modulator */
+       UCLASS_POWER_DOMAIN,    /* (SoC) Power domains */
        UCLASS_PWRSEQ,          /* Power sequence device */
        UCLASS_RAM,             /* RAM controller */
        UCLASS_REGULATOR,       /* Regulator device */
index 6aebe96b97bc795b711e51ef33a4d2d5434fca5c..d18ec8463b672ef08bd1c0807c158d2d6d838980 100644 (file)
@@ -256,8 +256,8 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
  * @name:      Device name (normally dev->name)
  * @buswidth:  Bus width (in bits, such as 4 or 8)
  * @caps:      Host capabilities (MMC_MODE_...)
- * @max_clk:   Maximum supported clock speed in HZ (e.g. 400000)
- * @min_clk:   Minimum supported clock speed in HZ (e.g. 150000000)
+ * @max_clk:   Maximum supported clock speed in HZ (e.g. 150000000)
+ * @min_clk:   Minimum supported clock speed in HZ (e.g. 400000)
  */
 void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
                     uint caps, u32 max_clk, u32 min_clk);
@@ -286,8 +286,8 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
  * This is used when you are not using CONFIG_BLK. Convert your driver over!
  *
  * @host:      DWMMC host structure
- * @max_clk:   Maximum supported clock speed in HZ (e.g. 400000)
- * @min_clk:   Minimum supported clock speed in HZ (e.g. 150000000)
+ * @max_clk:   Maximum supported clock speed in HZ (e.g. 150000000)
+ * @min_clk:   Minimum supported clock speed in HZ (e.g. 400000)
  * @return 0 if OK, -ve on error
  */
 int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
@@ -295,9 +295,6 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
 
 #ifdef CONFIG_DM_MMC_OPS
 /* Export the operations to drivers */
-int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
-                  struct mmc_data *data);
-int dwmci_set_ios(struct udevice *dev);
 int dwmci_probe(struct udevice *dev);
 extern const struct dm_mmc_ops dm_dwmci_ops;
 #endif
diff --git a/include/power-domain-uclass.h b/include/power-domain-uclass.h
new file mode 100644 (file)
index 0000000..5878021
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _POWER_DOMAIN_UCLASS_H
+#define _POWER_DOMAIN_UCLASS_H
+
+/* See power-domain.h for background documentation. */
+
+#include <power-domain.h>
+
+struct udevice;
+
+/**
+ * struct power_domain_ops - The functions that a power domain controller driver
+ * must implement.
+ */
+struct power_domain_ops {
+       /**
+        * of_xlate - Translate a client's device-tree (OF) power domain
+        * specifier.
+        *
+        * The power domain core calls this function as the first step in
+        * implementing a client's power_domain_get() call.
+        *
+        * If this function pointer is set to NULL, the power domain core will
+        * use a default implementation, which assumes #power-domain-cells =
+        * <1>, and that the DT cell contains a simple integer power domain ID.
+        *
+        * At present, the power domain API solely supports device-tree. If
+        * this changes, other xxx_xlate() functions may be added to support
+        * those other mechanisms.
+        *
+        * @power_domain:       The power domain struct to hold the
+        *                      translation result.
+        * @args:               The power domain specifier values from device
+        *                      tree.
+        * @return 0 if OK, or a negative error code.
+        */
+       int (*of_xlate)(struct power_domain *power_domain,
+                       struct fdtdec_phandle_args *args);
+       /**
+        * request - Request a translated power domain.
+        *
+        * The power domain core calls this function as the second step in
+        * implementing a client's power_domain_get() call, following a
+        * successful xxx_xlate() call.
+        *
+        * @power_domain:       The power domain to request; this has been
+        *                      filled in by a previous xxx_xlate() function
+        *                      call.
+        * @return 0 if OK, or a negative error code.
+        */
+       int (*request)(struct power_domain *power_domain);
+       /**
+        * free - Free a previously requested power domain.
+        *
+        * This is the implementation of the client power_domain_free() API.
+        *
+        * @power_domain:       The power domain to free.
+        * @return 0 if OK, or a negative error code.
+        */
+       int (*free)(struct power_domain *power_domain);
+       /**
+        * on - Power on a power domain.
+        *
+        * @power_domain:       The power domain to turn on.
+        * @return 0 if OK, or a negative error code.
+        */
+       int (*on)(struct power_domain *power_domain);
+       /**
+        * off - Power off a power domain.
+        *
+        * @power_domain:       The power domain to turn off.
+        * @return 0 if OK, or a negative error code.
+        */
+       int (*off)(struct power_domain *power_domain);
+};
+
+#endif
diff --git a/include/power-domain.h b/include/power-domain.h
new file mode 100644 (file)
index 0000000..1099979
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _POWER_DOMAIN_H
+#define _POWER_DOMAIN_H
+
+/**
+ * A power domain is a portion of an SoC or chip that is powered by a
+ * switchable source of power. In many cases, software has control over the
+ * power domain, and can turn the power source on or off. This is typically
+ * done to save power by powering off unused devices, or to enable software
+ * sequencing of initial powerup at boot. This API provides a means for
+ * drivers to turn power domains on and off.
+ *
+ * A driver that implements UCLASS_POWER_DOMAIN is a power domain controller or
+ * provider. A controller will often implement multiple separate power domains,
+ * since the hardware it manages often has this capability.
+ * power-domain-uclass.h describes the interface which power domain controllers
+ * must implement.
+ *
+ * Depending on the power domain controller hardware, changing the state of a
+ * power domain may require performing related operations on other resources.
+ * For example, some power domains may require certain clocks to be enabled
+ * whenever the power domain is powered on, or during the time when the power
+ * domain is transitioning state. These details are implementation-specific
+ * and should ideally be encapsulated entirely within the provider driver, or
+ * configured through mechanisms (e.g. device tree) that do not require client
+ * drivers to provide extra configuration information.
+ *
+ * Power domain consumers/clients are the drivers for HW modules within the
+ * power domain. This header file describes the API used by those drivers.
+ *
+ * In many cases, a single complex IO controller (e.g. a PCIe controller) will
+ * be the sole logic contained within a power domain. In such cases, it is
+ * logical for the relevant device driver to directly control that power
+ * domain. In other cases, multiple controllers, each with their own driver,
+ * may be contained in a single power domain. Any logic require to co-ordinate
+ * between drivers for these multiple controllers is beyond the scope of this
+ * API at present. Equally, this API does not define or implement any policy
+ * by which power domains are managed.
+ */
+
+struct udevice;
+
+/**
+ * struct power_domain - A handle to (allowing control of) a single power domain.
+ *
+ * Clients provide storage for power domain handles. The content of the
+ * structure is managed solely by the power domain API and power domain
+ * drivers. A power domain struct is initialized by "get"ing the power domain
+ * struct. The power domain struct is passed to all other power domain APIs to
+ * identify which power domain to operate upon.
+ *
+ * @dev: The device which implements the power domain.
+ * @id: The power domain ID within the provider.
+ *
+ * Currently, the power domain API assumes that a single integer ID is enough
+ * to identify and configure any power domain for any power domain provider. If
+ * this assumption becomes invalid in the future, the struct could be expanded
+ * to either (a) add more fields to allow power domain providers to store
+ * additional information, or (b) replace the id field with an opaque pointer,
+ * which the provider would dynamically allocate during its .of_xlate op, and
+ * process during is .request op. This may require the addition of an extra op
+ * to clean up the allocation.
+ */
+struct power_domain {
+       struct udevice *dev;
+       /*
+        * Written by of_xlate. We assume a single id is enough for now. In the
+        * future, we might add more fields here.
+        */
+       unsigned long id;
+};
+
+/**
+ * power_domain_get - Get/request the power domain for a device.
+ *
+ * This looks up and requests a power domain. Each device is assumed to have
+ * a single (or, at least one) power domain associated with it somehow, and
+ * that domain, or the first/default domain. The mapping of client device to
+ * provider power domain may be via device-tree properties, board-provided
+ * mapping tables, or some other mechanism.
+ *
+ * @dev:       The client device.
+ * @power_domain       A pointer to a power domain struct to initialize.
+ * @return 0 if OK, or a negative error code.
+ */
+int power_domain_get(struct udevice *dev, struct power_domain *power_domain);
+
+/**
+ * power_domain_free - Free a previously requested power domain.
+ *
+ * @power_domain:      A power domain struct that was previously successfully
+ *             requested by power_domain_get().
+ * @return 0 if OK, or a negative error code.
+ */
+int power_domain_free(struct power_domain *power_domain);
+
+/**
+ * power_domain_on - Enable power to a power domain.
+ *
+ * @power_domain:      A power domain struct that was previously successfully
+ *             requested by power_domain_get().
+ * @return 0 if OK, or a negative error code.
+ */
+int power_domain_on(struct power_domain *power_domain);
+
+/**
+ * power_domain_off - Disable power ot a power domain.
+ *
+ * @power_domain:      A power domain struct that was previously successfully
+ *             requested by power_domain_get().
+ * @return 0 if OK, or a negative error code.
+ */
+int power_domain_off(struct power_domain *power_domain);
+
+#endif
index 63c0814fe83cea2be9bb800940971c7f420395de..9bcd728120aa9a53b2f4d1a4ebe157539a7d1675 100644 (file)
@@ -54,7 +54,7 @@
  * which does the scan on the device node, for the 'regulator-name' constraint.
  * If the parent is not a PMIC device, and the child is not bind by function:
  * 'pmic_bind_childs()', then it's recommended to bind the device by call to
- * dm_scan_fdt_node() - this is usually done automatically for bus devices,
+ * dm_scan_fdt_dev() - this is usually done automatically for bus devices,
  * as a post bind method.
  *
  * Regulator get:
index cad3374e43d67694b32804af00a47691800fd1fb..1885e17c38d39d2dfa65238288db8898951460b7 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_LED) += led.o
 obj-$(CONFIG_DM_MAILBOX) += mailbox.o
 obj-$(CONFIG_DM_MMC) += mmc.o
 obj-$(CONFIG_DM_PCI) += pci.o
+obj-$(CONFIG_POWER_DOMAIN) += power-domain.o
 obj-$(CONFIG_RAM) += ram.o
 obj-y += regmap.o
 obj-$(CONFIG_REMOTEPROC) += remoteproc.o
index 3b5a23b934e3678b7527cbf8c6b3919e259a5e4b..d94dcf7a60d87988d9c50dae5f959c056a3777be 100644 (file)
@@ -7,7 +7,6 @@
 #include <common.h>
 #include <dm.h>
 #include <dm/device-internal.h>
-#include <dm/root.h>
 #include <dm/test.h>
 #include <dm/uclass-internal.h>
 #include <dm/util.h>
@@ -30,7 +29,7 @@ static struct dm_test_state *test_state;
 
 static int testbus_drv_probe(struct udevice *dev)
 {
-       return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+       return dm_scan_fdt_dev(dev);
 }
 
 static int testbus_child_post_bind(struct udevice *dev)
index 23d612eb81eb77368181891a3ef123d51d88bbcd..e2688bfbe9c06d29cf7806253adc5d5e8ba18ec2 100644 (file)
@@ -31,8 +31,8 @@ static int dm_test_i2c_find(struct unit_test_state *uts)
                                                       false, &bus));
 
        /*
-        * i2c_post_bind() will bind devices to chip selects. Check this then
-        * remove the emulation and the slave device.
+        * The post_bind() method will bind devices to chip selects. Check
+        * this then remove the emulation and the slave device.
         */
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
        ut_assertok(dm_i2c_probe(bus, chip, 0, &dev));
diff --git a/test/dm/power-domain.c b/test/dm/power-domain.c
new file mode 100644 (file)
index 0000000..379a8fa
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <asm/power-domain.h>
+#include <test/ut.h>
+
+/* This must match the specifier for power-domains in the DT node */
+#define TEST_POWER_DOMAIN 2
+
+static int dm_test_power_domain(struct unit_test_state *uts)
+{
+       struct udevice *dev_power_domain;
+       struct udevice *dev_test;
+
+       ut_assertok(uclass_get_device_by_name(UCLASS_POWER_DOMAIN,
+                                             "power-domain",
+                                             &dev_power_domain));
+       ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
+       ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
+                                                 TEST_POWER_DOMAIN));
+
+       ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test",
+                                             &dev_test));
+       ut_assertok(sandbox_power_domain_test_get(dev_test));
+
+       ut_assertok(sandbox_power_domain_test_on(dev_test));
+       ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
+       ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+                                                 TEST_POWER_DOMAIN));
+
+       ut_assertok(sandbox_power_domain_test_off(dev_test));
+       ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0));
+       ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
+                                                 TEST_POWER_DOMAIN));
+
+       ut_assertok(sandbox_power_domain_test_free(dev_test));
+
+       return 0;
+}
+DM_TEST(dm_test_power_domain, DM_TESTF_SCAN_FDT);
index 2e27da72d505c6afe2df467c0f89fad1ad08c4a5..5733096066c9780a4539270856b03ef4840ffab3 100644 (file)
@@ -30,8 +30,8 @@ static int dm_test_spi_find(struct unit_test_state *uts)
                                                       false, &bus));
 
        /*
-        * spi_post_bind() will bind devices to chip selects. Check this then
-        * remove the emulation and the slave device.
+        * The post_bind() method will bind devices to chip selects. Check
+        * this then remove the emulation and the slave device.
         */
        ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus));
        ut_assertok(spi_cs_info(bus, cs, &info));