Re: [PATCH 22/40] PCI, acpiphp: Separate out hot-add support of pci host bridge

2012-10-12 Thread Tang Chen

Hi Yinghai,

When I was reviewing this patch, I found a little problem.

Please refer to email:
[PATCH 0/3] Find pci root bridges by comparing HID from 
acpi_device_info, not acpi_device.


I could be wrong. :)
If I didn't consider your idea correct, or you have a better solution,
please let me know.

Thanks. :)


On 09/20/2012 02:54 AM, Yinghai Lu wrote:

It causes confusion.

We may only need acpi hp for pci host bridge.

Split host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

Also remove not used res_lock in the struct.

-v2: put back pci_root_hp change in one patch
-v3: add pcibios_resource_survey_bus() calling
-v4: remove not needed code with remove_bridge
-v5: put back support for acpiphp support for slots just on root bus.
-v6: change some functions to *_p2p_* to make it more clean.

Signed-off-by: Yinghai Lu
---
  drivers/acpi/Makefile  |1 +
  drivers/acpi/pci_root_hp.c |  238 
  drivers/pci/hotplug/acpiphp_glue.c |   59 +++---
  3 files changed, 254 insertions(+), 44 deletions(-)
  create mode 100644 drivers/acpi/pci_root_hp.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 47199e2..c9abd4c 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,6 +36,7 @@ acpi-y+= processor_core.o
  acpi-y+= ec.o
  acpi-$(CONFIG_ACPI_DOCK)  += dock.o
  acpi-y+= pci_root.o pci_link.o pci_irq.o 
pci_bind.o
+acpi-$(CONFIG_HOTPLUG) += pci_root_hp.o
  acpi-y+= power.o
  acpi-y+= event.o
  acpi-y+= sysfs.o
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
new file mode 100644
index 000..e07c31b
--- /dev/null
+++ b/drivers/acpi/pci_root_hp.c
@@ -0,0 +1,238 @@
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ * only support root bridge
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+static LIST_HEAD(acpi_root_bridge_list);
+struct acpi_root_bridge {
+   struct list_head list;
+   acpi_handle handle;
+   u32 flags;
+};
+
+/* bridge flags */
+#define ROOT_BRIDGE_HAS_EJ0(0x0002)
+#define ROOT_BRIDGE_HAS_PS3(0x0080)
+
+#define ACPI_STA_FUNCTIONING   (0x0008)
+
+static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+
+   list_for_each_entry(bridge,_root_bridge_list, list)
+   if (bridge->handle == handle)
+   return bridge;
+
+   return NULL;
+}
+
+/* allocate and initialize host bridge data structure */
+static void add_acpi_root_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+   acpi_handle dummy_handle;
+   acpi_status status;
+
+   /* if the bridge doesn't have _STA, we assume it is always there */
+   status = acpi_get_handle(handle, "_STA",_handle);
+   if (ACPI_SUCCESS(status)) {
+   unsigned long long tmp;
+
+   status = acpi_evaluate_integer(handle, "_STA", NULL,);
+   if (ACPI_FAILURE(status)) {
+   printk(KERN_DEBUG "%s: _STA evaluation failure\n",
+__func__);
+   return;
+   }
+   if ((tmp&  ACPI_STA_FUNCTIONING) == 0)
+   /* don't register this object */
+   return;
+   }
+
+   bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL);
+   if (!bridge)
+   return;
+
+   bridge->handle = handle;
+
+   if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0",_handle)))
+   bridge->flags |= ROOT_BRIDGE_HAS_EJ0;
+   if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3",_handle)))
+   bridge->flags |= ROOT_BRIDGE_HAS_PS3;
+
+   list_add(>list,_root_bridge_list);
+}
+
+struct acpi_root_hp_work {
+   struct work_struct work;
+   acpi_handle handle;
+   u32 type;
+   void *context;
+};
+
+static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
+   void *context,
+   void (*func)(struct work_struct *work))
+{
+   struct acpi_root_hp_work *hp_work;
+   int ret;
+
+   hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
+   if (!hp_work)
+   return;
+
+   hp_work->handle = handle;
+   hp_work->type = type;
+   hp_work->context = context;
+
+   INIT_WORK(_work->work, func);
+   ret = queue_work(kacpi_hotplug_wq,_work->work);
+   if (!ret)
+   kfree(hp_work);
+}
+
+/* Program resources in newly inserted bridge */
+static void acpi_root_configure_bridge(acpi_handle handle)
+{
+   struct acpi_pci_root *root = acpi_pci_find_root(handle);
+
+   

Re: [PATCH 22/40] PCI, acpiphp: Separate out hot-add support of pci host bridge

2012-10-12 Thread Tang Chen

Hi Yinghai,

When I was reviewing this patch, I found a little problem.

Please refer to email:
[PATCH 0/3] Find pci root bridges by comparing HID from 
acpi_device_info, not acpi_device.


I could be wrong. :)
If I didn't consider your idea correct, or you have a better solution,
please let me know.

