From patchwork Tue Oct 2 06:33:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 1535821 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id A20B0DFFCF for ; Tue, 2 Oct 2012 06:33:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754060Ab2JBGdM (ORCPT ); Tue, 2 Oct 2012 02:33:12 -0400 Received: from acsinet15.oracle.com ([141.146.126.227]:31269 "EHLO acsinet15.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753389Ab2JBGdK (ORCPT ); Tue, 2 Oct 2012 02:33:10 -0400 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by acsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q926X4vB012989 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 2 Oct 2012 06:33:05 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q926X4oU020943 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 2 Oct 2012 06:33:04 GMT Received: from abhmt111.oracle.com (abhmt111.oracle.com [141.146.116.63]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q926X4Ea001264; Tue, 2 Oct 2012 01:33:04 -0500 Received: from linux-siqj.site (/75.36.244.44) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 01 Oct 2012 23:33:04 -0700 From: Yinghai Lu To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, Yinghai Lu Subject: [PATCH 03/10] PCI: prepare to use device drivers_autoprobe to delay attach drivers Date: Mon, 1 Oct 2012 23:33:01 -0700 Message-Id: <1349159588-15029-4-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.7.7 In-Reply-To: <1349159588-15029-1-git-send-email-yinghai@kernel.org> References: <1349159588-15029-1-git-send-email-yinghai@kernel.org> X-Source-IP: acsinet21.oracle.com [141.146.126.237] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Now pci enumerate the pci devices later and later use pci_bus_add_devices to add them to devices and probe pci devices. The reason for that two steps, want to do pci_assign_unassigned_resources for hot add pci devices before pci drivers get loaded. That step would leave pci devices out of devices tree for a while, and we can not use bus iterator to loop pci devices. We could device drivers_autoprobe and pci_bus_type notifier to delay pci driver loading instead of keep of pci device out of device tree. The patch add notifier to split out device attach out of device_add. Signed-off-by: Yinghai Lu --- drivers/pci/bus.c | 11 +++++++++++ drivers/pci/hotplug.c | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 6fe2115..3144262 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -160,6 +160,16 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } +static void pci_bus_attach_device(struct pci_dev *dev) +{ + int ret; + + ret = device_attach(&dev->dev); + /* make rescan working ? */ + dev->dev.drivers_autoprobe = true; + WARN_ON(ret < 0); +} + /** * pci_bus_add_device - add a single device * @dev: device to add @@ -176,6 +186,7 @@ int pci_bus_add_device(struct pci_dev *dev) if (retval) return retval; + pci_bus_attach_device(dev); dev->is_added = 1; pci_proc_attach_device(dev); pci_create_sysfs_dev_files(dev); diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index 2b5352a..3983934 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c @@ -35,3 +35,28 @@ int pci_uevent(struct device *dev, struct kobj_uevent_env *env) return -ENOMEM; return 0; } + +static int pci_hp_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct device *dev = data; + + switch (event) { + case BUS_NOTIFY_ADD_DEVICE: + dev->drivers_autoprobe = false; + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block pci_hp_nb = { + .notifier_call = &pci_hp_notifier, +}; + +static int __init pci_hp_init(void) +{ + return bus_register_notifier(&pci_bus_type, &pci_hp_nb); +} + +fs_initcall(pci_hp_init);