Skip to contentSkip to conversation

acpi: export acpi_bus_trim

PATCH In review Kristen Accardi 2 participants 6 messages Feb 23, 2006 – Mar 2, 2006 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#1 lore raw

PATCH 1/3 acpi: export acpi_bus_trim

In reply to a message not in the archive

Export the acpi_bus_trim function so that the pci hotplug driver can use it.

---
 drivers/acpi/scan.c     |    5 +++--
 include/acpi/acpi_bus.h |    1 +
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/acpi/scan.c +3 -2
@@ -24,7 +24,6 @@ static LIST_HEAD(acpi_device_list);
 DEFINE_SPINLOCK(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
-static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 
 static void acpi_device_release(struct kobject *kobj)
 {
@@ -1268,7 +1267,7 @@ int acpi_bus_start(struct acpi_device *d
 
 EXPORT_SYMBOL(acpi_bus_start);
 
-static int acpi_bus_trim(struct acpi_device *start, int rmdevice)
+int acpi_bus_trim(struct acpi_device *start, int rmdevice)
 {
 	acpi_status status;
 	struct acpi_device *parent, *child;
@@ -1321,6 +1320,8 @@ static int acpi_bus_trim(struct acpi_dev
 	}
 	return err;
 }
+EXPORT_SYMBOL_GPL(acpi_bus_trim);
+
 
 static int acpi_bus_scan_fixed(struct acpi_device *root)
 {
include/acpi/acpi_bus.h +1 -0
@@ -330,6 +330,7 @@ int acpi_bus_register_driver(struct acpi
 int acpi_bus_unregister_driver(struct acpi_driver *driver);
 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
 		 acpi_handle handle, int type);
+int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 int acpi_bus_start(struct acpi_device *device);
 
 int acpi_match_ids(struct acpi_device *device, char *ids);

--

#6 lore raw

PATCH 3/3 acpi: remove dock event handling from ibm_acpi

In reply to a message not in the archive

Remove dock station support from ibm_acpi by default. This support has been put into acpiphp instead. Allow ibm_acpi to continue to provide docking station support via config option for laptops/docking stations that are not supported by acpiphp.

---
 drivers/acpi/Kconfig    |   12 ++++++++++++
 drivers/acpi/ibm_acpi.c |   13 ++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)
drivers/acpi/Kconfig +12 -0
@@ -205,6 +205,18 @@ config ACPI_IBM
 
 	  If you have an IBM ThinkPad laptop, say Y or M here.
 
+config ACPI_IBM_DOCK
+	bool "Legacy Docking Station Support"
+	depends on ACPI_IBM
+	default n
+	---help---
+	  Allows the ibm_acpi driver to handle docking station events.
+	  This support is obsoleted by CONFIG_HOTPLUG_PCI_ACPI.  It will
+	  allow locking and removing the laptop from the docking station,
+	  but will not properly connect PCI devices.
+
+	  If you are not sure, say N here.
+
 config ACPI_TOSHIBA
 	tristate "Toshiba Laptop Extras"
 	depends on X86
drivers/acpi/ibm_acpi.c +10 -3
@@ -160,13 +160,13 @@ IBM_HANDLE(cmos, root, "\\UCMS",	/* R50,
 	   "\\CMOS",		/* A3x, G4x, R32, T23, T30, X22-24, X30 */
 	   "\\CMS",		/* R40, R40e */
     );				/* all others */
-
+#ifdef CONFIG_ACPI_IBM_DOCK
 IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
 	   "\\_SB.PCI0.DOCK",	/* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
 	   "\\_SB.PCI0.PCI1.DOCK",	/* all others */
 	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
     );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
-
+#endif
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
 	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
 	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
@@ -844,7 +844,7 @@ static int _sta(acpi_handle handle)
 
 	return status;
 }
-
+#ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
 
 static int dock_read(char *p)
@@ -907,6 +907,7 @@ static void dock_notify(struct ibm_struc
 		acpi_bus_generate_event(ibm->device, event, 0);	/* unknown */
 	}
 }
