diff --git a/platforms/astbmc/rainier.c b/platforms/astbmc/rainier.c
index 467e6d5a..baa93254 100644
--- a/platforms/astbmc/rainier.c
+++ b/platforms/astbmc/rainier.c
@@ -10,6 +10,7 @@
 #include <i2c.h>
 #include <timebase.h>
 #include <timer.h>
+#include <pci.h>
 #include <pci-slot.h>
 
 #include "astbmc.h"
@@ -46,6 +47,61 @@ struct slot_hp_data {
 	uint8_t slot_index;
 };
 
+#define RAINIER_HP_DATA(st_name, controller, n)				\
+	static const struct slot_hp_data st_name = {			\
+		.hp_controller = &(controller),				\
+		.slot_index = n,					\
+	}
+
+#define RAINIER_SLOT_DEF(st_name, slot_name, hp_data)			\
+	static const struct slot_table_entry st_name[] = {		\
+		{							\
+			.etype = st_pluggable_slot,			\
+			.name = slot_name,				\
+			.platform_data = &(hp_data),			\
+		},							\
+		{ .etype = st_end },					\
+	}
+
+RAINIER_HP_DATA(c7_data, hp_controller_dcm0, 0);
+RAINIER_HP_DATA(c8_data, hp_controller_dcm0, 1);
+RAINIER_HP_DATA(c9_data, hp_controller_dcm0, 2);
+RAINIER_HP_DATA(c10_data, hp_controller_dcm0, 3);
+RAINIER_HP_DATA(c11_data, hp_controller_dcm0, 4);
+RAINIER_SLOT_DEF(p1phb3_slot, "C7", c7_data);
+RAINIER_SLOT_DEF(p1phb1_slot, "C8", c8_data);
+RAINIER_SLOT_DEF(p1phb0_slot, "C9", c9_data);
+RAINIER_SLOT_DEF(p0phb3_slot, "C10", c10_data);
+RAINIER_SLOT_DEF(p0phb0_slot, "C11", c11_data);
+
+RAINIER_HP_DATA(c0_data, hp_controller_dcm1, 0);
+RAINIER_HP_DATA(c1_data, hp_controller_dcm1, 1);
+RAINIER_HP_DATA(c2_data, hp_controller_dcm1, 2);
+RAINIER_HP_DATA(c3_data, hp_controller_dcm1, 3);
+RAINIER_HP_DATA(c4_data, hp_controller_dcm1, 4);
+RAINIER_SLOT_DEF(p3phb3_slot, "C0", c0_data);
+RAINIER_SLOT_DEF(p3phb1_slot, "C1", c1_data);
+RAINIER_SLOT_DEF(p3phb0_slot, "C2", c2_data);
+RAINIER_SLOT_DEF(p2phb3_slot, "C3", c3_data);
+RAINIER_SLOT_DEF(p2phb0_slot, "C4", c4_data);
+
+static const struct slot_table_entry rainier_phb_table[] = {
+	ST_PHB_ENTRY(0, 0, p0phb0_slot),
+	ST_PHB_ENTRY(0, 3, p0phb3_slot),
+
+	ST_PHB_ENTRY(2, 0, p1phb0_slot),
+	ST_PHB_ENTRY(2, 1, p1phb1_slot),
+	ST_PHB_ENTRY(2, 3, p1phb3_slot),
+
+	ST_PHB_ENTRY(4, 0, p2phb0_slot),
+	ST_PHB_ENTRY(4, 3, p2phb3_slot),
+
+	ST_PHB_ENTRY(6, 0, p3phb0_slot),
+	ST_PHB_ENTRY(6, 1, p3phb1_slot),
+	ST_PHB_ENTRY(6, 3, p3phb3_slot),
+	{ .etype = st_end },
+};
+
 static int64_t hp_controller_i2c_read(struct hp_controller *hpc,
 				      uint32_t *data)
 {
@@ -127,7 +183,7 @@ unlock:
 	return rc;
 }
 
-static void __unused timer_check_enable(struct timer *t __unused, void *data,
+static void timer_check_enable(struct timer *t __unused, void *data,
 			       uint64_t now __unused)
 {
 	struct pci_slot *slot = data;
@@ -176,7 +232,7 @@ unlock:
 	return rc;
 }
 
-static int64_t __unused hp_controller_disable(struct hp_controller *hpc, int slot_index)
+static int64_t hp_controller_disable(struct hp_controller *hpc, int slot_index)
 {
 	uint32_t state, en_mask, ctl_mask, pg_mask;
 	uint64_t rc = OPAL_SUCCESS;
@@ -227,11 +283,108 @@ static void hp_controller_init(struct hp_controller *hpc, uint32_t chip_id)
 	}
 }
 
