All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Chiang <achiang@hp.com>
To: lenb@kernel.org
Cc: linux-acpi@vger.kernel.org, Bjorn Helgaas <bjorn.helgaas@hp.com>,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org
Subject: [PATCH v2 03/11] ACPI: Introduce acpi_get_pci_dev()
Date: Wed, 03 Jun 2009 23:58:31 -0600	[thread overview]
Message-ID: <20090604055831.18802.52360.stgit@bob.kio> (raw)
In-Reply-To: <20090604054504.18802.21690.stgit@bob.kio>

Convert an ACPI CA handle to a struct pci_dev.

Performing this lookup dynamically allows us to get rid of the
ACPI-PCI binding code, which:

	- eliminates struct acpi_device vs struct pci_dev lifetime issues
	- lays more groundwork for eliminating .start from acpi_device_ops
	  and thus simplifying ACPI drivers
	- whacks out a lot of code

This change lays the groundwork for eliminating much of pci_bind.c.

Although pci_root.c may not be the most logical place for this
change, putting it here saves us from having to export acpi_pci_find_root.

Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Alex Chiang <achiang@hp.com>
---

 drivers/acpi/pci_root.c     |   81 +++++++++++++++++++++++++++++++++++++++++++
 include/acpi/acpi_drivers.h |    1 +
 2 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 888cb9f..e509991 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -329,6 +329,87 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
 	return NULL;
 }
 
+struct acpi_handle_node {
+	struct list_head node;
+	acpi_handle handle;
+};
+
+/**
+ * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev
+ * @handle: the handle in question
+ *
+ * Given an ACPI CA handle, the desired PCI device is located in the
+ * list of PCI devices.
+ *
+ * If the device is found, its reference count is increased and this
+ * function returns a pointer to its data structure.  The caller must
+ * decrement the reference count by calling pci_dev_put().
+ * If no device is found, %NULL is returned.
+ */
+struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
+{
+	int dev, fn;
+	unsigned long long adr;
+	acpi_status status;
+	acpi_handle phandle;
+	struct pci_bus *pbus;
+	struct pci_dev *pdev = NULL;
+	struct acpi_handle_node *node, *tmp;
+	struct acpi_pci_root *root;
+	LIST_HEAD(device_list);
+
+	/*
+	 * Walk up the ACPI CA namespace until we reach a PCI root bridge.
+	 */
+	phandle = handle;
+	while (!acpi_is_root_bridge(phandle)) {
+		node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL);
+		if (!node)
+			goto out;
+
+		INIT_LIST_HEAD(&node->node);
+		node->handle = phandle;
+		list_add(&node->node, &device_list);
+
+		status = acpi_get_parent(phandle, &phandle);
+		if (ACPI_FAILURE(status))
+			goto out;
+	}
+
+	root = acpi_pci_find_root(phandle);
+	if (!root)
+		goto out;
+
+	pbus = root->bus;
+
+	/*
+	 * Now, walk back down the PCI device tree until we return to our
+	 * original handle. Assumes that everything between the PCI root
+	 * bridge and the device we're looking for must be a P2P bridge.
+	 */
+	list_for_each_entry(node, &device_list, node) {
+		acpi_handle hnd = node->handle;
+		status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr);
+		if (ACPI_FAILURE(status))
+			goto out;
+		dev = (adr >> 16) & 0xffff;
+		fn  = adr & 0xffff;
+
+		pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
+		if (hnd == handle)
+			break;
+
+		pbus = pdev->subordinate;
+		pci_dev_put(pdev);
+	}
+out:
+	list_for_each_entry_safe(node, tmp, &device_list, node)
+		kfree(node);
+
+	return pdev;
+}
+EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
+
 /**
  * acpi_pci_osc_control_set - commit requested control to Firmware
  * @handle: acpi_handle for the target ACPI object
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index bbe9207..1ef529b 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -97,6 +97,7 @@ void acpi_pci_irq_del_prt(int segment, int bus);
 
 struct pci_bus;
 
+struct pci_dev *acpi_get_pci_dev(acpi_handle);
 acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id);
 int acpi_pci_bind_root(struct acpi_device *device, struct acpi_pci_id *id,
 		       struct pci_bus *bus);

  parent reply	other threads:[~2009-06-04  5:58 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-04  5:58 [PATCH v2 00/11] Dynamic ACPI-PCI binding Alex Chiang
2009-06-04  5:58 ` [PATCH v2 01/11] ACPI: make acpi_pci_bind() static Alex Chiang
2009-06-04  5:58 ` [PATCH v2 02/11] ACPI: Introduce acpi_is_root_bridge() Alex Chiang
2009-06-04  5:58 ` Alex Chiang [this message]
2009-06-04  5:58 ` [PATCH v2 04/11] ACPI: eviscerate pci_bind.c Alex Chiang
2009-06-04  5:58 ` [PATCH v2 05/11] ACPI: simplify acpi_pci_irq_add_prt() API Alex Chiang
2009-06-04  5:58 ` [PATCH v2 06/11] ACPI: simplify acpi_pci_irq_del_prt() API Alex Chiang
2009-06-04  5:58 ` [PATCH v2 07/11] ACPI: acpi_pci_unbind should clean up properly after acpi_pci_bind Alex Chiang
2009-06-04  8:42   ` Kenji Kaneshige
2009-06-04 23:35     ` Alex Chiang
2009-06-05 15:49       ` Bjorn Helgaas
2009-06-05 15:59         ` Alex Chiang
2009-06-09 19:14         ` Alex Chiang
2009-06-08  3:23       ` Kenji Kaneshige
2009-06-08  3:23         ` Kenji Kaneshige
2009-06-09 19:09         ` Alex Chiang
2009-06-04  5:58 ` [PATCH v2 08/11] PCI Hotplug: acpiphp: convert to acpi_get_pci_dev Alex Chiang
2009-06-11 21:48   ` Jesse Barnes
2009-06-11 22:17     ` Jesse Barnes
2009-06-11 22:17       ` Jesse Barnes
2009-06-04  5:59 ` [PATCH v2 09/11] ACPI: kill acpi_get_pci_id Alex Chiang
2009-06-04  5:59 ` [PATCH v2 10/11] ACPI: video: convert to acpi_get_pci_dev Alex Chiang
2009-06-04  5:59 ` [PATCH v2 11/11] ACPI: kill acpi_get_physical_pci_device() Alex Chiang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090604055831.18802.52360.stgit@bob.kio \
    --to=achiang@hp.com \
    --cc=bjorn.helgaas@hp.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.