diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c
index c41f11d60c75a4ed1687a5dca0334ac728262680..a3079dbca367e2b7cb60b5c25a5c50ac8f22bc14 100644
--- a/board/davedenx/qong/qong.c
+++ b/board/davedenx/qong/qong.c
@@ -28,11 +28,12 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
 #include <nand.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <asm/gpio.h>
 #include "qong_fpga.h"
 #include <watchdog.h>
+#include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -172,10 +173,15 @@ int board_late_init(void)
 {
 	u32 val;
 	struct pmic *p;
+	int ret;
 
-	pmic_init();
-	p = get_pmic();
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return ret;
 
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return -ENODEV;
 	/* Enable RTC battery */
 	pmic_reg_read(p, REG_POWER_CTL0, &val);
 	pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN);
diff --git a/board/freescale/mx31pdk/mx31pdk.c b/board/freescale/mx31pdk/mx31pdk.c
index 9f8bc53e711c02fd40ed9f2b58b35417a24a277a..bc60632aa0b34662a10243f30c9f6a42f856bbb0 100644
--- a/board/freescale/mx31pdk/mx31pdk.c
+++ b/board/freescale/mx31pdk/mx31pdk.c
@@ -30,8 +30,9 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/sys_proto.h>
 #include <watchdog.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
+#include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -83,10 +84,15 @@ int board_late_init(void)
 {
 	u32 val;
 	struct pmic *p;
+	int ret;
 
-	pmic_init();
-	p = get_pmic();
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return ret;
 
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return -ENODEV;
 	/* Enable RTC battery */
 	pmic_reg_read(p, REG_POWER_CTL0, &val);
 	pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN);
diff --git a/board/freescale/mx35pdk/mx35pdk.c b/board/freescale/mx35pdk/mx35pdk.c
index a12531fb892cf5dc7b0fb5e234fec6361f60a3b5..c835b0edeb573aba1d5cffb39831157dce4bea5e 100644
--- a/board/freescale/mx35pdk/mx35pdk.c
+++ b/board/freescale/mx35pdk/mx35pdk.c
@@ -31,7 +31,7 @@
 #include <asm/arch/mx35_pins.h>
 #include <asm/arch/iomux.h>
 #include <i2c.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