Thanks. :)


On 09/20/2012 02:54 AM, Yinghai Lu wrote:

It causes confusion.

We may only need acpi hp for pci host bridge.

Split host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

Also remove not used res_lock in the struct.

-v2: put back pci_root_hp change in one patch
-v3: add pcibios_resource_survey_bus() calling
-v4: remove not needed code with remove_bridge
-v5: put back support for acpiphp support for slots just on root bus.
-v6: change some functions to *_p2p_* to make it more clean.

Signed-off-by: Yinghai Luying...@kernel.org
---
  drivers/acpi/Makefile  |1 +
  drivers/acpi/pci_root_hp.c |  238 
  drivers/pci/hotplug/acpiphp_glue.c |   59 +++---
  3 files changed, 254 insertions(+), 44 deletions(-)
  create mode 100644 drivers/acpi/pci_root_hp.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 47199e2..c9abd4c 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,6 +36,7 @@ acpi-y+= processor_core.o
  acpi-y+= ec.o
  acpi-$(CONFIG_ACPI_DOCK)  += dock.o
  acpi-y+= pci_root.o pci_link.o pci_irq.o 
pci_bind.o
+acpi-$(CONFIG_HOTPLUG) += pci_root_hp.o
  acpi-y+= power.o
  acpi-y+= event.o
  acpi-y+= sysfs.o
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
new file mode 100644
index 000..e07c31b
--- /dev/null
+++ b/drivers/acpi/pci_root_hp.c
@@ -0,0 +1,238 @@
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ * only support root bridge
+ */
+
+#includelinux/init.h
+#includelinux/module.h
+
+#includelinux/kernel.h
+#includelinux/pci.h
+#includelinux/mutex.h
+#includelinux/slab.h
+#includelinux/acpi.h
+
+static LIST_HEAD(acpi_root_bridge_list);
+struct acpi_root_bridge {
+   struct list_head list;
+   acpi_handle handle;
+   u32 flags;
+};
+
+/* bridge flags */
+#define ROOT_BRIDGE_HAS_EJ0(0x0002)
+#define ROOT_BRIDGE_HAS_PS3(0x0080)
+
+#define ACPI_STA_FUNCTIONING   (0x0008)
+
+static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+
+   list_for_each_entry(bridge,acpi_root_bridge_list, list)
+   if (bridge-handle == handle)
+   return bridge;
+
+   return NULL;
+}
+
+/* allocate and initialize host bridge data structure */
+static void add_acpi_root_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+   acpi_handle dummy_handle;
+   acpi_status status;
+
+   /* if the bridge doesn't have _STA, we assume it is always there */
+   status = acpi_get_handle(handle, _STA,dummy_handle);
+   if (ACPI_SUCCESS(status)) {
+   unsigned long long tmp;
+
+   status = acpi_evaluate_integer(handle, _STA, NULL,tmp);
+   if (ACPI_FAILURE(status)) {
+   printk(KERN_DEBUG %s: _STA evaluation failure\n,
+__func__);
+   return;
+   }
+   if ((tmp  ACPI_STA_FUNCTIONING) == 0)
+   /* don't register this object */
+   return;
+   }
+
+   bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL);
+   if (!bridge)
+   return;
+
+   bridge-handle = handle;
+
+   if (ACPI_SUCCESS(acpi_get_handle(handle, _EJ0,dummy_handle)))
+   bridge-flags |= ROOT_BRIDGE_HAS_EJ0;
+   if (ACPI_SUCCESS(acpi_get_handle(handle, _PS3,dummy_handle)))
+   bridge-flags |= ROOT_BRIDGE_HAS_PS3;
+
+   list_add(bridge-list,acpi_root_bridge_list);
+}
+
+struct acpi_root_hp_work {
+   struct work_struct work;
+   acpi_handle handle;
+   u32 type;
+   void *context;
+};
+
+static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
+   void *context,
+   void (*func)(struct work_struct *work))
+{
+   struct acpi_root_hp_work *hp_work;
+   int ret;
+
+   hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
+   if (!hp_work)
+   return;
+
+   hp_work-handle = handle;
+   hp_work-type = type;
+   hp_work-context = context;
+
+   INIT_WORK(hp_work-work, func);
+   ret = queue_work(kacpi_hotplug_wq,hp_work-work);
+   if (!ret)
+   kfree(hp_work);
+}
+
+/* Program resources in newly inserted bridge */
+static void 

