diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c
index aa877c65fd389fc68853e39150a8907d08b8fecd..7c59c887f13d0d1ff1c209d151adc7f29f21c7d3 100644
--- a/drivers/misc/fsl_law.c
+++ b/drivers/misc/fsl_law.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Freescale Semiconductor, Inc.
+ * Copyright 2008-2009 Freescale Semiconductor, Inc.
  *
  * (C) Copyright 2000
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -29,7 +29,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define LAWAR_EN	0x80000000
 /* number of LAWs in the hw implementation */
 #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
     defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555)
@@ -46,6 +45,56 @@ DECLARE_GLOBAL_DATA_PTR;
 #error FSL_HW_NUM_LAWS not defined for this platform
 #endif
 
+#ifdef CONFIG_FSL_CORENET
+void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
+{
+	volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR);
+
+	gd->used_laws |= (1 << idx);
+
+	out_be32(&ccm->law[idx].lawar, 0);
+	out_be32(&ccm->law[idx].lawbarh, ((u64)addr >> 32));
+	out_be32(&ccm->law[idx].lawbarl, addr & 0xffffffff);
+	out_be32(&ccm->law[idx].lawar, LAW_EN | ((u32)id << 20) | (u32)sz);
+
+	/* Read back so that we sync the writes */
+	in_be32(&ccm->law[idx].lawar);
+}
+
+void disable_law(u8 idx)
+{
+	volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR);
+
+	gd->used_laws &= ~(1 << idx);
+
+	out_be32(&ccm->law[idx].lawar, 0);
+	out_be32(&ccm->law[idx].lawbarh, 0);
+	out_be32(&ccm->law[idx].lawbarl, 0);
+
+	/* Read back so that we sync the writes */
+	in_be32(&ccm->law[idx].lawar);
+
+	return;
+}
+
+static int get_law_entry(u8 i, struct law_entry *e)
+{
+	volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR);
+	u32 lawar;
+
+	lawar = in_be32(&ccm->law[i].lawar);
+
+	if (!(lawar & LAW_EN))
+		return 0;
+
+	e->addr = ((u64)in_be32(&ccm->law[i].lawbarh) << 32) |
+			in_be32(&ccm->law[i].lawbarl);
+	e->size = lawar & 0x3f;
+	e->trgt_id = (lawar >> 20) & 0xff;
+
+	return 1;
+}
+#else
 void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
 {
 	volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08);
@@ -56,12 +105,49 @@ void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
 
 	out_be32(lawar, 0);
 	out_be32(lawbar, addr >> 12);
-	out_be32(lawar, LAWAR_EN | ((u32)id << 20) | (u32)sz);
+	out_be32(lawar, LAW_EN | ((u32)id << 20) | (u32)sz);
 
 	/* Read back so that we sync the writes */
 	in_be32(lawar);
 }
 
+void disable_law(u8 idx)
+{
+	volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08);
+	volatile u32 *lawbar = base + 8 * idx;
+	volatile u32 *lawar = base + 8 * idx + 2;
+
+	gd->used_laws &= ~(1 << idx);
+
+	out_be32(lawar, 0);
+	out_be32(lawbar, 0);
+
+	/* Read back so that we sync the writes */
+	in_be32(lawar);
+
+	return;
+}
+
+static int get_law_entry(u8 i, struct law_entry *e)
+{
+	volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08);
+	volatile u32 *lawbar = base + 8 * i;
+	volatile u32 *lawar = base + 8 * i + 2;
+	u32 temp;
+
+	temp = in_be32(lawar);
+
+	if (!(temp & LAW_EN))
+		return 0;
+
+	e->addr = (u64)in_be32(lawbar) << 12;
+	e->size = temp & 0x3f;
+	e->trgt_id = (temp >> 20) & 0xff;
+
+	return 1;
+}
+#endif
+
 int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
 {
 	u32 idx = ffz(gd->used_laws);
@@ -94,18 +180,30 @@ int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
 	return idx;
 }
 
