From patchwork Sun Dec 2 15:01:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 1830891 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id D06593FCA5 for ; Sun, 2 Dec 2012 15:02:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752061Ab2LBPCI (ORCPT ); Sun, 2 Dec 2012 10:02:08 -0500 Received: from mail-pb0-f46.google.com ([209.85.160.46]:56131 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751553Ab2LBPCH (ORCPT ); Sun, 2 Dec 2012 10:02:07 -0500 Received: by mail-pb0-f46.google.com with SMTP id wy7so1445313pbc.19 for ; Sun, 02 Dec 2012 07:02:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=ZhZS5fcXwW1IzkEKscT4SbN63O657yroZEnHuON429g=; b=XiAXkJyUSKacBVdoKfKu2CNysqGo/FdjWoo7PBObF23XoeXZF/Ovu9o+bxUvHxYvAf 2wiaEHKIoF0ZiBDB6iXDFgpEqPMCtQkKi0RXCjqxyFNChiWN+El7YDEqTSsT24X6ZUXk JtSEhQe1LsFRG4CUTVPPF+r7BW2qMW3TIGqyGFtO+uW0hJjLUiqPd//AIAyRdzyZzRXN QNlDpkpB0/krmUiFjKCzELifEL8KXcGZup+sRIPH8/c/3VIG5GO0uHED4AfKYJFvC7e+ /ryAeibkXCsLAw6mdjQtEOUeyE76a2J6AChtFLbt8ocmPFEyg351kTAWaC65Ouh751NQ SJMg== Received: by 10.68.137.234 with SMTP id ql10mr21201396pbb.158.1354460526801; Sun, 02 Dec 2012 07:02:06 -0800 (PST) Received: from localhost ([183.37.207.193]) by mx.google.com with ESMTPS id i3sm2224187pav.18.2012.12.02.07.01.56 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 02 Dec 2012 07:02:05 -0800 (PST) From: Ming Lei To: Alan Stern , Greg Kroah-Hartman Cc: Lan Tianyu , Sarah Sharp , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, Oliver Neukum , linux-omap@vger.kernel.org, linux-usb@vger.kernel.org, Ming Lei , Andy Green , Roger Quadros , Felipe Balbi Subject: [RFC PATCH 2/5] driver core: introduce global device ADD/DEL notifier Date: Sun, 2 Dec 2012 23:01:04 +0800 Message-Id: <1354460467-28006-3-git-send-email-tom.leiming@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1354460467-28006-1-git-send-email-tom.leiming@gmail.com> References: <1354460467-28006-1-git-send-email-tom.leiming@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The global device ADD/DEL notifier is introduced so that some platform code can bind some device resource to the device. When this platform code runs, there is no any bus information about the device, so have to resort to the global notifier. Cc: Andy Green Cc: Roger Quadros Cc: Alan Stern Cc: Felipe Balbi Signed-off-by: Ming Lei --- drivers/base/core.c | 21 +++++++++++++++++++++ include/linux/device.h | 13 +++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index a235085..37f11ff 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -43,6 +43,9 @@ static __init int sysfs_deprecated_setup(char *arg) early_param("sysfs.deprecated", sysfs_deprecated_setup); #endif +/* global device nofifier */ +struct blocking_notifier_head dev_notifier; + int (*platform_notify)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL; static struct kobject *dev_kobj; @@ -1041,6 +1044,8 @@ int device_add(struct device *dev) if (platform_notify) platform_notify(dev); + blocking_notifier_call_chain(&dev_notifier, DEV_NOTIFY_ADD_DEVICE, dev); + error = device_create_file(dev, &uevent_attr); if (error) goto attrError; @@ -1228,6 +1233,7 @@ void device_del(struct device *dev) device_pm_remove(dev); driver_deferred_probe_del(dev); + blocking_notifier_call_chain(&dev_notifier, DEV_NOTIFY_DEL_DEVICE, dev); /* Notify the platform of the removal, in case they * need to do anything... */ @@ -1376,6 +1382,8 @@ struct device *device_find_child(struct device *parent, void *data, int __init devices_init(void) { + BLOCKING_INIT_NOTIFIER_HEAD(&dev_notifier); + devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); if (!devices_kset) return -ENOMEM; @@ -1995,6 +2003,19 @@ int dev_printk(const char *level, const struct device *dev, } EXPORT_SYMBOL(dev_printk); +/* The notifier should be avoided as far as possible */ +int dev_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&dev_notifier, nb); +} +EXPORT_SYMBOL_GPL(dev_register_notifier); + +int dev_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&dev_notifier, nb); +} +EXPORT_SYMBOL_GPL(dev_unregister_notifier); + #define define_dev_printk_level(func, kern_level) \ int func(const struct device *dev, const char *fmt, ...) \ { \ diff --git a/include/linux/device.h b/include/linux/device.h index 43dcda9..aeb54f6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -179,6 +179,19 @@ extern int bus_unregister_notifier(struct bus_type *bus, #define BUS_NOTIFY_UNBOUND_DRIVER 0x00000006 /* driver is unbound from the device */ +/* All 2 notifers below get called with the target struct device * + * as an argument. Note that those functions are likely to be called + * with the device lock held in the core, so be careful. + */ +#define DEV_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ +#define DEV_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */ +extern int dev_register_notifier(struct notifier_block *nb); +extern int dev_unregister_notifier(struct notifier_block *nb); + +extern struct kset *bus_get_kset(struct bus_type *bus); +extern struct klist *bus_get_device_klist(struct bus_type *bus); + + extern struct kset *bus_get_kset(struct bus_type *bus); extern struct klist *bus_get_device_klist(struct bus_type *bus);