[PATCH 22/40] PCI, acpiphp: Separate out hot-add support of pci host bridge

2012-09-19 Thread Yinghai Lu
It causes confusion.

We may only need acpi hp for pci host bridge.

Split host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

Also remove not used res_lock in the struct.

-v2: put back pci_root_hp change in one patch
-v3: add pcibios_resource_survey_bus() calling
-v4: remove not needed code with remove_bridge
-v5: put back support for acpiphp support for slots just on root bus.
-v6: change some functions to *_p2p_* to make it more clean.

Signed-off-by: Yinghai Lu 
---
 drivers/acpi/Makefile  |1 +
 drivers/acpi/pci_root_hp.c |  238 
 drivers/pci/hotplug/acpiphp_glue.c |   59 +++---
 3 files changed, 254 insertions(+), 44 deletions(-)
 create mode 100644 drivers/acpi/pci_root_hp.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 47199e2..c9abd4c 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,6 +36,7 @@ acpi-y+= processor_core.o
 acpi-y += ec.o
 acpi-$(CONFIG_ACPI_DOCK)   += dock.o
 acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-$(CONFIG_HOTPLUG) += pci_root_hp.o
 acpi-y += power.o
 acpi-y += event.o
 acpi-y += sysfs.o
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
new file mode 100644
index 000..e07c31b
--- /dev/null
+++ b/drivers/acpi/pci_root_hp.c
@@ -0,0 +1,238 @@
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ * only support root bridge
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static LIST_HEAD(acpi_root_bridge_list);
+struct acpi_root_bridge {
+   struct list_head list;
+   acpi_handle handle;
+   u32 flags;
+};
+
+/* bridge flags */
+#define ROOT_BRIDGE_HAS_EJ0(0x0002)
+#define ROOT_BRIDGE_HAS_PS3(0x0080)
+
+#define ACPI_STA_FUNCTIONING   (0x0008)
+
+static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+
+   list_for_each_entry(bridge, _root_bridge_list, list)
+   if (bridge->handle == handle)
+   return bridge;
+
+   return NULL;
+}
+
+/* allocate and initialize host bridge data structure */
+static void add_acpi_root_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+   acpi_handle dummy_handle;
+   acpi_status status;
+
+   /* if the bridge doesn't have _STA, we assume it is always there */
+   status = acpi_get_handle(handle, "_STA", _handle);
+   if (ACPI_SUCCESS(status)) {
+   unsigned long long tmp;
+
+   status = acpi_evaluate_integer(handle, "_STA", NULL, );
+   if (ACPI_FAILURE(status)) {
+   printk(KERN_DEBUG "%s: _STA evaluation failure\n",
+__func__);
+   return;
+   }
+   if ((tmp & ACPI_STA_FUNCTIONING) == 0)
+   /* don't register this object */
+   return;
+   }
+
+   bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL);
+   if (!bridge)
+   return;
+
+   bridge->handle = handle;
+
+   if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", _handle)))
+   bridge->flags |= ROOT_BRIDGE_HAS_EJ0;
+   if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", _handle)))
+   bridge->flags |= ROOT_BRIDGE_HAS_PS3;
+
+   list_add(>list, _root_bridge_list);
+}
+
+struct acpi_root_hp_work {
+   struct work_struct work;
+   acpi_handle handle;
+   u32 type;
+   void *context;
+};
+
+static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
+   void *context,
+   void (*func)(struct work_struct *work))
+{
+   struct acpi_root_hp_work *hp_work;
+   int ret;
+
+   hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
+   if (!hp_work)
+   return;
+
+   hp_work->handle = handle;
+   hp_work->type = type;
+   hp_work->context = context;
+
+   INIT_WORK(_work->work, func);
+   ret = queue_work(kacpi_hotplug_wq, _work->work);
+   if (!ret)
+   kfree(hp_work);
+}
+
+/* Program resources in newly inserted bridge */
+static void acpi_root_configure_bridge(acpi_handle handle)
+{
+   struct acpi_pci_root *root = acpi_pci_find_root(handle);
+
+   pcibios_resource_survey_bus(root->bus);
+   pci_assign_unassigned_bus_resources(root->bus);
+}
+
+static void handle_root_bridge_insertion(acpi_handle handle)
+{
+   struct acpi_device *device, *pdevice;
+   acpi_handle phandle;
+   int ret_val;
+
+   acpi_get_parent(handle, );
+   if (acpi_bus_get_device(phandle, )) {
+   printk(KERN_DEBUG "no parent device, assuming 

[PATCH 22/40] PCI, acpiphp: Separate out hot-add support of pci host bridge

2012-09-19 Thread Yinghai Lu
It causes confusion.

We may only need acpi hp for pci host bridge.

Split host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

Also remove not used res_lock in the struct.

-v2: put back pci_root_hp change in one patch
-v3: add pcibios_resource_survey_bus() calling
-v4: remove not needed code with remove_bridge
-v5: put back support for acpiphp support for slots just on root bus.
-v6: change some functions to *_p2p_* to make it more clean.

Signed-off-by: Yinghai Lu ying...@kernel.org
---
 drivers/acpi/Makefile  |1 +
 drivers/acpi/pci_root_hp.c |  238 
 drivers/pci/hotplug/acpiphp_glue.c |   59 +++---
 3 files changed, 254 insertions(+), 44 deletions(-)
 create mode 100644 drivers/acpi/pci_root_hp.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 47199e2..c9abd4c 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,6 +36,7 @@ acpi-y+= processor_core.o
 acpi-y += ec.o
 acpi-$(CONFIG_ACPI_DOCK)   += dock.o
 acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-$(CONFIG_HOTPLUG) += pci_root_hp.o
 acpi-y += power.o
 acpi-y += event.o
 acpi-y += sysfs.o
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
new file mode 100644
index 000..e07c31b
--- /dev/null
+++ b/drivers/acpi/pci_root_hp.c
@@ -0,0 +1,238 @@
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ * only support root bridge
+ */
+
+#include linux/init.h
+#include linux/module.h
+
+#include linux/kernel.h
+#include linux/pci.h
+#include linux/mutex.h
+#include linux/slab.h
+#include linux/acpi.h
+
+static LIST_HEAD(acpi_root_bridge_list);
+struct acpi_root_bridge {
+   struct list_head list;
+   acpi_handle handle;
+   u32 flags;
+};
+
+/* bridge flags */
+#define ROOT_BRIDGE_HAS_EJ0(0x0002)
+#define ROOT_BRIDGE_HAS_PS3(0x0080)
+
+#define ACPI_STA_FUNCTIONING   (0x0008)
+
+static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+
+   list_for_each_entry(bridge, acpi_root_bridge_list, list)
+   if (bridge-handle == handle)
+   return bridge;
+
+   return NULL;
+}
+
+/* allocate and initialize host bridge data structure */
+static void add_acpi_root_bridge(acpi_handle handle)
+{
+   struct acpi_root_bridge *bridge;
+   acpi_handle dummy_handle;
+   acpi_status status;
+
+   /* if the bridge doesn't have _STA, we assume it is always there */
+   status = acpi_get_handle(handle, _STA, dummy_handle);
+   if (ACPI_SUCCESS(status)) {
+   unsigned long long tmp;
+
+   status = acpi_evaluate_integer(handle, _STA, NULL, tmp);
+   if (ACPI_FAILURE(status)) {
+   printk(KERN_DEBUG %s: _STA evaluation failure\n,
+__func__);
+   return;
+   }
+   if ((tmp  ACPI_STA_FUNCTIONING) == 0)
+   /* don't register this object */
+   return;
+   }
+
+   bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL);
+   if (!bridge)
+   return;
+
+   bridge-handle = handle;
+
+   if (ACPI_SUCCESS(acpi_get_handle(handle, _EJ0, dummy_handle)))
+   bridge-flags |= ROOT_BRIDGE_HAS_EJ0;
+   if (ACPI_SUCCESS(acpi_get_handle(handle, _PS3, dummy_handle)))
+   bridge-flags |= ROOT_BRIDGE_HAS_PS3;
+
+   list_add(bridge-list, acpi_root_bridge_list);
+}
+
+struct acpi_root_hp_work {
+   struct work_struct work;
+   acpi_handle handle;
+   u32 type;
+   void *context;
+};
+
+static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
+   void *context,
+   void (*func)(struct work_struct *work))
+{
+   struct acpi_root_hp_work *hp_work;
+   int ret;
+
+   hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
+   if (!hp_work)
+   return;
+
+   hp_work-handle = handle;
+   hp_work-type = type;
+   hp_work-context = context;
+
+   INIT_WORK(hp_work-work, func);
+   ret = queue_work(kacpi_hotplug_wq, hp_work-work);
+   if (!ret)
+   kfree(hp_work);
+}
+
+/* Program resources in newly inserted bridge */
+static void acpi_root_configure_bridge(acpi_handle handle)
+{
+   struct acpi_pci_root *root = acpi_pci_find_root(handle);
+
+   pcibios_resource_survey_bus(root-bus);
+   pci_assign_unassigned_bus_resources(root-bus);
+}
+
+static void handle_root_bridge_insertion(acpi_handle handle)
+{
+   struct acpi_device *device, *pdevice;
+   acpi_handle phandle;
+   int ret_val;
+
+