summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig6
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/ata/sata_ceva.c28
-rw-r--r--drivers/block/blk-uclass.c23
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/fs_loader.c295
-rw-r--r--drivers/misc/fsl_portals.c11
-rw-r--r--drivers/mmc/omap_hsmmc.c12
-rw-r--r--drivers/net/fm/fm.c2
-rw-r--r--drivers/net/fm/init.c3
-rw-r--r--drivers/net/fsl-mc/mc.c41
-rw-r--r--drivers/net/pfe_eth/pfe_mdio.c1
-rw-r--r--drivers/pinctrl/pinctrl-sandbox.c3
-rw-r--r--drivers/qe/Kconfig12
-rw-r--r--drivers/qe/qe.c2
-rw-r--r--drivers/w1-eeprom/Kconfig29
-rw-r--r--drivers/w1-eeprom/Makefile5
-rw-r--r--drivers/w1-eeprom/ds24xxx.c55
-rw-r--r--drivers/w1-eeprom/eep_sandbox.c61
-rw-r--r--drivers/w1-eeprom/w1-eeprom-uclass.c116
-rw-r--r--drivers/w1/Kconfig25
-rw-r--r--drivers/w1/Makefile3
-rw-r--r--drivers/w1/w1-gpio.c176
-rw-r--r--drivers/w1/w1-uclass.c240
25 files changed, 1140 insertions, 21 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 56536c4b19..9ac90c461f 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -74,6 +74,8 @@ source "drivers/power/Kconfig"
source "drivers/pwm/Kconfig"
+source "drivers/qe/Kconfig"
+
source "drivers/ram/Kconfig"
source "drivers/remoteproc/Kconfig"
@@ -106,6 +108,10 @@ source "drivers/usb/Kconfig"
source "drivers/video/Kconfig"
+source "drivers/w1/Kconfig"
+
+source "drivers/w1-eeprom/Kconfig"
+
source "drivers/watchdog/Kconfig"
config PHYS_TO_BUS
diff --git a/drivers/Makefile b/drivers/Makefile
index 23ea609b09..1d5905fe73 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -105,6 +105,8 @@ obj-y += smem/
obj-y += soc/
obj-y += thermal/
obj-y += axi/
+obj-$(CONFIG_W1) += w1/
+obj-$(CONFIG_W1_EEPROM) += w1-eeprom/
obj-$(CONFIG_MACH_PIC32) += ddr/microchip/
endif
diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c
index 047cff7f83..65896d1705 100644
--- a/drivers/ata/sata_ceva.c
+++ b/drivers/ata/sata_ceva.c
@@ -81,13 +81,24 @@
#define CEVA_TRANS_CFG 0x08000029
#define CEVA_AXICC_CFG 0x3fffffff
+/* for ls1021a */
+#define LS1021_AHCI_VEND_AXICC 0xC0
+#define LS1021_CEVA_PHY2_CFG 0x28183414
+#define LS1021_CEVA_PHY3_CFG 0x0e080e06
+#define LS1021_CEVA_PHY4_CFG 0x064a080b
+#define LS1021_CEVA_PHY5_CFG 0x2aa86470
+
/* ecc addr-val pair */
#define ECC_DIS_ADDR_CH2 0x80000000
-#define ECC_DIS_VAL_CH2 0x20140520
+#define ECC_DIS_VAL_CH2 0x20140520
+#define SATA_ECC_REG_ADDR 0x20220520
+#define SATA_ECC_DISABLE 0x00020000
enum ceva_soc {
CEVA_1V84,
CEVA_LS1012A,
+ CEVA_LS1021A,
+ CEVA_LS1043A,
};
struct ceva_sata_priv {
@@ -113,7 +124,20 @@ static int ceva_init_sata(struct ceva_sata_priv *priv)
writel(tmp, base + AHCI_VEND_PTC);
break;
+ case CEVA_LS1021A:
+ writel(SATA_ECC_DISABLE, SATA_ECC_REG_ADDR);
+ writel(CEVA_PHY1_CFG, base + AHCI_VEND_PPCFG);
+ writel(LS1021_CEVA_PHY2_CFG, base + AHCI_VEND_PP2C);
+ writel(LS1021_CEVA_PHY3_CFG, base + AHCI_VEND_PP3C);
+ writel(LS1021_CEVA_PHY4_CFG, base + AHCI_VEND_PP4C);
+ writel(LS1021_CEVA_PHY5_CFG, base + AHCI_VEND_PP5C);
+ writel(CEVA_TRANS_CFG, base + AHCI_VEND_PTC);
+ if (priv->flag & FLAG_COHERENT)
+ writel(CEVA_AXICC_CFG, base + LS1021_AHCI_VEND_AXICC);
+ break;
+
case CEVA_LS1012A:
+ case CEVA_LS1043A:
writel(ECC_DIS_ADDR_CH2, ECC_DIS_VAL_CH2);
writel(CEVA_PHY1_CFG, base + AHCI_VEND_PPCFG);
writel(CEVA_TRANS_CFG, base + AHCI_VEND_PTC);
@@ -144,6 +168,8 @@ static int sata_ceva_probe(struct udevice *dev)
static const struct udevice_id sata_ceva_ids[] = {
{ .compatible = "ceva,ahci-1v84", .data = CEVA_1V84 },
{ .compatible = "fsl,ls1012a-ahci", .data = CEVA_LS1012A },
+ { .compatible = "fsl,ls1021a-ahci", .data = CEVA_LS1021A },
+ { .compatible = "fsl,ls1043a-ahci", .data = CEVA_LS1043A },
{ }
};
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 9e0c823969..facf52711c 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -132,6 +132,29 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
}
/**
+ * blk_get_by_device() - Get the block device descriptor for the given device
+ * @dev: Instance of a storage device
+ *
+ * Return: With block device descriptor on success , NULL if there is no such
+ * block device.
+ */
+struct blk_desc *blk_get_by_device(struct udevice *dev)
+{
+ struct udevice *child_dev, *next;
+
+ device_foreach_child_safe(child_dev, next, dev) {
+ if (device_get_uclass_id(child_dev) != UCLASS_BLK)
+ continue;
+
+ return dev_get_uclass_platdata(child_dev);
+ }
+
+ debug("%s: No block device found\n", __func__);
+
+ return NULL;
+}
+
+/**
* get_desc() - Get the block device descriptor for the given device number
*
* @if_type: Interface type
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index bfa5c91687..b0fb73f692 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -295,4 +295,13 @@ config MPC83XX_SERDES
help
Support for serdes found on MPC83xx SoCs.
+config FS_LOADER
+ bool "Enable loader driver for file system"
+ help
+ This is file system generic loader which can be used to load
+ the file image from the storage into target such as memory.
+
+ The consumer driver would then use this loader to program whatever,
+ ie. the FPGA device.
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index da4666fdfc..acf24c44fa 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -56,3 +56,4 @@ obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o
+obj-$(CONFIG_FS_LOADER) += fs_loader.o
diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c
new file mode 100644
index 0000000000..5fe642b4be
--- /dev/null
+++ b/drivers/misc/fs_loader.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2018 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <blk.h>
+#include <fs.h>
+#include <fs_loader.h>
+#include <linux/string.h>
+#include <mapmem.h>
+#include <malloc.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct firmware_priv {
+ const char *name; /* Filename */
+ u32 offset; /* Offset of reading a file */
+};
+
+#ifdef CONFIG_CMD_UBIFS
+static int mount_ubifs(char *mtdpart, char *ubivol)
+{
+ int ret = ubi_part(mtdpart, NULL);
+
+ if (ret) {
+ debug("Cannot find mtd partition %s\n", mtdpart);
+ return ret;
+ }
+
+ return cmd_ubifs_mount(ubivol);
+}
+
+static int umount_ubifs(void)
+{
+ return cmd_ubifs_umount();
+}
+#else
+static int mount_ubifs(char *mtdpart, char *ubivol)
+{
+ debug("Error: Cannot load image: no UBIFS support\n");
+ return -ENOSYS;
+}
+#endif
+
+static int select_fs_dev(struct device_platdata *plat)
+{
+ int ret;
+
+ if (plat->phandlepart.phandle) {
+ ofnode node;
+
+ node = ofnode_get_by_phandle(plat->phandlepart.phandle);
+
+ int of_offset = ofnode_to_offset(node);
+
+ struct udevice *dev;
+
+ ret = device_get_global_by_of_offset(of_offset, &dev);
+ if (!ret) {
+ struct blk_desc *desc = blk_get_by_device(dev);
+ if (desc) {
+ ret = fs_set_blk_dev_with_part(desc,
+ plat->phandlepart.partition);
+ } else {
+ debug("%s: No device found\n", __func__);
+ return -ENODEV;
+ }
+ }
+ } else if (plat->mtdpart && plat->ubivol) {
+ ret = mount_ubifs(plat->mtdpart, plat->ubivol);
+ if (ret)
+ return ret;
+
+ ret = fs_set_blk_dev("ubi", NULL, FS_TYPE_UBIFS);
+ } else {
+ debug("Error: unsupported storage device.\n");
+ return -ENODEV;
+ }
+
+ if (ret)
+ debug("Error: could not access storage.\n");
+
+ return ret;
+}
+
+/**
+ * _request_firmware_prepare - Prepare firmware struct.
+ *
+ * @name: Name of firmware file.
+ * @dbuf: Address of buffer to load firmware into.
+ * @size: Size of buffer.
+ * @offset: Offset of a file for start reading into buffer.
+ * @firmwarep: Pointer to pointer to firmware image.
+ *
+ * Return: Negative value if fail, 0 for successful.
+ */
+static int _request_firmware_prepare(const char *name, void *dbuf,
+ size_t size, u32 offset,
+ struct firmware **firmwarep)
+{
+ if (!name || name[0] == '\0')
+ return -EINVAL;
+
+ /* No memory allocation is required if *firmwarep is allocated */
+ if (!(*firmwarep)) {
+ (*firmwarep) = calloc(1, sizeof(struct firmware));
+ if (!(*firmwarep))
+ return -ENOMEM;
+
+ (*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv));
+ if (!(*firmwarep)->priv) {
+ free(*firmwarep);
+ return -ENOMEM;
+ }
+ } else if (!(*firmwarep)->priv) {
+ (*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv));
+ if (!(*firmwarep)->priv) {
+ free(*firmwarep);
+ return -ENOMEM;
+ }
+ }
+
+ ((struct firmware_priv *)((*firmwarep)->priv))->name = name;
+ ((struct firmware_priv *)((*firmwarep)->priv))->offset = offset;
+ (*firmwarep)->data = dbuf;
+ (*firmwarep)->size = size;
+
+ return 0;
+}
+
+/**
+ * release_firmware - Release the resource associated with a firmware image
+ * @firmware: Firmware resource to release
+ */
+void release_firmware(struct firmware *firmware)
+{
+ if (firmware) {
+ if (firmware->priv) {
+ free(firmware->priv);
+ firmware->priv = NULL;
+ }
+ free(firmware);
+ }
+}
+
+/**
+ * fw_get_filesystem_firmware - load firmware into an allocated buffer.
+ * @plat: Platform data such as storage and partition firmware loading from.
+ * @firmware: pointer to firmware image.
+ *
+ * Return: Size of total read, negative value when error.
+ */
+static int fw_get_filesystem_firmware(struct device_platdata *plat,
+ struct firmware *firmware)
+{
+ struct firmware_priv *fw_priv = NULL;
+ loff_t actread;
+ char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume;
+ int ret;
+
+ storage_interface = env_get("storage_interface");
+ dev_part = env_get("fw_dev_part");
+ ubi_mtdpart = env_get("fw_ubi_mtdpart");
+ ubi_volume = env_get("fw_ubi_volume");
+
+ if (storage_interface && dev_part) {
+ ret = fs_set_blk_dev(storage_interface, dev_part, FS_TYPE_ANY);
+ } else if (storage_interface && ubi_mtdpart && ubi_volume) {
+ ret = mount_ubifs(ubi_mtdpart, ubi_volume);
+ if (ret)
+ return ret;
+
+ if (!strcmp("ubi", storage_interface))
+ ret = fs_set_blk_dev(storage_interface, NULL,
+ FS_TYPE_UBIFS);
+ else
+ ret = -ENODEV;
+ } else {
+ ret = select_fs_dev(plat);
+ }
+
+ if (ret)
+ goto out;
+
+ fw_priv = firmware->priv;
+
+ ret = fs_read(fw_priv->name, (ulong)map_to_sysmem(firmware->data),
+ fw_priv->offset, firmware->size, &actread);
+ if (ret) {
+ debug("Error: %d Failed to read %s from flash %lld != %d.\n",
+ ret, fw_priv->name, actread, firmware->size);
+ } else {
+ ret = actread;
+ }
+
+out:
+#ifdef CONFIG_CMD_UBIFS
+ umount_ubifs();
+#endif
+ return ret;
+}
+
+/**
+ * request_firmware_into_buf - Load firmware into a previously allocated buffer.
+ * @plat: Platform data such as storage and partition firmware loading from.
+ * @name: Name of firmware file.
+ * @buf: Address of buffer to load firmware into.
+ * @size: Size of buffer.
+ * @offset: Offset of a file for start reading into buffer.
+ * @firmwarep: Pointer to firmware image.
+ *
+ * The firmware is loaded directly into the buffer pointed to by @buf and
+ * the @firmwarep data member is pointed at @buf.
+ *
+ * Return: Size of total read, negative value when error.
+ */
+int request_firmware_into_buf(struct device_platdata *plat,
+ const char *name,
+ void *buf, size_t size, u32 offset,
+ struct firmware **firmwarep)
+{
+ int ret;
+
+ if (!plat)
+ return -EINVAL;
+
+ ret = _request_firmware_prepare(name, buf, size, offset, firmwarep);
+ if (ret < 0) /* error */
+ return ret;
+
+ ret = fw_get_filesystem_firmware(plat, *firmwarep);
+
+ return ret;
+}
+
+static int fs_loader_ofdata_to_platdata(struct udevice *dev)
+{
+ const char *fs_loader_path;
+ u32 phandlepart[2];
+
+ fs_loader_path = ofnode_get_chosen_prop("firmware-loader");
+
+ if (fs_loader_path) {
+ ofnode fs_loader_node;
+
+ fs_loader_node = ofnode_path(fs_loader_path);
+ if (ofnode_valid(fs_loader_node)) {
+ struct device_platdata *plat;
+ plat = dev->platdata;
+
+ if (!ofnode_read_u32_array(fs_loader_node,
+ "phandlepart",
+ phandlepart, 2)) {
+ plat->phandlepart.phandle = phandlepart[0];
+ plat->phandlepart.partition = phandlepart[1];
+ }
+
+ plat->mtdpart = (char *)ofnode_read_string(
+ fs_loader_node, "mtdpart");
+
+ plat->ubivol = (char *)ofnode_read_string(
+ fs_loader_node, "ubivol");
+ }
+ }
+
+ return 0;
+}
+
+static int fs_loader_probe(struct udevice *dev)
+{
+ return 0;
+};
+
+static const struct udevice_id fs_loader_ids[] = {
+ { .compatible = "u-boot,fs-loader"},
+ { }
+};
+
+U_BOOT_DRIVER(fs_loader) = {
+ .name = "fs-loader",
+ .id = UCLASS_FS_FIRMWARE_LOADER,
+ .of_match = fs_loader_ids,
+ .probe = fs_loader_probe,
+ .ofdata_to_platdata = fs_loader_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct device_platdata),
+};
+
+UCLASS_DRIVER(fs_loader) = {
+ .id = UCLASS_FS_FIRMWARE_LOADER,
+ .name = "fs-loader",
+};
diff --git a/drivers/misc/fsl_portals.c b/drivers/misc/fsl_portals.c
index d3137680ad..45eed22f6e 100644
--- a/drivers/misc/fsl_portals.c
+++ b/drivers/misc/fsl_portals.c
@@ -49,7 +49,7 @@ void setup_qbman_portals(void)
out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn);
}
#else
-#ifdef CONFIG_ARCH_LS1046A
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
int i;
for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) {
@@ -197,7 +197,7 @@ void fdt_fixup_qportals(void *blob)
char compat[64];
int compat_len;
-#ifdef CONFIG_ARCH_LS1046A
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
int smmu_ph = fdt_get_smmu_phandle(blob);
#endif
@@ -211,7 +211,8 @@ void fdt_fixup_qportals(void *blob)
off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal");
while (off != -FDT_ERR_NOTFOUND) {
-#if defined(CONFIG_PPC) || defined(CONFIG_ARCH_LS1046A)
+#if defined(CONFIG_PPC) || defined(CONFIG_ARCH_LS1043A) || \
+defined(CONFIG_ARCH_LS1046A)
#ifdef CONFIG_FSL_CORENET
u32 liodns[2];
#endif
@@ -226,7 +227,7 @@ void fdt_fixup_qportals(void *blob)
int j;
#endif
-#endif /* CONFIG_PPC || CONFIG_ARCH_LS1046A */
+#endif /* CONFIG_PPC || CONFIG_ARCH_LS1043A || CONFIG_ARCH_LS1046A */
err = fdt_setprop(blob, off, "compatible", compat, compat_len);
if (err < 0)
goto err;
@@ -275,7 +276,7 @@ void fdt_fixup_qportals(void *blob)
goto err;
#endif
#else
-#ifdef CONFIG_ARCH_LS1046A
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
if (smmu_ph >= 0) {
u32 icids[3];
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 8ab56d247d..ec853d063f 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -83,7 +83,6 @@ struct omap_hsmmc_data {
#if CONFIG_IS_ENABLED(DM_MMC)
struct gpio_desc cd_gpio; /* Change Detect GPIO */
struct gpio_desc wp_gpio; /* Write Protect GPIO */
- bool cd_inverted;
#else
int cd_gpio;
int wp_gpio;
@@ -1368,17 +1367,15 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
#if CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_getcd(struct udevice *dev)
{
- struct omap_hsmmc_data *priv = dev_get_priv(dev);
int value = -1;
#if CONFIG_IS_ENABLED(DM_GPIO)
+ struct omap_hsmmc_data *priv = dev_get_priv(dev);
value = dm_gpio_get_value(&priv->cd_gpio);
#endif
/* if no CD return as 1 */
if (value < 0)
return 1;
- if (priv->cd_inverted)
- return !value;
return value;
}
@@ -1860,10 +1857,6 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
}
#endif
-#ifdef OMAP_HSMMC_USE_GPIO
- plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
-#endif
-
return 0;
}
#endif
@@ -1892,9 +1885,6 @@ static int omap_hsmmc_probe(struct udevice *dev)
priv->base_addr = plat->base_addr;
priv->controller_flags = plat->controller_flags;
priv->hw_rev = plat->hw_rev;
-#ifdef OMAP_HSMMC_USE_GPIO
- priv->cd_inverted = plat->cd_inverted;
-#endif
#ifdef CONFIG_BLK
mmc = plat->mmc;
diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c
index 3327073bf1..c5cf188f05 100644
--- a/drivers/net/fm/fm.c
+++ b/drivers/net/fm/fm.c
@@ -402,7 +402,7 @@ int fm_init_common(int index, struct ccsr_fman *reg)
printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
dev, blk, cnt);
mmc_init(mmc);
- (void)mmc->block_dev.block_read(&mmc->block_dev, blk, cnt,
+ (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt,
addr);
}
#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_REMOTE)
diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c
index 147d0437c5..f896e80b6d 100644
--- a/drivers/net/fm/init.c
+++ b/drivers/net/fm/init.c
@@ -328,7 +328,8 @@ void fdt_fixup_fman_ethernet(void *blob)
ft_fixup_port(blob, &fm_info[i],
"fsl,fman-1g-mac");
} else {
- if (ft_fixup_port(blob, &fm_info[i], "fsl,fman-tgec"))
+ if (ft_fixup_port(blob, &fm_info[i], "fsl,fman-xgec") &&
+ ft_fixup_port(blob, &fm_info[i], "fsl,fman-tgec"))
ft_fixup_port(blob, &fm_info[i],
"fsl,fman-10g-mac");
}
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 940025a467..d9a897dc86 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -2,6 +2,7 @@
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
+ * Copyright 2017-2018 NXP
*/
#include <common.h>
#include <errno.h>
@@ -29,6 +30,7 @@
#define MC_BOOT_ENV_VAR "mcinitcmd"
DECLARE_GLOBAL_DATA_PTR;
+static int mc_memset_resv_ram;
static int mc_boot_status = -1;
static int mc_dpl_applied = -1;
#ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
@@ -278,6 +280,40 @@ static int mc_fixup_dpl_mac_addr(void *blob, int dpmac_id,
MC_FIXUP_DPL);
}
+void fdt_fsl_mc_fixup_iommu_map_entry(void *blob)
+{
+ u32 *prop;
+ u32 iommu_map[4];
+ int offset;
+ int lenp;
+
+ /* find fsl-mc node */
+ offset = fdt_path_offset(blob, "/soc/fsl-mc");
+ if (offset < 0)
+ offset = fdt_path_offset(blob, "/fsl-mc");
+ if (offset < 0) {
+ printf("%s: fsl-mc: ERR: fsl-mc node not found in DT, err %d\n",
+ __func__, offset);
+ return;
+ }
+
+ prop = fdt_getprop_w(blob, offset, "iommu-map", &lenp);
+ if (!prop) {
+ debug("%s: fsl-mc: ERR: missing iommu-map in fsl-mc bus node\n",
+ __func__);
+ return;
+ }
+
+ iommu_map[0] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_START);
+ iommu_map[1] = *++prop;
+ iommu_map[2] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_START);
+ iommu_map[3] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_END -
+ FSL_DPAA2_STREAM_ID_START + 1);
+
+ fdt_setprop_inplace(blob, offset, "iommu-map",
+ iommu_map, sizeof(iommu_map));
+}
+
static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id,
struct eth_device *eth_dev)
{
@@ -810,6 +846,11 @@ u64 mc_get_dram_addr(void)
{
size_t mc_ram_size = mc_get_dram_block_size();
+ if (!mc_memset_resv_ram || (get_mc_boot_status() < 0)) {
+ mc_memset_resv_ram = 1;
+ memset((void *)gd->arch.resv_ram, 0, mc_ram_size);
+ }
+
return (gd->arch.resv_ram + mc_ram_size - 1) &
MC_RAM_BASE_ADDR_ALIGNMENT_MASK;
}
diff --git a/drivers/net/pfe_eth/pfe_mdio.c b/drivers/net/pfe_eth/pfe_mdio.c
index b53edb741f..2dde9e7ac8 100644
--- a/drivers/net/pfe_eth/pfe_mdio.c
+++ b/drivers/net/pfe_eth/pfe_mdio.c
@@ -162,7 +162,6 @@ static void pfe_configure_serdes(struct pfe_eth_dev *priv)
if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII_2500)
sgmii_2500 = 1;
- printf("%s %d\n", __func__, priv->gemac_port);
/* PCS configuration done with corresponding GEMAC */
bus.priv = gem_info[priv->gemac_port].gemac_base;
diff --git a/drivers/pinctrl/pinctrl-sandbox.c b/drivers/pinctrl/pinctrl-sandbox.c
index 468fa2a7d0..755ac08bdf 100644
--- a/drivers/pinctrl/pinctrl-sandbox.c
+++ b/drivers/pinctrl/pinctrl-sandbox.c
@@ -14,6 +14,7 @@ static const char * const sandbox_pins[] = {
"SDA",
"TX",
"RX",
+ "W1"
};
static const char * const sandbox_groups[] = {
@@ -21,12 +22,14 @@ static const char * const sandbox_groups[] = {
"serial_a",
"serial_b",
"spi",
+ "w1",
};
static const char * const sandbox_functions[] = {
"i2c",
"serial",
"spi",
+ "w1",
};
static const struct pinconf_param sandbox_conf_params[] = {
diff --git a/drivers/qe/Kconfig b/drivers/qe/Kconfig
new file mode 100644
index 0000000000..49a6e32b16
--- /dev/null
+++ b/drivers/qe/Kconfig
@@ -0,0 +1,12 @@
+#
+# QUICC Engine Drivers
+#
+config U_QE
+ bool "Enable support for U QUICC Engine"
+ default y if (ARCH_LS1021A && !SD_BOOT && !NAND_BOOT && !QSPI_BOOT) \
+ || (TARGET_T1024QDS) \
+ || (TARGET_T1024RDB) \
+ || (TARGET_T1040QDS && !NOBQFMAN) \
+ || (TARGET_LS1043ARDB && !SPL_NO_QE && !NAND_BOOT && !QSPI_BOOT)
+ help
+ Choose this option to add support for U QUICC Engine.
diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c
index 7654df8008..7010bbc230 100644
--- a/drivers/qe/qe.c
+++ b/drivers/qe/qe.c
@@ -218,7 +218,7 @@ void u_qe_init(void)
printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
dev, blk, cnt);
mmc_init(mmc);
- (void)mmc->block_dev.block_read(&mmc->block_dev, blk, cnt,
+ (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt,
addr);
}
#endif
diff --git a/drivers/w1-eeprom/Kconfig b/drivers/w1-eeprom/Kconfig
new file mode 100644
index 0000000000..4b7f3c4e0b
--- /dev/null
+++ b/drivers/w1-eeprom/Kconfig
@@ -0,0 +1,29 @@
+#
+# EEPROM subsystem configuration
+#
+
+menu "1-wire EEPROM support"
+
+config W1_EEPROM
+ bool "Enable support for EEPROMs on 1wire interface"
+ depends on DM
+ help
+ Support for the EEPROMs connected on 1-wire Dallas protocol interface
+
+if W1_EEPROM
+
+config W1_EEPROM_DS24XXX
+ bool "Enable Maxim DS24 families EEPROM support"
+ depends on W1
+ help
+ Maxim DS24 EEPROMs 1-Wire EEPROM support
+
+config W1_EEPROM_SANDBOX
+ bool "Enable sandbox onewire EEPROM driver"
+ depends on W1
+ help
+ Sandbox driver for a onewire EEPROM memory
+
+endif
+
+endmenu
diff --git a/drivers/w1-eeprom/Makefile b/drivers/w1-eeprom/Makefile
new file mode 100644
index 0000000000..03cc4c8ac8
--- /dev/null
+++ b/drivers/w1-eeprom/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_W1_EEPROM) += w1-eeprom-uclass.o
+
+obj-$(CONFIG_W1_EEPROM_DS24XXX) += ds24xxx.o
+
+obj-$(CONFIG_W1_EEPROM_SANDBOX) += eep_sandbox.o
diff --git a/drivers/w1-eeprom/ds24xxx.c b/drivers/w1-eeprom/ds24xxx.c
new file mode 100644
index 0000000000..56186e587c
--- /dev/null
+++ b/drivers/w1-eeprom/ds24xxx.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Copyright (c) 2015 Free Electrons
+ * Copyright (c) 2015 NextThing Co
+ * Copyright (c) 2018 Microchip Technology, Inc.
+ *
+ */
+
+#include <common.h>
+#include <linux/err.h>
+#include <dm.h>
+#include <w1-eeprom.h>
+#include <w1.h>
+
+#define W1_F2D_READ_EEPROM 0xf0
+
+static int ds24xxx_read_buf(struct udevice *dev, unsigned int offset,
+ u8 *buf, unsigned int count)
+{
+ w1_reset_select(dev);
+
+ w1_write_byte(dev, W1_F2D_READ_EEPROM);
+ w1_write_byte(dev, offset & 0xff);
+ w1_write_byte(dev, offset >> 8);
+
+ return w1_read_buf(dev, buf, count);
+}
+
+static int ds24xxx_probe(struct udevice *dev)
+{
+ struct w1_device *w1;
+
+ w1 = dev_get_platdata(dev);
+ w1->id = 0;
+ return 0;
+}
+
+static const struct w1_eeprom_ops ds24xxx_ops = {
+ .read_buf = ds24xxx_read_buf,
+};
+
+static const struct udevice_id ds24xxx_id[] = {
+ { .compatible = "maxim,ds24b33", .data = W1_FAMILY_DS24B33 },
+ { .compatible = "maxim,ds2431", .data = W1_FAMILY_DS2431 },
+ { },
+};
+
+U_BOOT_DRIVER(ds24xxx) = {
+ .name = "ds24xxx",
+ .id = UCLASS_W1_EEPROM,
+ .of_match = ds24xxx_id,
+ .ops = &ds24xxx_ops,
+ .probe = ds24xxx_probe,
+};
diff --git a/drivers/w1-eeprom/eep_sandbox.c b/drivers/w1-eeprom/eep_sandbox.c
new file mode 100644
index 0000000000..27c7f9f1b6
--- /dev/null
+++ b/drivers/w1-eeprom/eep_sandbox.c
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * Copyright (c) 2018 Microchip Technology, Inc.
+ *
+ */
+
+#include <common.h>
+#include <linux/err.h>
+#include <dm.h>
+#include <w1-eeprom.h>
+#include <w1.h>
+
+#define W1_F2D_READ_EEPROM 0xf0
+
+#define EEP_SANDBOX_SAMPLE_MEM "this is a sample EEPROM memory string."
+
+static int eep_sandbox_read_buf(struct udevice *dev, unsigned int offset,
+ u8 *buf, unsigned int count)
+{
+ /* do not allow to copy more than our maximum sample string */
+ if (offset + count < strlen(EEP_SANDBOX_SAMPLE_MEM)) {
+ offset = 0;
+ count = strlen(EEP_SANDBOX_SAMPLE_MEM);
+ }
+ strncpy((char *)buf, EEP_SANDBOX_SAMPLE_MEM, count);
+
+ /*
+ * in case the w1 subsystem uses some different kind of sandbox testing,
+ * like randomized gpio values , we take the buffer from there
+ */
+
+ w1_reset_select(dev);
+
+ w1_write_byte(dev, W1_F2D_READ_EEPROM);
+ w1_write_byte(dev, offset & 0xff);
+ w1_write_byte(dev, offset >> 8);
+
+ w1_read_buf(dev, buf, count);
+
+ /*
+ * even if read buf from w1 fails, return success as we hardcoded
+ * the buffer.
+ */
+ return 0;
+}
+
+static const struct w1_eeprom_ops eep_sandbox_ops = {
+ .read_buf = eep_sandbox_read_buf,
+};
+
+static const struct udevice_id eep_sandbox_id[] = {
+ { .compatible = "sandbox,w1-eeprom", .data = W1_FAMILY_EEP_SANDBOX },
+ { },
+};
+
+U_BOOT_DRIVER(eep_sandbox) = {
+ .name = "eep_sandbox",
+ .id = UCLASS_W1_EEPROM,
+ .of_match = eep_sandbox_id,
+ .ops = &eep_sandbox_ops,
+};
diff --git a/drivers/w1-eeprom/w1-eeprom-uclass.c b/drivers/w1-eeprom/w1-eeprom-uclass.c
new file mode 100644
index 0000000000..7b0579344c
--- /dev/null
+++ b/drivers/w1-eeprom/w1-eeprom-uclass.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Copyright (c) 2015 Free Electrons
+ * Copyright (c) 2015 NextThing Co.
+ * Copyright (c) 2018 Microchip Technology, Inc.
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ * Eugen Hristev <eugen.hristev@microchip.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <w1.h>
+#include <w1-eeprom.h>
+
+#include <dm/device-internal.h>
+
+int w1_eeprom_read_buf(struct udevice *dev, unsigned int offset,
+ u8 *buf, unsigned int count)
+{
+ const struct w1_eeprom_ops *ops = device_get_ops(dev);
+ u64 id = 0;
+ int ret;
+
+ if (!ops->read_buf)
+ return -ENOSYS;
+
+ ret = w1_eeprom_get_id(dev, &id);
+ if (ret)
+ return ret;
+ if (!id)
+ return -ENODEV;
+
+ return ops->read_buf(dev, offset, buf, count);
+}
+
+int w1_eeprom_register_new_device(u64 id)
+{
+ u8 family = id & 0xff;
+ int ret;
+ struct udevice *dev;
+
+ for (ret = uclass_first_device(UCLASS_W1_EEPROM, &dev);
+ !ret && dev;
+ uclass_next_device(&dev)) {
+ if (ret || !dev) {
+ debug("cannot find w1 eeprom dev\n");
+ return ret;
+ }
+ if (dev_get_driver_data(dev) == family) {
+ struct w1_device *w1;
+
+ w1 = dev_get_parent_platdata(dev);
+ if (w1->id) /* device already in use */
+ continue;
+ w1->id = id;
+ debug("%s: Match found: %s:%s %llx\n", __func__,
+ dev->name, dev->driver->name, id);
+ return 0;
+ }
+ }
+
+ debug("%s: No matches found: error %d\n", __func__, ret);
+
+ return ret;
+}
+
+int w1_eeprom_get_id(struct udevice *dev, u64 *id)
+{
+ struct w1_device *w1 = dev_get_parent_platdata(dev);
+
+ if (!w1)
+ return -ENODEV;
+ *id = w1->id;
+
+ return 0;
+}
+
+UCLASS_DRIVER(w1_eeprom) = {
+ .name = "w1_eeprom",
+ .id = UCLASS_W1_EEPROM,
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ .post_bind = dm_scan_fdt_dev,
+#endif
+};
+
+int w1_eeprom_dm_init(void)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_W1_EEPROM, &uc);
+ if (ret) {
+ debug("W1_EEPROM uclass not available\n");
+ return ret;
+ }
+
+ uclass_foreach_dev(dev, uc) {
+ ret = device_probe(dev);
+ if (ret == -ENODEV) { /* No such device. */
+ debug("W1_EEPROM not available.\n");
+ continue;
+ }
+
+ if (ret) { /* Other error. */
+ printf("W1_EEPROM probe failed, error %d\n", ret);
+ continue;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
new file mode 100644
index 0000000000..d6e045739d
--- /dev/null
+++ b/drivers/w1/Kconfig
@@ -0,0 +1,25 @@
+#
+# W1 subsystem configuration
+#
+
+menu "1-Wire support"
+
+config W1
+ bool "Enable 1-wire controllers support"
+ default no
+ depends on DM
+ help
+ Support for the Dallas 1-Wire bus.
+
+if W1
+
+config W1_GPIO
+ bool "Enable 1-wire GPIO bitbanging"
+ default no
+ depends on DM_GPIO
+ help
+ Emulate a 1-wire bus using a GPIO.
+
+endif
+
+endmenu
diff --git a/drivers/w1/Makefile b/drivers/w1/Makefile
new file mode 100644
index 0000000000..7fd8697f84
--- /dev/null
+++ b/drivers/w1/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_W1) += w1-uclass.o
+
+obj-$(CONFIG_W1_GPIO) += w1-gpio.o
diff --git a/drivers/w1/w1-gpio.c b/drivers/w1/w1-gpio.c
new file mode 100644
index 0000000000..5e5d6b3f6c
--- /dev/null
+++ b/drivers/w1/w1-gpio.c
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * Copyright (c) 2015 Free Electrons
+ * Copyright (c) 2015 NextThing Co
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <w1.h>
+
+#include <asm/gpio.h>
+
+#define W1_TIMING_A 6
+#define W1_TIMING_B 64
+#define W1_TIMING_C 60
+#define W1_TIMING_D 10
+#define W1_TIMING_E 9
+#define W1_TIMING_F 55
+#define W1_TIMING_G 0
+#define W1_TIMING_H 480
+#define W1_TIMING_I 70
+#define W1_TIMING_J 410
+
+struct w1_gpio_pdata {
+ struct gpio_desc gpio;
+ u64 search_id;
+};
+
+static bool w1_gpio_read_bit(struct udevice *dev)
+{
+ struct w1_gpio_pdata *pdata = dev_get_platdata(dev);
+ int val;
+
+ dm_gpio_set_dir_flags(&pdata->gpio, GPIOD_IS_OUT);
+ udelay(W1_TIMING_A);
+
+ dm_gpio_set_dir_flags(&pdata->gpio, GPIOD_IS_IN);
+ udelay(W1_TIMING_E);
+
+ val = dm_gpio_get_value(&pdata->gpio);
+ if (val < 0)
+ debug("error in retrieving GPIO value");
+ udelay(W1_TIMING_F);
+
+ return val;
+}
+
+static u8 w1_gpio_read_byte(struct udevice *dev)
+{
+ int i;
+ u8 ret = 0;
+
+ for (i = 0; i < 8; ++i)
+ ret |= (w1_gpio_read_bit(dev) ? 1 : 0) << i;
+
+ return ret;
+}
+
+static void w1_gpio_write_bit(struct udevice *dev, bool bit)
+{
+ struct w1_gpio_pdata *pdata = dev_get_platdata(dev);
+
+ dm_gpio_set_dir_flags(&pdata->gpio, GPIOD_IS_OUT);
+
+ bit ? udelay(W1_TIMING_A) : udelay(W1_TIMING_C);
+
+ dm_gpio_set_value(&pdata->gpio, 1);
+
+ bit ? udelay(W1_TIMING_B) : udelay(W1_TIMING_D);
+}
+
+static void w1_gpio_write_byte(struct udevice *dev, u8 byte)
+{
+ int i;
+
+ for (i = 0; i < 8; ++i)
+ w1_gpio_write_bit(dev, (byte >> i) & 0x1);
+}
+
+static bool w1_gpio_reset(struct udevice *dev)
+{
+ struct w1_gpio_pdata *pdata = dev_get_platdata(dev);
+ int val;
+
+ /* initiate the reset pulse. first we must pull the bus to low */
+ dm_gpio_set_dir_flags(&pdata->gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ udelay(W1_TIMING_G);
+
+ dm_gpio_set_value(&pdata->gpio, 0);
+ /* wait for the specified time with the bus kept low */
+ udelay(W1_TIMING_H);
+
+ /* now we must read the presence pulse */
+ dm_gpio_set_dir_flags(&pdata->gpio, GPIOD_IS_IN);
+ udelay(W1_TIMING_I);
+
+ val = dm_gpio_get_value(&pdata->gpio);
+ if (val < 0)
+ debug("error in retrieving GPIO value");
+
+ /* if nobody pulled the bus down , it means nobody is on the bus */
+ if (val != 0)
+ return 1;
+ /* we have the bus pulled down, let's wait for the specified presence time */
+ udelay(W1_TIMING_J);
+
+ /* read again, the other end should leave the bus free */
+ val = dm_gpio_get_value(&pdata->gpio);
+ if (val < 0)
+ debug("error in retrieving GPIO value");
+
+ /* bus is not going up again, so we have an error */
+ if (val != 1)
+ return 1;
+
+ /* all good, presence detected */
+ return 0;
+}
+
+static u8 w1_gpio_triplet(struct udevice *dev, bool bdir)
+{
+ u8 id_bit = w1_gpio_read_bit(dev);
+ u8 comp_bit = w1_gpio_read_bit(dev);
+ u8 retval;
+
+ if (id_bit && comp_bit)
+ return 0x03; /* error */
+
+ if (!id_bit && !comp_bit) {
+ /* Both bits are valid, take the direction given */
+ retval = bdir ? 0x04 : 0;
+ } else {
+ /* Only one bit is valid, take that direction */
+ bdir = id_bit;
+ retval = id_bit ? 0x05 : 0x02;
+ }
+
+ w1_gpio_write_bit(dev, bdir);
+ return retval;
+}
+
+static const struct w1_ops w1_gpio_ops = {
+ .read_byte = w1_gpio_read_byte,
+ .reset = w1_gpio_reset,
+ .triplet = w1_gpio_triplet,
+ .write_byte = w1_gpio_write_byte,
+};
+
+static int w1_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+ struct w1_gpio_pdata *pdata = dev_get_platdata(dev);
+ int ret;
+
+ ret = gpio_request_by_name(dev, "gpios", 0, &pdata->gpio, 0);
+ if (ret < 0)
+ printf("Error claiming GPIO %d\n", ret);
+
+ return ret;
+};
+
+static const struct udevice_id w1_gpio_id[] = {
+ { "w1-gpio", 0 },
+ { },
+};
+
+U_BOOT_DRIVER(w1_gpio_drv) = {
+ .id = UCLASS_W1,
+ .name = "w1_gpio_drv",
+ .of_match = w1_gpio_id,
+ .ofdata_to_platdata = w1_gpio_ofdata_to_platdata,
+ .ops = &w1_gpio_ops,
+ .platdata_auto_alloc_size = sizeof(struct w1_gpio_pdata),
+};
diff --git a/drivers/w1/w1-uclass.c b/drivers/w1/w1-uclass.c
new file mode 100644
index 0000000000..aecf7fec77
--- /dev/null
+++ b/drivers/w1/w1-uclass.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Copyright (c) 2015 Free Electrons
+ * Copyright (c) 2015 NextThing Co.
+ * Copyright (c) 2018 Microchip Technology, Inc.
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ * Eugen Hristev <eugen.hristev@microchip.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <w1.h>
+#include <w1-eeprom.h>
+
+#include <dm/device-internal.h>
+
+#define W1_MATCH_ROM 0x55
+#define W1_SKIP_ROM 0xcc
+#define W1_SEARCH 0xf0
+
+struct w1_bus {
+ u64 search_id;
+};
+
+static int w1_enumerate(struct udevice *bus)
+{
+ const struct w1_ops *ops = device_get_ops(bus);
+ struct w1_bus *w1 = dev_get_uclass_priv(bus);
+ u64 last_rn, rn = w1->search_id, tmp64;
+ bool last_device = false;
+ int search_bit, desc_bit = 64;
+ int last_zero = -1;
+ u8 triplet_ret = 0;
+ int i;
+
+ if (!ops->reset || !ops->write_byte || !ops->triplet)
+ return -ENOSYS;
+
+ while (!last_device) {
+ last_rn = rn;
+ rn = 0;
+
+ /*
+ * Reset bus and all 1-wire device state machines
+ * so they can respond to our requests.
+ *
+ * Return 0 - device(s) present, 1 - no devices present.
+ */
+ if (ops->reset(bus)) {
+ debug("%s: No devices present on the wire.\n",
+ __func__);
+ break;
+ }
+
+ /* Start the search */
+ ops->write_byte(bus, W1_SEARCH);
+ for (i = 0; i < 64; ++i) {
+ /* Determine the direction/search bit */
+ if (i == desc_bit)
+ /* took the 0 path last time, so take the 1 path */
+ search_bit = 1;
+ else if (i > desc_bit)
+ /* take the 0 path on the next branch */
+ search_bit = 0;
+ else
+ search_bit = ((last_rn >> i) & 0x1);
+
+ /* Read two bits and write one bit */
+ triplet_ret = ops->triplet(bus, search_bit);
+
+ /* quit if no device responded */
+ if ((triplet_ret & 0x03) == 0x03)
+ break;
+
+ /* If both directions were valid, and we took the 0 path... */
+ if (triplet_ret == 0)
+ last_zero = i;
+
+ /* extract the direction taken & update the device number */
+ tmp64 = (triplet_ret >> 2);
+ rn |= (tmp64 << i);
+ }
+
+ /* last device or error, aborting here */
+ if ((triplet_ret & 0x03) == 0x03)
+ last_device = true;
+
+ if ((triplet_ret & 0x03) != 0x03) {
+ if (desc_bit == last_zero || last_zero < 0) {
+ last_device = 1;
+ w1->search_id = 0;
+ } else {
+ w1->search_id = rn;
+ }
+ desc_bit = last_zero;
+
+ debug("%s: Detected new device 0x%llx (family 0x%x)\n",
+ bus->name, rn, (u8)(rn & 0xff));
+
+ /* attempt to register as w1-eeprom device */
+ w1_eeprom_register_new_device(rn);
+ }
+ }
+
+ return 0;
+}
+
+int w1_get_bus(int busnum, struct udevice **busp)
+{
+ int ret, i = 0;
+
+ struct udevice *dev;
+
+ for (ret = uclass_first_device(UCLASS_W1, &dev);
+ !ret;
+ uclass_next_device(&dev), i++) {
+ if (ret) {
+ debug("Cannot find w1 bus %d\n", busnum);
+ return ret;
+ }
+ if (i == busnum) {
+ *busp = dev;
+ return 0;
+ }
+ }
+ return ret;
+}
+
+u8 w1_get_device_family(struct udevice *dev)
+{
+ struct w1_device *w1 = dev_get_parent_platdata(dev);
+
+ return w1->id & 0xff;
+}
+
+int w1_reset_select(struct udevice *dev)
+{
+ struct w1_device *w1 = dev_get_parent_platdata(dev);
+ struct udevice *bus = dev_get_parent(dev);
+ const struct w1_ops *ops = device_get_ops(bus);
+ int i;
+
+ if (!ops->reset || !ops->write_byte)
+ return -ENOSYS;
+
+ ops->reset(bus);
+
+ ops->write_byte(bus, W1_MATCH_ROM);
+
+ for (i = 0; i < sizeof(w1->id); i++)
+ ops->write_byte(bus, (w1->id >> (i * 8)) & 0xff);
+
+ return 0;
+}
+
+int w1_read_byte(struct udevice *dev)
+{
+ struct udevice *bus = dev_get_parent(dev);
+ const struct w1_ops *ops = device_get_ops(bus);
+
+ if (!ops->read_byte)
+ return -ENOSYS;
+
+ return ops->read_byte(bus);
+}
+
+int w1_read_buf(struct udevice *dev, u8 *buf, unsigned int count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ ret = w1_read_byte(dev);
+ if (ret < 0)
+ return ret;
+
+ buf[i] = ret & 0xff;
+ }
+
+ return 0;
+}
+
+int w1_write_byte(struct udevice *dev, u8 byte)
+{
+ struct udevice *bus = dev_get_parent(dev);
+ const struct w1_ops *ops = device_get_ops(bus);
+
+ if (!ops->write_byte)
+ return -ENOSYS;
+
+ ops->write_byte(bus, byte);
+
+ return 0;
+}
+
+static int w1_post_probe(struct udevice *bus)
+{
+ w1_enumerate(bus);
+
+ return 0;
+}
+
+int w1_init(void)
+{
+ struct udevice *bus;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_W1, &uc);
+ if (ret)
+ return ret;
+
+ uclass_foreach_dev(bus, uc) {
+ ret = device_probe(bus);
+ if (ret == -ENODEV) { /* No such device. */
+ printf("W1 controller not available.\n");
+ continue;
+ }
+
+ if (ret) { /* Other error. */
+ printf("W1 controller probe failed.\n");
+ continue;
+ }
+ }
+ return 0;
+}
+
+UCLASS_DRIVER(w1) = {
+ .name = "w1",
+ .id = UCLASS_W1,
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+ .per_device_auto_alloc_size = sizeof(struct w1_bus),
+ .post_probe = w1_post_probe,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ .post_bind = dm_scan_fdt_dev,
+#endif
+ .per_child_platdata_auto_alloc_size = sizeof(struct w1_device),
+};