From patchwork Wed Jan 2 23:07:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Helgaas X-Patchwork-Id: 209159 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id C357A2C0098 for ; Thu, 3 Jan 2013 10:13:32 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752739Ab3ABXNb (ORCPT ); Wed, 2 Jan 2013 18:13:31 -0500 Received: from mail-yh0-f74.google.com ([209.85.213.74]:35438 "EHLO mail-yh0-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752206Ab3ABXNa (ORCPT ); Wed, 2 Jan 2013 18:13:30 -0500 Received: by mail-yh0-f74.google.com with SMTP id w68so511501yhw.5 for ; Wed, 02 Jan 2013 15:13:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:date:from:to:cc:subject:message-id:references :mime-version:content-type:content-disposition:in-reply-to :user-agent; bh=Nk/+BBxlqZf1P4lGXAzduOIhmWmSUKu2Z2gXhLoCHVc=; b=MTAyOPJDbu2aiUK7e5Ge0GTQkdVPGlBHPI9Uu8bKkJ4zbitk6vQ9G6JCVeMrnnqLNN FIJT+9NKSclgIiFtDljJL8hqlQRfEq9cz454Hi2s/iC7iz2AbAFbJABo+4bDOKaSrFbw zbRd+W2UABvhkRT5ICLskiNDH2RM2nMnFzlpeW2xNA2bplitSpp0cT7KWaUhkNW5M4JU yS07ZcVkWIRxgEVIQfpbUIZRbhxDFC1aFDZxBKnbGzqyRg1j5tZH5KF4lEazi4paIMI5 duDpi6SDcf58q2AcF5LHlPniqnWb1vqZtxp35+5enA1l3YooVlWiNkGNCyy45NlGggni bDug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:date:from:to:cc:subject:message-id:references :mime-version:content-type:content-disposition:in-reply-to :user-agent:x-gm-message-state; bh=Nk/+BBxlqZf1P4lGXAzduOIhmWmSUKu2Z2gXhLoCHVc=; b=O7Z9DjOs6hH/aSzlA2YBrVuv+gpqz3//+eIK5/5c+GRqbbdyvpT00FNRmyKMyGmNnI gXkBDmgZmWNwBLMTWf0Ffyo6AYha6AqV/N8iCxHbvYwcGsJC3y1eGQJuyOfiEA3e5guE 6Yzm+AdjiPQBsjhw6wtZRBljwb6ms8VP5Z0Pk7ugp6etzEh8IFDuP/anHenOXBuIUnBz DhKxQDutQiSgiEy1opRDlBlnbPP8RCyJmJfwDCC3AxXstxXn5CT5jrbq1YoXGsMJgA8m MA9Dj54Rfu5kUgDHZ+sWiN+mfdGou/IeKkHg2JQBnKaqKxp1D7WvWSqcs0wPlVkLKcDi PoAg== X-Received: by 10.236.89.9 with SMTP id b9mr21482671yhf.30.1357168052815; Wed, 02 Jan 2013 15:07:32 -0800 (PST) Received: from wpzn4.hot.corp.google.com (216-239-44-65.google.com [216.239.44.65]) by gmr-mx.google.com with ESMTPS id s58si3816178yhi.6.2013.01.02.15.07.32 (version=TLSv1/SSLv3 cipher=AES128-SHA); Wed, 02 Jan 2013 15:07:32 -0800 (PST) Received: from bhelgaas.mtv.corp.google.com (bhelgaas.mtv.corp.google.com [172.17.131.112]) by wpzn4.hot.corp.google.com (Postfix) with ESMTP id A22D182004A; Wed, 2 Jan 2013 15:07:32 -0800 (PST) Received: by bhelgaas.mtv.corp.google.com (Postfix, from userid 131485) id 4A4E9180325; Wed, 2 Jan 2013 15:07:32 -0800 (PST) Date: Wed, 2 Jan 2013 16:07:32 -0700 From: Bjorn Helgaas To: "Rafael J. Wysocki" Cc: "linux-pci@vger.kernel.org" , ACPI Devel Maling List , Greg Kroah-Hartman , LKML , Tony Luck , "H. Peter Anvin" , Yinghai Lu , Jiang Liu , Myron Stowe Subject: Re: [Alternative 2][PATCH] ACPI / PCI: Set root bridge ACPI handle in advance Message-ID: <20130102230732.GB31813@google.com> References: <1558789.gX8cmBgyDV@vostro.rjw.lan> <5457615.T2WjKPXXC4@vostro.rjw.lan> <2816571.07LqOj3EJg@vostro.rjw.lan> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <2816571.07LqOj3EJg@vostro.rjw.lan> User-Agent: Mutt/1.5.20 (2009-06-14) X-Gm-Message-State: ALoCoQnehgfFma5FLxatuJS0XTPIuo/iVy6fMkmCDdgHV7oH9tKjPo43NbbJPy/E4Fa8qpXrVgYQ0a71UH7D27KRgKXDFt+lhlo89fk0pS2Q64Ce/qNTQ7UHCU5q8b1fCthmfjFL9tExPO0Cxw17CA/6xSy8S+CZQuay8OxU8Qf1ERyevQC7kJ48pBXS1T9QkgphiZzcONfKl7Xr3rs+z2weGGb0YIGz/g== Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org On Thu, Dec 27, 2012 at 10:32:13PM +0100, Rafael J. Wysocki wrote: > To that end, split pci_create_root_bus() into two functions, > pci_alloc_root() and pci_add_root(), that will allocate memory for > the new PCI bus and bridge representations and register them with > the driver core, respectively, and that may be called directly by > the architectures that need to set the root bridge's ACPI handle > before registering it. I'm trying to *reduce* the interfaces for creating and scanning PCI host bridges, and this is a step in the opposite direction. > Next, Make both x86 and ia64 (the only architectures using ACPI at > the moment) call pci_alloc_root(), set the root bridge's ACPI handle > and then call pci_add_root() in their pci_acpi_scan_root() routines > instead of calling pci_create_root_bus(). For the other code paths > adding PCI root bridges define a new pci_create_root_bus() as a > simple combination of pci_alloc_root() and pci_add_root(). pci_create_root_bus() takes a "struct device *parent" argument. That seems like a logical place to tell the PCI core about the host bridge device, but x86 and ia64 currently pass NULL there. The patch below shows what I'm thinking. It does have the side-effect of changing the sysfs topology from this: /sys/devices/pci0000:00 /sys/devices/pci0000:00/0000:00:00.0 to this: /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/pci0000:00 /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/pci0000:00/0000:00:00.0 because it puts the PCI root bus (pci0000:00) under the PNP0A08 device rather than at the top level. That seems like an improvement to me, but it *is* different. Bjorn commit 5dee5f2f4fefbe4888939871c2252299067123bf Author: Bjorn Helgaas Date: Wed Jan 2 13:47:02 2013 -0700 --- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 0c01261..1cfde12 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -552,8 +552,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) if (!setup_mcfg_map(info, domain, (u8)root->secondary.start, (u8)root->secondary.end, root->mcfg_addr)) - bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, - sd, &resources); + bus = pci_create_root_bus(&device->dev, busnum, + &pci_root_ops, sd, + &resources); if (bus) { pci_scan_child_bus(bus); @@ -593,6 +594,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) return bus; } +int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) +{ + struct device *parent = bridge->dev.parent; + + if (parent) + ACPI_HANDLE_SET(&bridge->dev, to_acpi_device(parent)->handle); + return 0; +} + int __init pci_acpi_init(void) { struct pci_dev *dev = NULL; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 1af4008..d4516c4 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -303,28 +303,9 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) return 0; } -static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) -{ - int num; - unsigned int seg, bus; - - /* - * The string should be the same as root bridge's name - * Please look at 'pci_scan_bus_parented' - */ - num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus); - if (num != 2) - return -ENODEV; - *handle = acpi_get_pci_rootbridge_handle(seg, bus); - if (!*handle) - return -ENODEV; - return 0; -} - static struct acpi_bus_type acpi_pci_bus = { .bus = &pci_bus_type, .find_device = acpi_pci_find_device, - .find_bridge = acpi_pci_find_root_bridge, }; static int __init acpi_pci_init(void) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6186f03..3575b2b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1633,6 +1633,11 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) return max; } +int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) +{ + return 0; +} + struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources) { @@ -1645,7 +1650,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, char bus_addr[64]; char *fmt; - b = pci_alloc_bus(); if (!b) return NULL; @@ -1666,6 +1670,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, bridge->dev.parent = parent; bridge->dev.release = pci_release_bus_bridge_dev; dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); + error = pcibios_root_bridge_prepare(bridge); + if (error) + goto bridge_dev_reg_err; error = device_register(&bridge->dev); if (error) goto bridge_dev_reg_err; diff --git a/include/linux/pci.h b/include/linux/pci.h index 15472d6..238438c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -674,6 +674,7 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */ /* Some device drivers need know if pci is initiated */ extern int no_pci_devices(void); +int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge); void pcibios_fixup_bus(struct pci_bus *); int __must_check pcibios_enable_device(struct pci_dev *, int mask); /* Architecture specific versions may override this (weak) */