-void disable_law(u8 idx)
+struct law_entry find_law(phys_addr_t addr)
 {
-	volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08);
-	volatile u32 *lawbar = base + 8 * idx;
-	volatile u32 *lawar = base + 8 * idx + 2;
+	struct law_entry entry;
+	int i;
 
-	gd->used_laws &= ~(1 << idx);
+	entry.index = -1;
+	entry.addr = 0;
+	entry.size = 0;
+	entry.trgt_id = 0;
 
-	out_be32(lawar, 0);
-	out_be32(lawbar, 0);
+	for (i = 0; i < FSL_HW_NUM_LAWS; i++) {
+		u64 upper;
 
-	return;
+		if (!get_law_entry(i, &entry))
+			continue;
+
+		upper = entry.addr + (2ull << entry.size);
+		if ((addr >= entry.addr) && (addr < upper)) {
+			entry.index = i;
+			break;
+		}
+	}
+
+	return entry;
 }
 
 void print_laws(void)
@@ -173,7 +271,13 @@ void init_laws(void)
 {
 	int i;
 
+#if FSL_HW_NUM_LAWS < 32
 	gd->used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1);
+#elif FSL_HW_NUM_LAWS == 32
+	gd->used_laws = 0;
+#else
+#error FSL_HW_NUM_LAWS can not be greater than 32 w/o code changes
+#endif
 
 	for (i = 0; i < num_law_entries; i++) {
 		if (law_table[i].index == -1)
diff --git a/include/asm-ppc/fsl_law.h b/include/asm-ppc/fsl_law.h
index e06a1a6e0e1818663594472b395c2b74385f5898..31bb7545b5343eadb8700f95f83f0092b9fccec8 100644
--- a/include/asm-ppc/fsl_law.h
+++ b/include/asm-ppc/fsl_law.h
@@ -1,8 +1,18 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
 #ifndef _FSL_LAW_H_
 #define _FSL_LAW_H_
 
 #include <asm/io.h>
 
+#define LAW_EN	0x80000000
+
 #define SET_LAW_ENTRY(idx, a, sz, trgt) \
 	{ .index = idx, .addr = a, .size = sz, .trgt_id = trgt }
 
@@ -36,6 +46,25 @@ enum law_size {
 	LAW_SIZE_32G,
 };
 
+#ifdef CONFIG_FSL_CORENET
+enum law_trgt_if {
+	LAW_TRGT_IF_PCIE_1 = 0x00,
+	LAW_TRGT_IF_PCIE_2 = 0x01,
+	LAW_TRGT_IF_PCIE_3 = 0x02,
+	LAW_TRGT_IF_RIO_1 = 0x08,
+	LAW_TRGT_IF_RIO_2 = 0x09,
+
+	LAW_TRGT_IF_DDR_1 = 0x10,
+	LAW_TRGT_IF_DDR_2 = 0x11,	/* 2nd controller */
+	LAW_TRGT_IF_DDR_INTRLV = 0x14,
+
+	LAW_TRGT_IF_BMAN = 0x18,
+	LAW_TRGT_IF_DCSR = 0x1d,
+	LAW_TRGT_IF_LBC = 0x1f,
+	LAW_TRGT_IF_QMAN = 0x3c,
+};
+#define LAW_TRGT_IF_DDR		LAW_TRGT_IF_DDR_1
+#else
 enum law_trgt_if {
 	LAW_TRGT_IF_PCI = 0x00,
 	LAW_TRGT_IF_PCI_2 = 0x01,
@@ -64,6 +93,7 @@ enum law_trgt_if {
 #if defined(CONFIG_MPC8572) || defined(CONFIG_P2020)
 #define LAW_TRGT_IF_PCIE_3	LAW_TRGT_IF_PCI
 #endif
+#endif /* CONFIG_FSL_CORENET */
 
 struct law_entry {
 	int index;
@@ -76,6 +106,7 @@ extern void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if
 extern int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id);
 extern int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id);
 extern int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id);
+extern struct law_entry find_law(phys_addr_t addr);
 extern void disable_law(u8 idx);
 extern void init_laws(void);
 extern void print_laws(void);