+static int64_t rainier_pci_slot_get_power_state(struct pci_slot *slot,
+						uint8_t *val)
+{
+	uint32_t state, en_mask, ctl_mask, pg_mask;
+	struct slot_table_entry *ent = slot->data;
+	const struct slot_hp_data *hp_data;
+	struct hp_controller *hpc;
+	uint32_t slot_index;
+
+	if (!ent || !ent->platform_data)
+		return OPAL_PARAMETER;
+
+	hp_data = ent->platform_data;
+	slot_index = hp_data->slot_index;
+	hpc = hp_data->hp_controller;
+
+	hp_get_masks(slot_index, &en_mask, &pg_mask, &ctl_mask);
+
+	lock(&hpc->lock);
+	hp_controller_i2c_read(hpc, &state);
+	unlock(&hpc->lock);
+
+	*val = (state & en_mask) && (state & pg_mask);
+	return 0;
+}
+
+static int64_t rainier_pci_slot_set_power_state(struct pci_slot *slot,
+						uint8_t val)
+{
+	struct slot_table_entry *ent = slot->data;
+	const struct slot_hp_data *hp_data;
+	struct hp_controller *hpc;
+	uint32_t slot_index;
+	int64_t rc;
+
+	if (!ent || !ent->platform_data)
+		return OPAL_PARAMETER;
+	if (val != PCI_SLOT_POWER_OFF && val != PCI_SLOT_POWER_ON)
+		return OPAL_PARAMETER;
+
+	hp_data = ent->platform_data;
+	slot_index = hp_data->slot_index;
+	hpc = hp_data->hp_controller;
+
+	slot->power_state = val;
+	if (val == PCI_SLOT_POWER_ON) {
+		rc = hp_controller_enable(hpc, slot_index);
+		if (!rc) {
+			/* schedule to check state of PGOOD after 2s */
+			init_timer(&hpc->slot_timer[slot_index],
+				   timer_check_enable, slot);
+			schedule_timer(&hpc->slot_timer[slot_index],
+				       msecs_to_tb(PGOOD_QUERY_WINDOW));
+			pci_slot_set_state(slot, PCI_SLOT_STATE_SPOWER_START);
+			rc = OPAL_ASYNC_COMPLETION;
+		}
+	} else {
+		rc = hp_controller_disable(hpc, slot_index);
+	}
+	return rc;
+}
+
+static void rainier_get_slot_info(struct phb *phb, struct pci_device *pd)
+{
+	struct pci_slot *slot;
+
+	if (!pd || pd->slot)
+		return;
+
+	slot_table_get_slot_info(phb, pd);
+	if (!pd->slot)
+		return;
+
+	slot = pd->slot;
+	if (!pd->parent && phb->slot) {
+		void (*tmp)(struct pci_slot *slot, struct dt_node *np);
+		/*
+		 * For PHB slots, keep the ops of the PHB, except for
+		 * add_properties, which was defined by the slot table
+		 * framework and takes care of things like slot label,
+		 * location, ...
+		 */
+		tmp = slot->ops.add_properties;
+		memcpy(&slot->ops, &phb->slot->ops,
+		       sizeof(struct pci_slot_ops));
+		slot->ops.add_properties = tmp;
+	}
+
+	if (slot->data) {
+		/* slots defined in our slot table support power management */
+		slot->ops.get_power_state = rainier_pci_slot_get_power_state;
+		slot->ops.set_power_state = rainier_pci_slot_set_power_state;
+	}
+}
+
 static void rainier_pci_probe_complete(void)
 {
 	prlog(PR_DEBUG, "PLAT: checking power of PCI slots\n");
 	hp_controller_check_enable(&hp_controller_dcm0, -1);
 	hp_controller_check_enable(&hp_controller_dcm1, -1);
+
+	check_all_slot_table();
 }
 
 static void rainier_init_slot_power(void)
@@ -246,6 +399,7 @@ static void rainier_init_slot_power(void)
 static void rainier_init(void)
 {
 	astbmc_init();
+	slot_table_init(rainier_phb_table);
 	rainier_init_slot_power();
 }
 
@@ -274,6 +428,7 @@ DECLARE_PLATFORM(rainier) = {
 	.bmc			= &bmc_plat_ast2600_openbmc,
 	.cec_power_down         = astbmc_ipmi_power_down,
 	.cec_reboot             = astbmc_ipmi_reboot,
+	.pci_get_slot_info	= rainier_get_slot_info,
 	.pci_probe_complete	= rainier_pci_probe_complete,
 	.elog_commit		= ipmi_elog_commit,
 	.exit			= astbmc_exit,
