diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c
index 711470f36477d905e45cef93a69aa64343bbb001..612c9103e37e7ab964e32c11faab5483151a83ad 100644
--- a/arch/x86/cpu/ivybridge/early_me.c
+++ b/arch/x86/cpu/ivybridge/early_me.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
@@ -25,33 +26,36 @@ static const char *const me_ack_values[] = {
 	[ME_HFS_ACK_CONTINUE]	= "Continue to boot"
 };
 
-static inline void pci_read_dword_ptr(void *ptr, int offset)
+static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr,
+				      int offset)
 {
 	u32 dword;
 
-	dword = x86_pci_read_config32(PCH_ME_DEV, offset);
+	dm_pci_read_config32(me_dev, offset, &dword);
 	memcpy(ptr, &dword, sizeof(dword));
 }
 
-static inline void pci_write_dword_ptr(void *ptr, int offset)
+static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr,
+				       int offset)
 {
 	u32 dword = 0;
+
 	memcpy(&dword, ptr, sizeof(dword));
-	x86_pci_write_config32(PCH_ME_DEV, offset, dword);
+	dm_pci_write_config32(me_dev, offset, dword);
 }
 
-void intel_early_me_status(void)
+void intel_early_me_status(struct udevice *me_dev)
 {
 	struct me_hfs hfs;
 	struct me_gmes gmes;
 
-	pci_read_dword_ptr(&hfs, PCI_ME_HFS);
-	pci_read_dword_ptr(&gmes, PCI_ME_GMES);
+	pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
+	pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES);
 
 	intel_me_status(&hfs, &gmes);
 }
 
-int intel_early_me_init(void)
+int intel_early_me_init(struct udevice *me_dev)
 {
 	int count;
 	struct me_uma uma;
@@ -61,7 +65,7 @@ int intel_early_me_init(void)
 
 	/* Wait for ME UMA SIZE VALID bit to be set */
 	for (count = ME_RETRY; count > 0; --count) {
-		pci_read_dword_ptr(&uma, PCI_ME_UMA);
+		pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA);
 		if (uma.valid)
 			break;
 		udelay(ME_DELAY);
@@ -72,7 +76,7 @@ int intel_early_me_init(void)
 	}
 
 	/* Check for valid firmware */
-	pci_read_dword_ptr(&hfs, PCI_ME_HFS);
+	pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
 	if (hfs.fpt_bad) {
 		printf("WARNING: ME has bad firmware\n");
 		return -EBADF;
@@ -83,11 +87,11 @@ int intel_early_me_init(void)
 	return 0;
 }
 
-int intel_early_me_uma_size(void)
+int intel_early_me_uma_size(struct udevice *me_dev)
 {
 	struct me_uma uma;
 
-	pci_read_dword_ptr(&uma, PCI_ME_UMA);
+	pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA);
 	if (uma.valid) {
 		debug("ME: Requested %uMB UMA\n", uma.size);
 		return uma.size;
@@ -97,11 +101,11 @@ int intel_early_me_uma_size(void)
 	return -EINVAL;
 }
 
-static inline void set_global_reset(int enable)
+static inline void set_global_reset(struct udevice *dev, int enable)
 {
 	u32 etr3;
 
-	etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3);
+	dm_pci_read_config32(dev, ETR3, &etr3);
 
 	/* Clear CF9 Without Resume Well Reset Enable */
 	etr3 &= ~ETR3_CWORWRE;
@@ -112,10 +116,11 @@ static inline void set_global_reset(int enable)
 	else
 		etr3 &= ~ETR3_CF9GR;
 
-	x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
+	dm_pci_write_config32(dev, ETR3, etr3);
 }
 
-int intel_early_me_init_done(u8 status)
+int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev,
+			     uint status)
 {
 	int count;
 	u32 mebase_l, mebase_h;
@@ -126,8 +131,8 @@ int intel_early_me_init_done(u8 status)
 	};
 
 	/* MEBASE from MESEG_BASE[35:20] */
