aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/root.c9
-rw-r--r--drivers/core/simple-bus.c3
-rw-r--r--drivers/i2c/i2c-uclass.c15
-rw-r--r--drivers/i2c/sandbox_i2c.c4
-rw-r--r--drivers/misc/cros_ec.c9
-rw-r--r--drivers/mmc/dw_mmc.c6
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c32
-rw-r--r--drivers/mmc/zynq_sdhci.c39
-rw-r--r--drivers/net/phy/marvell.c1
-rw-r--r--drivers/pch/pch-uclass.c15
-rw-r--r--drivers/pci/pci-uclass.c24
-rw-r--r--drivers/pci/pci_sandbox.c11
-rw-r--r--drivers/pinctrl/pinctrl_pic32.c9
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3036.c9
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3288.c15
-rw-r--r--drivers/power/Kconfig2
-rw-r--r--drivers/power/domain/Kconfig20
-rw-r--r--drivers/power/domain/Makefile7
-rw-r--r--drivers/power/domain/power-domain-uclass.c112
-rw-r--r--drivers/power/domain/sandbox-power-domain-test.c55
-rw-r--r--drivers/power/domain/sandbox-power-domain.c104
-rw-r--r--drivers/power/pmic/pm8916.c9
-rw-r--r--drivers/power/regulator/Kconfig2
-rw-r--r--drivers/spi/spi-uclass.c9
-rw-r--r--drivers/spmi/spmi-uclass.c8
-rw-r--r--drivers/usb/emul/usb-emul-uclass.c9
-rw-r--r--drivers/usb/host/ehci-zynq.c103
-rw-r--r--drivers/usb/host/usb-uclass.c9
28 files changed, 451 insertions, 199 deletions
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 1587024..33dc9c0 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 1a9c864..5c955da 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 20b30ff..dbd3789 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 2c84c41..4696a1a 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 e3229ef..aea8d61 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 2cf7bae..b58c282 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 6a0e971..8a96302 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 d405929..bcd154a 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 58d287b..4eeb0f6 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 7216660..af794eb 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 32590ce..342b78c 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 6de5130..6a84ee3 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 5cf97ec..9acac29 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 1f78bf8..6aea856 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 8cb3b82..ae8a4f1 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 3c44167..b422703 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 0000000..b904097
--- /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 0000000..c18292f
--- /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 0000000..1bb6262
--- /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 0000000..92a3a2a
--- /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 0000000..9071346
--- /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 d4c7d4a..2b65c69 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 465ff3f..17f22dd 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 8003f9b..247abfa 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 4ddd51b..6edece2 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 ee7ea5a..6e03c1e 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 37a7935..76642cd 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 69c9a50..be114fc 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),