+#endif
 
 static int bay_status_supported;
 static int bay_status2_supported;
@@ -1574,6 +1575,7 @@ static struct ibm_struct ibms[] = {
 	 .read = light_read,
 	 .write = light_write,
 	 },
+#ifdef CONFIG_ACPI_IBM_DOCK
 	{
 	 .name = "dock",
 	 .read = dock_read,
@@ -1589,6 +1591,7 @@ static struct ibm_struct ibms[] = {
 	 .handle = &pci_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
+#endif
 	{
 	 .name = "bay",
 	 .init = bay_init,
@@ -1880,7 +1883,9 @@ IBM_PARAM(hotkey);
 IBM_PARAM(bluetooth);
 IBM_PARAM(video);
 IBM_PARAM(light);
+#ifdef CONFIG_ACPI_IBM_DOCK
 IBM_PARAM(dock);
+#endif
 IBM_PARAM(bay);
 IBM_PARAM(cmos);
 IBM_PARAM(led);
@@ -1927,7 +1932,9 @@ static int __init acpi_ibm_init(void)
 	IBM_HANDLE_INIT(hkey);
 	IBM_HANDLE_INIT(lght);
 	IBM_HANDLE_INIT(cmos);
+#ifdef CONFIG_ACPI_IBM_DOCK
 	IBM_HANDLE_INIT(dock);
+#endif
 	IBM_HANDLE_INIT(pci);
 	IBM_HANDLE_INIT(bay);
 	if (bay_handle)

--

#2 lore raw

PATCH 2/3 acpiphp: add dock event handling

In reply to a message not in the archive

These patches add generic dock event handling to acpiphp. If there are pci devices that need to be inserted/removed after the dock event, the event notification will be handed down to the normal pci hotplug event handler in acpiphp so that new bridges/devices can be enumerated.

Because some dock stations do not have pci bridges or pci devices that need to be inserted after a dock, acpiphp will remain loaded to handle dock events even if no hotpluggable pci slots are discovered.

You probably need to have the pci=assign-busses kernel parameter enabled to use these patches, and you may not allow ibm_acpi to handle docking notifications and use this patch.

This patch incorporates feedback provided by many.

---
 drivers/pci/hotplug/Makefile       |    3 
 drivers/pci/hotplug/acpiphp.h      |   36 +++
 drivers/pci/hotplug/acpiphp_core.c |    7 
 drivers/pci/hotplug/acpiphp_dock.c |  438 +++++++++++++++++++++++++++++++++++++
 drivers/pci/hotplug/acpiphp_glue.c |   82 +++++-
 5 files changed, 546 insertions(+), 20 deletions(-)
drivers/pci/hotplug/acpiphp.h +36 -0
@@ -161,6 +161,25 @@ struct acpiphp_attention_info
 	struct module *owner;
 };
 
+
+struct dependent_device {
+	struct list_head device_list;
+	struct list_head pci_list;
+	acpi_handle handle;
+	struct acpiphp_func *func;
+};
+
+
+struct acpiphp_dock_station {
+	acpi_handle handle;
+	u32 last_dock_time;
+	u32 flags;
+	struct acpiphp_func *dock_bridge;
+	struct list_head dependent_devices;
+	struct list_head pci_dependent_devices;
+};
+
+
 /* PCI bus bridge HID */
 #define ACPI_PCI_HOST_HID		"PNP0A03"
 
@@ -198,6 +217,12 @@ struct acpiphp_attention_info
 #define FUNC_HAS_PS1		(0x00000020)
 #define FUNC_HAS_PS2		(0x00000040)
 #define FUNC_HAS_PS3		(0x00000080)
+#define FUNC_HAS_DCK            (0x00000100)
+#define FUNC_IS_DD              (0x00000200)
+
+/* dock station flags */
+#define DOCK_DOCKING            (0x00000001)
+#define DOCK_HAS_BRIDGE         (0x00000002)
 
 /* function prototypes */
 
@@ -211,6 +236,7 @@ extern void acpiphp_glue_exit (void);
 extern int acpiphp_get_num_slots (void);
 extern struct acpiphp_slot *get_slot_from_id (int id);
 typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
+void handle_hotplug_event_func(acpi_handle, u32, void*);
 
 extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
 extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
@@ -220,6 +246,16 @@ extern u8 acpiphp_get_latch_status (stru
 extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
 extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
 
+/* acpiphp_dock.c */
+extern int find_dock_station(void);
+extern void remove_dock_station(void);
+extern void add_dependent_device(struct dependent_device *new_dd);
+extern void add_pci_dependent_device(struct dependent_device *new_dd);
+extern struct dependent_device *get_dependent_device(acpi_handle handle);
+extern int is_dependent_device(acpi_handle handle);
+extern int detect_dependent_devices(acpi_handle *bridge_handle);
+extern struct dependent_device *alloc_dependent_device(acpi_handle handle);
+
 /* variables */
 extern int acpiphp_debug;
 
drivers/pci/hotplug/acpiphp_core.c +6 -1
@@ -429,14 +429,17 @@ static void __exit cleanup_slots (void)
 static int __init acpiphp_init(void)
 {
 	int retval;
+	int docking_station;
 
 	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
 
 	acpiphp_debug = debug;
 
+	docking_station = find_dock_station();
+
 	/* read all the ACPI info from the system */
 	retval = init_acpi();
-	if (retval)
+	if (retval && !(docking_station))
 		return retval;
 
 	return init_slots();
@@ -448,6 +451,8 @@ static void __exit acpiphp_exit(void)
 	cleanup_slots();
 	/* deallocate internal data structures etc. */
 	acpiphp_glue_exit();
+
+	remove_dock_station();
 }
 
 module_init(acpiphp_init);
drivers/pci/hotplug/acpiphp_dock.c new file +438 -0

438 lines not on this page · raw message

drivers/pci/hotplug/acpiphp_glue.c +64 -18

158 lines not on this page · raw message

drivers/pci/hotplug/Makefile +2 -1
@@ -37,7 +37,8 @@ ibmphp-objs		:=	ibmphp_core.o	\
 				ibmphp_hpc.o
 
 acpiphp-objs		:=	acpiphp_core.o	\
-				acpiphp_glue.o
+				acpiphp_glue.o  \
+				acpiphp_dock.o
 
 rpaphp-objs		:=	rpaphp_core.o	\
 				rpaphp_pci.o	\

--

#3 lore raw

Re: [patch 2/3] acpiphp: add dock event handling

At Thu, 23 Feb 2006 11:56:17 -0800,

Quoted 17 lines · Kristen Accardi
drivers/pci/hotplug/acpiphp_glue.c +8 -3
@@ -828,11 +862,21 @@ static int acpiphp_bus_add(struct acpiph
 		dbg("no parent device, assuming NULL\n");
 		pdevice = NULL;
 	}
+	if (!acpi_bus_get_device(func->handle, &device)) {
+		dbg("bus exists... trim\n");
+		/* this shouldn't be in here, so remove
+		 * the bus then re-add it...
+		 */
+		ret_val = acpi_bus_trim(device, 1);
+		dbg("acpi_bus_trim return %x\n", ret_val);
+	}
 	ret_val = acpi_bus_add(&device, pdevice, func->handle,
-			ACPI_BUS_TYPE_DEVICE);
-	if (ret_val)
-		dbg("cannot add bridge to acpi list\n");

drivers/pci/hotplug/acpiphp_glue.c static int acpiphp_bus_add(struct acpiph · line 882

Quoted 10 lines
drivers/pci/hotplug/acpiphp_glue.c +6 -1
-
+		ACPI_BUS_TYPE_DEVICE);
+	if (ret_val) {
+		dbg("error adding bus, %x\n",
+			-ret_val);
+		goto acpiphp_bus_add_out;
+	}
 	/*
 	 * try to start anyway.  We could have failed to add
 	 * simply because this bus had previously been added

Hi Kristen,

Why don't you call acpi_bus_trim() when the device is removed. This time, eject_dock() or disable_device()? So you don't need to call acpi_bus_trim() as error case.

Thanks,
MUNE

#4 lore raw

Re: [Pcihpd-discuss] Re: [patch 2/3] acpiphp: add dock event handling

Quoted 32 lines · MUNEDA Takahiro

At Thu, 23 Feb 2006 11:56:17 -0800,

Quoted 17 lines · Kristen Accardi
drivers/pci/hotplug/acpiphp_glue.c +8 -3
@@ -828,11 +862,21 @@ static int acpiphp_bus_add(struct acpiph
 		dbg("no parent device, assuming NULL\n");
 		pdevice = NULL;
 	}
+	if (!acpi_bus_get_device(func->handle, &device)) {
+		dbg("bus exists... trim\n");
+		/* this shouldn't be in here, so remove
+		 * the bus then re-add it...
+		 */
+		ret_val = acpi_bus_trim(device, 1);
+		dbg("acpi_bus_trim return %x\n", ret_val);
+	}
 	ret_val = acpi_bus_add(&device, pdevice, func->handle,
-			ACPI_BUS_TYPE_DEVICE);
-	if (ret_val)
-		dbg("cannot add bridge to acpi list\n");

drivers/pci/hotplug/acpiphp_glue.c static int acpiphp_bus_add(struct acpiph · line 882

Quoted 10 lines
drivers/pci/hotplug/acpiphp_glue.c +6 -1
-
+		ACPI_BUS_TYPE_DEVICE);
+	if (ret_val) {
+		dbg("error adding bus, %x\n",
+			-ret_val);
+		goto acpiphp_bus_add_out;
+	}
 	/*
 	 * try to start anyway.  We could have failed to add
 	 * simply because this bus had previously been added

Hi Kristen,

Quoted 7 lines

Why don't you call acpi_bus_trim() when the device is removed. This time, eject_dock() or disable_device()? So you don't need to call acpi_bus_trim() as error case.

Thanks,
MUNE

MUNE,
I added this because I found that in some laptops the dsdt reported a bus present that wasn't actually, so the bus would be added at boot time, but the PRT not read if the laptop was booted undocked. Initially I tried to get a handle to the existing bus, and then if the bus already was added, just call acpi_bus_start() - but this did not cause the PRT to be read in this case - the only thing that worked for me was to remove the bus and readd it. If there's a better way to handle this, I'd appreciate the suggestion.

Kristen

#5 lore raw

Re: [Pcihpd-discuss] Re: [patch 2/3] acpiphp: add dock event handling

At Fri, 24 Feb 2006 09:29:37 -0800,

Quoted 9 lines · Kristen Accardi

I added this because I found that in some laptops the dsdt reported a bus present that wasn't actually, so the bus would be added at boot time, but the PRT not read if the laptop was booted undocked. Initially I tried to get a handle to the existing bus, and then if the bus already was added, just call acpi_bus_start() - but this did not cause the PRT to be read in this case - the only thing that worked for me was to remove the bus and readd it. If there's a better way to handle this, I'd appreciate the suggestion.

Hi Kristen,

I'm sorry for my late reply.
I understood the issue which you are encountered. When the _STA is not defined, acpi assumes that the device is always there. But actually, the device is not connected. So, when the device is added, acpi_device structure has already exist. Is my understanding right?

I've tried to solve this issue. But I could not find better solution, unfortunately. So I think your idea is good now,

Thanks,
MUNE