--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/hotplug/ppcphp.c	Fri Mar 19 09:50:42 2004
@@ -0,0 +1,237 @@
+
+>  	- Port the Linux PPC hotplug pci controller driver to the
+> 	  hotplug pci core interface, whenever Anton sends me an
+> 	  updated file...
+
+OK, OK :)
+
+I actually started rewriting the ppc hotswap code, it was a mess :)
+I found yet another useful bit of information, we can get the type
+of the pci slot.
+
+It is missing some of the insert and remove hooks, turns out we have an
+issue with large memory machines that means Im going to have to rewrite
+that bit totally. So there are some bits missing but it should end up
+fitting inside these hooks.
+
+Any suggestions on how to integrate it would be appreciated, I bundled a
+few things together into a struct Foo in the hope you would have
+somewhere to put them :)
+
+Anton
+
+
+/*
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+
+#define DR_INDICATOR 9002
+#define DR_ENTITY_SENSE 9003
+#define POWER_FULL_ON 100
+#define POWER_FULL_OFF 0
+#define ISOLATION_STATE 9001
+#define ISOLATE 0
+#define UNISOLATE 1
+
+char ibm_types[] = {
+	"NULL",
+	"33Mhz, 32 bit, 5 Volt PCI",
+	"50Mhz, 32 bit, 5 Volt PCI",
+	"33Mhz, 32 bit, 3.3 Volt PCI",
+	"33Mhz, 64 bit, 5 Volt PCI",
+	"50Mhz, 64 bit, 5 Volt PCI",
+	"33Mhz, 64 bit, 3.3 Volt PCI",
+	"66Mhz, 32 bit, 3.3 Volt PCI",
+	"66Mhz, 64 bit, 3.3 Volt PCI",
+	"Remote I/O (RIO), copper",
+	"Remote I/O (RIO), fibre optic"
+};
+
+struct Foo {
+	int state;
+	int type;
+	int power_domain;
+	char *name;
+};
+
+char *get_type(struct Foo *foo)
+{
+	return ibm_types[foo->type];
+}
+
+int get_state(struct Foo *foo)
+{
+	int error;
+	long status;
+
+	error = call_rtas("get-sensor-state", 2, 2, &status, DR_ENTITY_SENSE,
+			index[1]);
+
+	/*
+	 * status:
+	 * 0 - Slot is empty
+	 * 1 - Slot is occupied
+	 * 2 - Slot is unusable
+	 *
+	 * error:
+	 * -9000 - Slot must be power up and unisolated to get state
+	 * -9001 - Slot must be powerd up to get state
+	 * -9002 - Slot is unusable
+	 */
+	if (error == -9000)
+		status = 3;
+	else if (error == -9001)
+		status = 3;
+	else if (error == -9002)
+		status = 2;
+	else if (error)
+		status = -1;
+
+	return status;
+}
+
+int set_indicator(struct Foo *foo, int state)
+{
+	int error;
+
+	/*
+	 * 0 - Inactive
+	 * 1 - Active
+	 * 2 - Identify
+	 * 3 - Action
+	 */
+	if (state < 0 || state > 3)
+		return -1;
+
+	error = call_rtas("set-indicator", 3, 1, NULL, DR_INDICATOR, foo->slot,
+				state);
+
+	if (error)
+		return -1;
+
+	return 0;
+}
+
+#DEFINE RTAS_DELAY(A) \
+if (!(A)) \
+	break; \
+if ((A) == -2) { \
+	if (current->need_resched) \
+		schedule(); \
+	continue; \
+} \
+if ((A) >= 9900) { \
+	set_current_state(TASK_INTERRUPTIBLE); \
+	schedule_timeout((HZ+1000)/1000); \
+	continue; \
+} \
+return -1;
+
+int hot_add_pci(struct Foo *foo)
+{
+	int error;
+
+	while(1) {
+		error = call_rtas("set-power-level", 2, 2, NULL,
+				foo->power_domain, POWER_FULL_ON);
+		RTAS_DELAY(error);
+	}
+
+	while(1) {
+		error = call_rtas("set-indicator", 3, 1, NULL, ISOLATION_STATE,
+				foo->index, UNISOLATE);
+		RTAS_DELAY(error);
+	}
+
+	/* configure-connector */
+
+	return -1;
+}
+
+int hot_remove_pci(struct Foo *foo)
+{
+	int error;
+
+	while(1) {
+		error = call_rtas("set-indicator", 3, 1, NULL, ISOLATION_STATE,
+				foo->index, ISOLATE);
+		RTAS_DELAY(error);
+	}
+
+	while(1) {
+		error = call_rtas("set-power-level", 2, 2, NULL,
+				foo->power_domain, POWER_FULL_OFF);
+		RTAS_DELAY(error);
+	}
+
+	return 0;
+}
+
+void ppc_hotplug_init(void)
+{
+	struct device_node *p;
+	int *indexes, *names, *types, *power_domains;
+	int i;
+	char *name, *type;
+
+	for (p = find_devices("pci"); p; p = p->next) {
+		/*
+		 * indexes[0] is the number of indexes
+		 * indexes[1...n] are the slot numbers
+		 */
+		indexes = (int *)get_property(p, "ibm,drc-indexes", NULL);
+		if (!indexes)
+			continue;
+
+		/* &names[1] contains NULL terminated slot names */
+		names = (int *)get_property(p, "ibm,drc-names", NULL);
+		if (!names) {
+			printk("missing ibm,drc-names\n");
+			continue;
+		}
+
+		/* &types[1] contains NULL terminated slot types */
+		types = (int *)get_property(p, "ibm,drc-types", NULL);
+		if (!types) {
+			printk("missing ibm,drc-types\n");
+			continue;
+		}
+
+		/* power_domains[1...n] are the slot power domains */
+		power_domains = (int *)get_property(p,
+					"ibm,drc-power-domains", NULL);
+		if (!power_domains) {
+			printk("missing ibm,drc-power-domains\n");
+			continue;
+		}
+
+		name = (char *)&names[1];
+		type = (char *)&types[1];
+
+		for (i = 0; i < indexes[0]; i++) {
+			foo->slot = indexes[i];
+			foo->name = name;
+			if (atoi(type) > 0 && atoi(type) < 11)
+				foo->type = atoi(type);
+			else
+				foo->type = 0;
+			foo->power_domain = power_domains[i];
+
+			name += (strlen(name) + 1);
+			type += (strlen(type) + 1);
+		}
+	}
+
+	return;
+}