-	mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
-	mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
+	dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L, &mebase_l);
+	dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H, &mebase_h);
 	mebase_h &= 0xf;
 	did.uma_base = (mebase_l >> 20) | (mebase_h << 12);
 
@@ -135,25 +140,25 @@ int intel_early_me_init_done(u8 status)
 	debug("ME: Sending Init Done with status: %d, UMA base: 0x%04x\n",
 	      status, did.uma_base);
 
-	pci_write_dword_ptr(&did, PCI_ME_H_GS);
+	pci_write_dword_ptr(me_dev, &did, PCI_ME_H_GS);
 
 	/* Must wait for ME acknowledgement */
 	for (count = ME_RETRY; count > 0; --count) {
-		pci_read_dword_ptr(&hfs, PCI_ME_HFS);
+		pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
 		if (hfs.bios_msg_ack)
 			break;
 		udelay(ME_DELAY);
 	}
 	if (!count) {
 		printf("ERROR: ME failed to respond\n");
-		return -1;
+		return -ETIMEDOUT;
 	}
 
 	/* Return the requested BIOS action */
 	debug("ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]);
 
 	/* Check status after acknowledgement */
-	intel_early_me_status();
+	intel_early_me_status(me_dev);
 
 	switch (hfs.ack_data) {
 	case ME_HFS_ACK_CONTINUE:
@@ -161,17 +166,17 @@ int intel_early_me_init_done(u8 status)
 		return 0;
 	case ME_HFS_ACK_RESET:
 		/* Non-power cycle reset */
-		set_global_reset(0);
+		set_global_reset(dev, 0);
 		reset_cpu(0);
 		break;
 	case ME_HFS_ACK_PWR_CYCLE:
 		/* Power cycle reset */
-		set_global_reset(0);
+		set_global_reset(dev, 0);
 		x86_full_reset();
 		break;
 	case ME_HFS_ACK_GBL_RESET:
 		/* Global reset */
-		set_global_reset(1);
+		set_global_reset(dev, 1);
 		x86_full_reset();
 		break;
 	case ME_HFS_ACK_S3:
@@ -180,5 +185,16 @@ int intel_early_me_init_done(u8 status)
 		break;
 	}
 
-	return -1;
+	return -EINVAL;
 }
+
+static const struct udevice_id ivybridge_syscon_ids[] = {
+	{ .compatible = "intel,me", },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_intel_me) = {
+	.name = "intel_me_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = ivybridge_syscon_ids,
+};
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 6105cc02595319bd6325d4a922dfedf79c5cc412..696351b7bf7186d6e9d38fbe7fec65ca62f005a7 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -286,7 +286,8 @@ static int recovery_mode_enabled(void)
  * @dev: Northbridge device
  * @pei_data: configuration data for UEFI PEI reference code
  */
-int sdram_initialise(struct udevice *dev, struct pei_data *pei_data)
+int sdram_initialise(struct udevice *dev, struct udevice *me_dev,
+		     struct pei_data *pei_data)
 {
 	unsigned version;
 	const char *data;
@@ -296,10 +297,10 @@ int sdram_initialise(struct udevice *dev, struct pei_data *pei_data)
 	report_platform_info();
 
 	/* Wait for ME to be ready */
-	ret = intel_early_me_init();
+	ret = intel_early_me_init(me_dev);
 	if (ret)
 		return ret;
-	ret = intel_early_me_uma_size();
+	ret = intel_early_me_uma_size(me_dev);
 	if (ret < 0)
 		return ret;
 
@@ -378,9 +379,9 @@ int sdram_initialise(struct udevice *dev, struct pei_data *pei_data)
 	dm_pci_read_config16(dev, PCI_DEVICE_ID, &done);
 	done &= BASE_REV_MASK;
 	if (BASE_REV_SNB == done)
-		intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
+		intel_early_me_init_done(dev, me_dev, ME_INIT_STATUS_SUCCESS);
 	else
-		intel_early_me_status();
+		intel_early_me_status(me_dev);
 
 	post_system_agent_init(pei_data);
 	report_memory_config();
@@ -730,7 +731,7 @@ int dram_init(void)
 			{ 0, 4, 0x0000 }, /* P13= Empty */
 		},
 	};
