From patchwork Fri Jan 18 16:07:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 2003851 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 8930FDF280 for ; Fri, 18 Jan 2013 16:10:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752744Ab3ARQKC (ORCPT ); Fri, 18 Jan 2013 11:10:02 -0500 Received: from mail-da0-f48.google.com ([209.85.210.48]:51756 "EHLO mail-da0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754454Ab3ARQIJ (ORCPT ); Fri, 18 Jan 2013 11:08:09 -0500 Received: by mail-da0-f48.google.com with SMTP id k18so1703831dae.7 for ; Fri, 18 Jan 2013 08:08:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=eVh5YV4BCoHa7A6AZVoOvGh1gAYwatXpVAoVTTfCUNI=; b=ORUhjc3ao2j1nscprXdUxbBSD837kMT5+tqeVKWuyVsn5ir/NTPLuOSUs8LdAlSvp8 VssREbAIe+8f7YORCqD675iinokPiNWH00TBxf6JmFnMw2zQPThxdr5uxi5IVzwKituA nX2FjYnRJUw1x0b2eYJXPpko4GJxrzqo1Fs568we+NjQN3eoh//A5lcr44NwmrVf/enx hxFpZg5GtLIo5yj+/P7Ku93d0bG5Y16BajHpRhtww0ktwjEqDnnRndueFdyht5w5xfFX 6JNgdeAQ9tKDQhiuTxbB7TTK5o2AVebxx1JG14tPG+8hgPlYXHLqwS89dKHGlG/3olg4 Yuqg== X-Received: by 10.68.241.65 with SMTP id wg1mr6772166pbc.141.1358525288774; Fri, 18 Jan 2013 08:08:08 -0800 (PST) Received: from localhost.localdomain ([120.197.109.98]) by mx.google.com with ESMTPS id ux4sm3320742pbc.25.2013.01.18.08.08.04 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 18 Jan 2013 08:08:07 -0800 (PST) From: Jiang Liu To: "Rafael J . Wysocki" , Bjorn Helgaas Cc: Jiang Liu , Yinghai Lu , Kenji Kaneshige , Yijing Wang , Jiang Liu , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Greg Kroah-Hartman , ACPI Devel Maling List , Toshi Kani , Myron Stowe Subject: [RFC PATCH v5 2/8] PCI: split registration of PCI bus devices into two stages Date: Sat, 19 Jan 2013 00:07:40 +0800 Message-Id: <1358525267-14268-3-git-send-email-jiang.liu@huawei.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1358525267-14268-1-git-send-email-jiang.liu@huawei.com> References: <1358525267-14268-1-git-send-email-jiang.liu@huawei.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org When handling BUS_NOTIFY_ADD_DEVICE event for a PCI bridge device, the notification handler can't hold reference count to the new PCI bus because the device object for the new bus (pci_dev->subordinate->dev) hasn't been initialized yet. Split the registration of PCI bus device into two stages as below, so that the event handler could hold reference count to the new PCI bus when handling BUS_NOTIFY_ADD_DEVICE event. 1) device_initialize(&pci_dev->dev) 2) device_initialize(&pci_dev->subordinate->dev) 3) notify BUS_NOTIFY_ADD_DEVICE event for pci_dev 4) device_add(&pci_dev->dev) 5) device_add(&pci_dev->subordinate->dev) Signed-off-by: Jiang Liu Signed-off-by: Yinghai Lu Acked-by: Rafael J. Wysocki --- drivers/pci/bus.c | 2 +- drivers/pci/probe.c | 4 +++- drivers/pci/remove.c | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index a543746..4c843cd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -193,7 +193,7 @@ int pci_bus_add_child(struct pci_bus *bus) if (bus->bridge) bus->dev.parent = bus->bridge; - retval = device_register(&bus->dev); + retval = device_add(&bus->dev); if (retval) return retval; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ec5d28f..adb77c6 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -639,6 +639,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, */ child->dev.class = &pcibus_class; dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); + device_initialize(&child->dev); /* * Set up the primary, secondary and subordinate @@ -1673,7 +1674,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, b->dev.class = &pcibus_class; b->dev.parent = b->bridge; dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus); - error = device_register(&b->dev); + device_initialize(&b->dev); + error = device_add(&b->dev); if (error) goto class_dev_reg_err; diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 10693f5..0d03026 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -48,11 +48,11 @@ void pci_remove_bus(struct pci_bus *bus) list_del(&bus->node); pci_bus_release_busn_res(bus); up_write(&pci_bus_sem); - if (!bus->is_added) - return; - - pci_remove_legacy_files(bus); - device_unregister(&bus->dev); + if (bus->is_added) { + pci_remove_legacy_files(bus); + device_del(&bus->dev); + } + put_device(&bus->dev); } EXPORT_SYMBOL(pci_remove_bus);