@@ -207,7 +207,9 @@ int board_init(void)
 static inline int pmic_detect(void)
 {
 	unsigned int id;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("FSL_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	pmic_reg_read(p, REG_IDENTIFICATION, &id);
 
@@ -231,10 +233,14 @@ int board_late_init(void)
 	u8 val;
 	u32 pmic_val;
 	struct pmic *p;
+	int ret;
+
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return ret;
 
-	pmic_init();
 	if (pmic_detect()) {
-		p = get_pmic();
+		p = pmic_get("FSL_PMIC");
 		mxc_request_iomux(MX35_PIN_WATCHDOG_RST, MUX_CONFIG_SION |
 					MUX_CONFIG_ALT1);
 
diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c
index 421d8c224444e4ba935f71e6cf9fde39307e385a..5504636ddf411505664a623bcc1f987b96d1f2b2 100644
--- a/board/freescale/mx51evk/mx51evk.c
+++ b/board/freescale/mx51evk/mx51evk.c
@@ -33,7 +33,7 @@
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
 #include <usb/ehci-fsl.h>
@@ -252,9 +252,15 @@ static void power_init(void)
 	unsigned int val;
 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 	struct pmic *p;
+	int ret;
+
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return;
 
-	pmic_init();
-	p = get_pmic();
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return;
 
 	/* Write needed to Power Gate 2 register */
 	pmic_reg_read(p, REG_POWER_MISC, &val);
diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c
index bb4621d62ece80a139b2138a991360867540a8d5..12735014767b9d59908d9f5bc7fab99d0436867e 100644
--- a/board/freescale/mx53evk/mx53evk.c
+++ b/board/freescale/mx53evk/mx53evk.c
@@ -34,7 +34,7 @@
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <asm/gpio.h>
 #include <mc13892.h>
@@ -123,9 +123,15 @@ void power_init(void)
 {
 	unsigned int val;
 	struct pmic *p;
+	int ret;
+
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return;
 
-	pmic_init();
-	p = get_pmic();
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return;
 
 	/* Set VDDA to 1.25V */
 	pmic_reg_read(p, REG_SW_2, &val);
diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c
index a11e8831866cfa143bb18ba0f6aeac3fec71b8a1..f4a9b084208581ca72baa4edac08dc68074404e4 100644
--- a/board/freescale/mx53loco/mx53loco.c
+++ b/board/freescale/mx53loco/mx53loco.c
@@ -36,7 +36,7 @@
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <asm/gpio.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <dialog_pmic.h>
 #include <fsl_pmic.h>
 #include <linux/fb.h>
@@ -344,10 +344,16 @@ static int power_init(void)
 	unsigned int val;
 	int ret = -1;
 	struct pmic *p;
+	int retval;
 
 	if (!i2c_probe(CONFIG_SYS_DIALOG_PMIC_I2C_ADDR)) {
-		pmic_dialog_init();
-		p = get_pmic();
+		retval = pmic_dialog_init(I2C_PMIC);
+		if (retval)
+			return retval;
+
+		p = pmic_get("DIALOG_PMIC");
+		if (!p)
+			return -ENODEV;
 
 		/* Set VDDA to 1.25V */
 		val = DA9052_BUCKCORE_BCOREEN | DA_BUCKCORE_VBCORE_1_250V;
@@ -363,8 +369,13 @@ static int power_init(void)
 	}
 
 	if (!i2c_probe(CONFIG_SYS_FSL_PMIC_I2C_ADDR)) {
-		pmic_init();
-		p = get_pmic();
+		retval = pmic_init(I2C_PMIC);
+		if (retval)
+			return retval;
+
+		p = pmic_get("DIALOG_PMIC");
+		if (!p)
+			return -ENODEV;
 
 		/* Set VDDGP to 1.25V for 1GHz on SW1 */
 		pmic_reg_read(p, REG_SW_0, &val);
diff --git a/board/genesi/mx51_efikamx/efikamx.c b/board/genesi/mx51_efikamx/efikamx.c
index c2b2823ef9dab8fe146af8c5ada34b9fe08fa86a..69d41db530d0ce5b9a5244adfd64dacc798dc6c2 100644
--- a/board/genesi/mx51_efikamx/efikamx.c
+++ b/board/genesi/mx51_efikamx/efikamx.c
@@ -33,7 +33,7 @@
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
 
@@ -173,9 +173,15 @@ static void power_init(void)
 	unsigned int val;
 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 	struct pmic *p;
+	int ret;
+
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return;
 
-	pmic_init();
-	p = get_pmic();
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return;
 
 	/* Write needed to Power Gate 2 register */
 	pmic_reg_read(p, REG_POWER_MISC, &val);
diff --git a/board/hale/tt01/tt01.c b/board/hale/tt01/tt01.c
index 143fcefedf55e710c055d92d859eebc2ec225724..0c2cb795dd66448bb44e64fce3703609acaef16d 100644
--- a/board/hale/tt01/tt01.c
+++ b/board/hale/tt01/tt01.c
@@ -25,12 +25,13 @@
 #include <common.h>
 #include <netdev.h>
 #include <command.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13783.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
+#include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -195,14 +196,21 @@ int board_mmc_init(bd_t *bis)
 {
 	u32 val;
 	struct pmic *p;
+	int ret;
 
 	/*
 	* this is the first driver to use the pmic, so call
 	* pmic_init() here. board_late_init() is too late for
 	* the MMC driver.
 	*/
-	pmic_init();
-	p = get_pmic();
+
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return ret;
+
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	/* configure pins for SDHC1 only */
 	mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SD1_CLK, MUX_CTL_FUNC));
diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c
index e8fb1ea4130a740480cd685c0cb09d9c9d732d51..71ed618c6fd5d51d2855b93d7a260f256ad84fc5 100644
--- a/board/samsung/goni/goni.c
+++ b/board/samsung/goni/goni.c
@@ -25,10 +25,10 @@
 #include <common.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <usb/s3c_udc.h>
 #include <asm/arch/cpu.h>
-#include <max8998_pmic.h>
+#include <power/max8998_pmic.h>
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct s5pc110_gpio *s5pc110_gpio;
@@ -42,8 +42,9 @@ int board_init(void)
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
 #if defined(CONFIG_PMIC)
-	pmic_init();
+	pmic_init(I2C_5);
 #endif
+
 	return 0;
 }
 
@@ -108,7 +109,9 @@ static int s5pc1xx_phy_control(int on)
 {
 	int ret;
 	static int status;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("MAX8998_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	if (pmic_probe(p))
 		return -1;
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index e11a8922fca98983c9b4c4841f66a6a3786bf199..e0a98901f733029e5621813b4a13e3d343401c36 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -34,9 +34,9 @@
 #include <asm/arch/mipi_dsim.h>
 #include <asm/arch/watchdog.h>
 #include <asm/arch/power.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <usb/s3c_udc.h>
-#include <max8997_pmic.h>
+#include <power/max8997_pmic.h>
 #include <libtizen.h>
 
 #include "setup.h"
@@ -69,7 +69,7 @@ int board_init(void)
 	printf("HW Revision:\t0x%x\n", board_rev);
 
 #if defined(CONFIG_PMIC)
-	pmic_init();
+	pmic_init(I2C_5);
 #endif
 
 	return 0;
@@ -238,7 +238,9 @@ static int s5pc210_phy_control(int on)
 {
 	int ret = 0;
 	u32 val = 0;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("MAX8997_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	if (pmic_probe(p))
 		return -1;
@@ -413,7 +415,9 @@ static void lcd_reset(void)
 static int lcd_power(void)
 {
 	int ret = 0;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("MAX8997_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	if (pmic_probe(p))
 		return 0;
@@ -473,7 +477,9 @@ static struct mipi_dsim_lcd_device mipi_lcd_device = {
 static int mipi_power(void)
 {
 	int ret = 0;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("MAX8997_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	if (pmic_probe(p))
 		return 0;
diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c
index 90fff5cf5e181af64cfd56b53937d64daac916bd..c4950ddc2698432c1f995c042302bc0e83b486fc 100644
--- a/board/samsung/universal_c210/universal.c
+++ b/board/samsung/universal_c210/universal.c
@@ -27,10 +27,10 @@
 #include <asm/arch/adc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <usb/s3c_udc.h>
 #include <asm/arch/cpu.h>
-#include <max8998_pmic.h>
+#include <power/max8998_pmic.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -59,7 +59,7 @@ int board_init(void)
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
 #if defined(CONFIG_PMIC)
-	pmic_init();
+	pmic_init(I2C_5);
 #endif
 
 	check_hw_revision();
@@ -112,7 +112,9 @@ static unsigned short get_adc_value(int channel)
 static int adc_power_control(int on)
 {
 	int ret;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("MAX8998_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	if (pmic_probe(p))
 		return -1;
@@ -280,7 +282,9 @@ int board_mmc_init(bd_t *bis)
 static int s5pc210_phy_control(int on)
 {
 	int ret = 0;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("MAX8998_PMIC");
+	if (!p)
+		return -ENODEV;
 
 	if (pmic_probe(p))
 		return -1;
diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c
index abdd1aac2b5dd9bda98fb0a664506b4e6ed54d68..a471fec23dd791d2198495a4a3a5aff4afc3f57a 100644
--- a/board/ttcontrol/vision2/vision2.c
+++ b/board/ttcontrol/vision2/vision2.c
@@ -34,7 +34,7 @@
 #include <asm/arch/sys_proto.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_esdhc.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
@@ -306,9 +306,15 @@ static void power_init_mx51(void)
 {
 	unsigned int val;
 	struct pmic *p;
+	int ret;
+
+	ret = pmic_init(I2C_PMIC);
+	if (ret)
+		return;
 
-	pmic_init();
-	p = get_pmic();
+	p = pmic_get("FSL_PMIC");
+	if (!p)
+		return;
 
 	/* Write needed to Power Gate 2 register */
 	pmic_reg_read(p, REG_POWER_MISC, &val);
diff --git a/drivers/misc/pmic_core.c b/drivers/misc/pmic_core.c
index 5d62a56d346925c6cdd263648e81ac6e0bcbcd94..4066b15adcdbdeeefd6d6f26ca27f4d792cdaa88 100644
--- a/drivers/misc/pmic_core.c
+++ b/drivers/misc/pmic_core.c
@@ -27,18 +27,21 @@
  */
 
 #include <common.h>
+#include <malloc.h>
 #include <linux/types.h>
-#include <pmic.h>
+#include <linux/list.h>
+#include <power/pmic.h>
 
-static struct pmic pmic;
+static LIST_HEAD(pmic_list);
 
-int check_reg(u32 reg)
+int check_reg(struct pmic *p, u32 reg)
 {
-	if (reg >= pmic.number_of_regs) {
+	if (reg >= p->number_of_regs) {
 		printf("<reg num> = %d is invalid. Should be less than %d\n",
-		       reg, pmic.number_of_regs);
+		       reg, p->number_of_regs);
 		return -1;
 	}
+
 	return 0;
 }
 
@@ -65,11 +68,16 @@ static void pmic_show_info(struct pmic *p)
 	printf("PMIC: %s\n", p->name);
 }
 
-static void pmic_dump(struct pmic *p)
+static int pmic_dump(struct pmic *p)
 {
 	int i, ret;
 	u32 val;
 
+	if (!p) {
+		puts("Wrong PMIC name!\n");
+		return -1;
+	}
+
 	pmic_show_info(p);
 	for (i = 0; i < p->number_of_regs; i++) {
 		ret = pmic_reg_read(p, i, &val);
@@ -82,35 +90,84 @@ static void pmic_dump(struct pmic *p)
 		printf("%08x ", val);
 	}
 	puts("\n");
+	return 0;
 }
 
-struct pmic *get_pmic(void)
+struct pmic *pmic_alloc(void)
 {
-	return &pmic;
+	struct pmic *p;
+
+	p = calloc(sizeof(*p), 1);
+	if (!p) {
+		printf("%s: No available memory for allocation!\n", __func__);
+		return NULL;
+	}
+
+	list_add_tail(&p->list, &pmic_list);
+
+	debug("%s: new pmic struct: 0x%p\n", __func__, p);
+
+	return p;
+}
+
+struct pmic *pmic_get(const char *s)
+{
+	struct pmic *p;
+
+	list_for_each_entry(p, &pmic_list, list) {
+		if (strcmp(p->name, s) == 0) {
+			debug("%s: pmic %s -> 0x%p\n", __func__, p->name, p);
+			return p;
+		}
+	}
+
+	return NULL;
+}
+
+static void pmic_list_names(void)
+{
+	struct pmic *p;
+
+	puts("PMIC devices:\n");
+	list_for_each_entry(p, &pmic_list, list) {
+		printf("name: %s\n", p->name);
+	}
 }
 
 int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	u32 ret, reg, val;
+	struct pmic *p;
 	char *cmd;
 
-	struct pmic *p = &pmic;
-
 	/* at least two arguments please */
 	if (argc < 2)
-		return cmd_usage(cmdtp);
+		return CMD_RET_USAGE;
 
 	cmd = argv[1];
+
+	if (strcmp(cmd, "list") == 0) {
+		pmic_list_names();
+		return CMD_RET_SUCCESS;
+	}
+
 	if (strcmp(cmd, "dump") == 0) {
-		pmic_dump(p);
-		return 0;
+		p = pmic_get(argv[2]);
+		if (!p)
+			return CMD_RET_FAILURE;
+		if (pmic_dump(p))
+			return CMD_RET_FAILURE;
+		return CMD_RET_SUCCESS;
 	}
 
 	if (strcmp(cmd, "read") == 0) {
-		if (argc < 3)
-			return cmd_usage(cmdtp);
+		if (argc < 4)
+			return CMD_RET_USAGE;
 
-		reg = simple_strtoul(argv[2], NULL, 16);
+		reg = simple_strtoul(argv[3], NULL, 16);
+		p = pmic_get(argv[2]);
+		if (!p)
+			return CMD_RET_FAILURE;
 
 		ret = pmic_reg_read(p, reg, &val);
 
@@ -119,29 +176,32 @@ int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 		printf("\n0x%02x: 0x%08x\n", reg, val);
 
-		return 0;
+		return CMD_RET_SUCCESS;
 	}
 
 	if (strcmp(cmd, "write") == 0) {
-		if (argc < 4)
-			return cmd_usage(cmdtp);
-
-		reg = simple_strtoul(argv[2], NULL, 16);
-		val = simple_strtoul(argv[3], NULL, 16);
-
+		if (argc < 5)
+			return CMD_RET_USAGE;
+
+		reg = simple_strtoul(argv[3], NULL, 16);
+		val = simple_strtoul(argv[4], NULL, 16);
+		p = pmic_get(argv[2]);
+		if (!p)
+			return CMD_RET_FAILURE;
 		pmic_reg_write(p, reg, val);
 
-		return 0;
+		return CMD_RET_SUCCESS;
 	}
 
 	/* No subcommand found */
-	return 1;
+	return CMD_RET_SUCCESS;
 }
 
 U_BOOT_CMD(
 	pmic,	CONFIG_SYS_MAXARGS, 1, do_pmic,
 	"PMIC",
-	"dump - dump PMIC registers\n"
-	"pmic read <reg> - read register\n"
-	"pmic write <reg> <value> - write register"
+	"list - list available PMICs\n"
+	"pmic dump name - dump named PMIC registers\n"
+	"pmic name read <reg> - read register\n"
+	"pmic name write <reg> <value> - write register"
 );
diff --git a/drivers/misc/pmic_dialog.c b/drivers/misc/pmic_dialog.c
index e97af1d1d01a3020516f83fa7ef3b6ccee2ec9a2..d7ebd1583e8303495f4641e06d80cf4a83a91072 100644
--- a/drivers/misc/pmic_dialog.c
+++ b/drivers/misc/pmic_dialog.c
@@ -17,13 +17,19 @@
  */
 
 #include <common.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <dialog_pmic.h>
+#include <errno.h>
 
-int pmic_dialog_init(void)
+int pmic_dialog_init(unsigned char bus)
 {
-	struct pmic *p = get_pmic();
 	static const char name[] = "DIALOG_PMIC";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
 
 	p->name = name;
 	p->number_of_regs = DIALOG_NUM_OF_REGS;
@@ -31,7 +37,7 @@ int pmic_dialog_init(void)
 	p->interface = PMIC_I2C;
 	p->hw.i2c.addr = CONFIG_SYS_DIALOG_PMIC_I2C_ADDR;
 	p->hw.i2c.tx_num = 1;
-	p->bus = I2C_PMIC;
+	p->bus = bus;
 
 	return 0;
 }
diff --git a/drivers/misc/pmic_fsl.c b/drivers/misc/pmic_fsl.c
index 0ff75ed76e506e6ffe249b15d2add731d1632a93..0275fd9891aacea35cc9a51c53de48a9de029b8a 100644
--- a/drivers/misc/pmic_fsl.c
+++ b/drivers/misc/pmic_fsl.c
@@ -23,8 +23,9 @@
 
 #include <common.h>
 #include <spi.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
+#include <errno.h>
 
 #if defined(CONFIG_PMIC_SPI)
 static u32 pmic_spi_prepare_tx(u32 reg, u32 *val, u32 write)
@@ -33,10 +34,15 @@ static u32 pmic_spi_prepare_tx(u32 reg, u32 *val, u32 write)
 }
 #endif
 
-int pmic_init(void)
+int pmic_init(unsigned char bus)
 {
-	struct pmic *p = get_pmic();
 	static const char name[] = "FSL_PMIC";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
 
 	p->name = name;
 	p->number_of_regs = PMIC_NUM_OF_REGS;
@@ -54,7 +60,7 @@ int pmic_init(void)
 	p->interface = PMIC_I2C;
 	p->hw.i2c.addr = CONFIG_SYS_FSL_PMIC_I2C_ADDR;
 	p->hw.i2c.tx_num = 3;
-	p->bus = I2C_PMIC;
+	p->bus = bus;
 #else
 #error "You must select CONFIG_PMIC_SPI or CONFIG_PMIC_I2C"
 #endif
diff --git a/drivers/misc/pmic_i2c.c b/drivers/misc/pmic_i2c.c
index 1064bfe993dedcbb352a58c0d45295897faa0af1..3e5a784cf539cc942dcf87b5ee0bfad487f49053 100644
--- a/drivers/misc/pmic_i2c.c
+++ b/drivers/misc/pmic_i2c.c
@@ -28,7 +28,7 @@
 
 #include <common.h>
 #include <linux/types.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <i2c.h>
 #include <compiler.h>
 
@@ -36,7 +36,7 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
 {
 	unsigned char buf[4] = { 0 };
 
-	if (check_reg(reg))
+	if (check_reg(p, reg))
 		return -1;
 
 	switch (pmic_i2c_tx_num) {
@@ -79,7 +79,7 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
 	unsigned char buf[4] = { 0 };
 	u32 ret_val = 0;
 
-	if (check_reg(reg))
+	if (check_reg(p, reg))
 		return -1;
 
 	if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num))
diff --git a/drivers/misc/pmic_max8997.c b/drivers/misc/pmic_max8997.c
index 4943f667b519f40ed161cc8860d4706e63f3da94..7fe1b53ff07872eea67562258bf0b2c09bd10528 100644
--- a/drivers/misc/pmic_max8997.c
+++ b/drivers/misc/pmic_max8997.c
@@ -22,14 +22,20 @@
  */
 
 #include <common.h>
-#include <pmic.h>
-#include <max8997_pmic.h>
+#include <power/pmic.h>
+#include <power/max8997_pmic.h>
 #include <i2c.h>
+#include <errno.h>
 
-int pmic_init(void)
+int pmic_init(unsigned char bus)
 {
-	struct pmic *p = get_pmic();
 	static const char name[] = "MAX8997_PMIC";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
 
 	puts("Board PMIC init\n");
 
@@ -38,7 +44,7 @@ int pmic_init(void)
 	p->number_of_regs = PMIC_NUM_OF_REGS;
 	p->hw.i2c.addr = MAX8997_I2C_ADDR;
 	p->hw.i2c.tx_num = 1;
-	p->bus = I2C_0;
+	p->bus = bus;
 
 	return 0;
 }
diff --git a/drivers/misc/pmic_max8998.c b/drivers/misc/pmic_max8998.c
index cc69fd708032f3ab423728f35e0a3a1c5c813f74..452e1c8d86279642a78182603c98935d33916523 100644
--- a/drivers/misc/pmic_max8998.c
+++ b/drivers/misc/pmic_max8998.c
@@ -22,13 +22,19 @@
  */
 
 #include <common.h>
-#include <pmic.h>
-#include <max8998_pmic.h>
+#include <power/pmic.h>
+#include <power/max8998_pmic.h>
+#include <errno.h>
 
-int pmic_init(void)
+int pmic_init(unsigned char bus)
 {
-	struct pmic *p = get_pmic();
 	static const char name[] = "MAX8998_PMIC";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
 
 	puts("Board PMIC init\n");
 
@@ -37,7 +43,7 @@ int pmic_init(void)
 	p->number_of_regs = PMIC_NUM_OF_REGS;
 	p->hw.i2c.addr = MAX8998_I2C_ADDR;
 	p->hw.i2c.tx_num = 1;
-	p->bus = I2C_PMIC;
+	p->bus = bus;
 
 	return 0;
 }
diff --git a/drivers/misc/pmic_spi.c b/drivers/misc/pmic_spi.c
index 5a0dd22e29078c6a4b0b8e9fc7d2ad2867ece25e..27488ea5d929b6cd50c27b62b79396f0c8470cc1 100644
--- a/drivers/misc/pmic_spi.c
+++ b/drivers/misc/pmic_spi.c
@@ -28,7 +28,7 @@
 
 #include <common.h>
 #include <linux/types.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <spi.h>
 
 static struct spi_slave *slave;
@@ -59,7 +59,7 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write)
 			return -1;
 	}
 
-	if (check_reg(reg))
+	if (check_reg(p, reg))
 		return -1;
 
 	if (spi_claim_bus(slave))
diff --git a/drivers/rtc/mc13xxx-rtc.c b/drivers/rtc/mc13xxx-rtc.c
index 70ea8a15898116a553d70d7150588331b859cf46..e79f4621d3f9e8157e5861b3382a91181031b4dc 100644
--- a/drivers/rtc/mc13xxx-rtc.c
+++ b/drivers/rtc/mc13xxx-rtc.c
@@ -23,16 +23,18 @@
 #include <common.h>
 #include <rtc.h>
 #include <spi.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 
 int rtc_get(struct rtc_time *rtc)
 {
 	u32 day1, day2, time;
 	int tim, i = 0;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("FSL_PMIC");
 	int ret;
 
+	if (!p)
+		return -1;
 	do {
 		ret = pmic_reg_read(p, REG_RTC_DAY, &day1);
 		if (ret < 0)
@@ -61,7 +63,9 @@ int rtc_get(struct rtc_time *rtc)
 int rtc_set(struct rtc_time *rtc)
 {
 	u32 time, day;
-	struct pmic *p = get_pmic();
+	struct pmic *p = pmic_get("FSL_PMIC");
+	if (!p)
+		return -1;
 
 	time = mktime(rtc->tm_year, rtc->tm_mon, rtc->tm_mday,
 		      rtc->tm_hour, rtc->tm_min, rtc->tm_sec);
diff --git a/include/max8997_pmic.h b/include/power/max8997_pmic.h
similarity index 92%
rename from include/max8997_pmic.h
rename to include/power/max8997_pmic.h
index 17ae24ea6a0b895ad51e4add1cbf20df7e5412e5..1db7deb3bebc2a954e467ae6f6510f0c1718e0e6 100644
--- a/include/max8997_pmic.h
+++ b/include/power/max8997_pmic.h
@@ -111,7 +111,7 @@ enum {
 	MAX8997_REG_MBCCTRL6	= 0x55,
 	MAX8997_REG_OTPCGHCVS	= 0x56,
 
-	MAX8997_REG_SAFEOUTCTRL	= 0x5a,
+	MAX8997_REG_SAFEOUTCTRL = 0x5a,
 
 	MAX8997_REG_LBCNFG1	= 0x5e,
 	MAX8997_REG_LBCNFG2	= 0x5f,
@@ -171,9 +171,22 @@ enum {
 	PMIC_NUM_OF_REGS = 0x9b,
 };
 
+#define ACTDISSAFEO1 (1 << 4)
+#define ACTDISSAFEO2 (1 << 5)
 #define ENSAFEOUT1 (1 << 6)
 #define ENSAFEOUT2 (1 << 7)
 
+/* Charger */
+enum {CHARGER_ENABLE, CHARGER_DISABLE};
+#define DETBAT                  (1 << 2)
+#define MBCICHFCSET             (1 << 4)
+#define MBCHOSTEN               (1 << 6)
+#define VCHGR_FC                (1 << 7)
+
+#define CHARGER_MIN_CURRENT 200
+#define CHARGER_MAX_CURRENT 950
+#define CHARGER_CURRENT_RESOLUTION 50
+
 #define MAX8997_I2C_ADDR        (0xCC >> 1)
 #define MAX8997_RTC_ADDR	(0x0C >> 1)
 #define MAX8997_MUIC_ADDR	(0x4A >> 1)
diff --git a/include/max8998_pmic.h b/include/power/max8998_pmic.h
similarity index 100%
rename from include/max8998_pmic.h
rename to include/power/max8998_pmic.h
diff --git a/include/pmic.h b/include/power/pmic.h
similarity index 84%
rename from include/pmic.h
rename to include/power/pmic.h
index 1a2db0511094fb6a4b2471a50e7bd5d0af94e5a0..e9affc8dd60dae7064b1872b96476c12941d58e5 100644
--- a/include/pmic.h
+++ b/include/power/pmic.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Samsung Electronics
+ *  Copyright (C) 2011-2012 Samsung Electronics
  *  Lukasz Majewski <l.majewski@samsung.com>
  *
  * See file CREDITS for list of people who contributed to this
@@ -24,6 +24,10 @@
 #ifndef __CORE_PMIC_H_
 #define __CORE_PMIC_H_
 
+#include <common.h>
+#include <linux/list.h>
+#include <i2c.h>
+
 enum { PMIC_I2C, PMIC_SPI, };
 enum { I2C_PMIC, I2C_NUM, };
 enum { PMIC_READ, PMIC_WRITE, };
@@ -49,17 +53,20 @@ struct pmic {
 	unsigned char bus;
 	unsigned char interface;
 	unsigned char sensor_byte_order;
-	unsigned char number_of_regs;
+	unsigned int number_of_regs;
 	union hw {
 		struct p_i2c i2c;
 		struct p_spi spi;
 	} hw;
+
+	struct list_head list;
 };
 
-int pmic_init(void);
-int pmic_dialog_init(void);
-int check_reg(u32 reg);
-struct pmic *get_pmic(void);
+int pmic_init(unsigned char bus);
+int pmic_dialog_init(unsigned char bus);
+int check_reg(struct pmic *p, u32 reg);
+struct pmic *pmic_alloc(void);
+struct pmic *pmic_get(const char *s);
 int pmic_probe(struct pmic *p);
 int pmic_reg_read(struct pmic *p, u32 reg, u32 *val);
 int pmic_reg_write(struct pmic *p, u32 reg, u32 val);