-	struct udevice *dev;
+	struct udevice *dev, *me_dev;
 	int ret;
 
 	ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
@@ -738,12 +739,17 @@ int dram_init(void)
 		return ret;
 	if (!dev)
 		return -ENODEV;
+	ret = uclass_first_device(UCLASS_SYSCON, &me_dev);
+	if (ret)
+		return ret;
+	if (!me_dev)
+		return -ENODEV;
 	debug("Boot mode %d\n", gd->arch.pei_boot_mode);
 	debug("mrc_input %p\n", pei_data.mrc_input);
 	pei_data.boot_mode = gd->arch.pei_boot_mode;
 	ret = copy_spd(&pei_data);
 	if (!ret)
-		ret = sdram_initialise(dev, &pei_data);
+		ret = sdram_initialise(dev, me_dev, &pei_data);
 	if (ret)
 		return ret;
 
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index 54f20431728ee2b21453a439278bc424ee6ea5d4..329eae8658fb58919fd0aa8e9648ffaf56d914d9 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -220,6 +220,12 @@
 			intel,pch-backlight = <0x04000000>;
 		};
 
+		me@16,0 {
+			reg = <0x0000b000 0 0 0 0>;
+			compatible = "intel,me";
+			u-boot,dm-pre-reloc;
+		};
+
 		pch@1f,0 {
 			reg = <0x0000f800 0 0 0 0>;
 			compatible = "intel,bd82x6x", "intel,pch9";
diff --git a/arch/x86/include/asm/arch-ivybridge/me.h b/arch/x86/include/asm/arch-ivybridge/me.h
index 3a0809d6ece7c6438a5929f71e1f66de00883828..eb1b73f92e7469afc91894bd792304e8ebdd15bb 100644
--- a/arch/x86/include/asm/arch-ivybridge/me.h
+++ b/arch/x86/include/asm/arch-ivybridge/me.h
@@ -345,12 +345,47 @@ struct __packed me_fwcaps {
 	u8 reserved[3];
 };
 
-/* Defined in me_status.c for both romstage and ramstage */
+/**
+ * intel_me_status() - Check Intel Management Engine status
+ *
+ * struct hfs:	Firmware status
+ * struct gmes:	Management engine status
+ */
 void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes);
 
-void intel_early_me_status(void);
-int intel_early_me_init(void);
-int intel_early_me_uma_size(void);
-int intel_early_me_init_done(u8 status);
+/**
+ * intel_early_me_status() - Check early Management Engine Status
+ *
+ * @me_dev:	Management engine PCI device
+ */
+void intel_early_me_status(struct udevice *me_dev);
+
+/**
+ * intel_early_me_init() - Early Intel Management Engine init
+ *
+ * @me_dev:	Management engine PCI device
+ * @return 0 if OK, -ve on error
+ */
+int intel_early_me_init(struct udevice *me_dev);
+
+/**
+ * intel_early_me_uma_size() - Get UMA size from the Intel Management Engine
+ *
+ * @me_dev:	Management engine PCI device
+ * @return UMA size if OK, -EINVAL on error
+ */
+int intel_early_me_uma_size(struct udevice *me_dev);
+
+/**
+ * intel_early_me_init_done() - Complete Intel Management Engine init
+ *
+ * @dev:	Northbridge device
+ * @me_dev:	Management engine PCI device
+ * @status:	Status result (ME_INIT_...)
+ * @return 0 to continue to boot, -EINVAL on unknown result data, -ETIMEDOUT
+ * if ME did not respond
+ */
+int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev,
+			     uint status);
 
 #endif