From patchwork Wed Dec 2 07:21:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 7743261 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id EA8EEBEEE1 for ; Wed, 2 Dec 2015 07:22:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E7B90206DB for ; Wed, 2 Dec 2015 07:22:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D5C74206B5 for ; Wed, 2 Dec 2015 07:22:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757484AbbLBHWl (ORCPT ); Wed, 2 Dec 2015 02:22:41 -0500 Received: from mailout4.w1.samsung.com ([210.118.77.14]:10912 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755974AbbLBHVy (ORCPT ); Wed, 2 Dec 2015 02:21:54 -0500 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NYP00AIIZ4GLF90@mailout4.w1.samsung.com>; Wed, 02 Dec 2015 07:21:52 +0000 (GMT) X-AuditID: cbfec7f5-f79b16d000005389-8e-565e9c0f53a1 Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id C9.47.21385.F0C9E565; Wed, 2 Dec 2015 07:21:51 +0000 (GMT) Received: from amdc1339.digital.local ([106.116.147.30]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NYP00M15Z4C9D00@eusync1.samsung.com>; Wed, 02 Dec 2015 07:21:51 +0000 (GMT) From: Marek Szyprowski To: linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Marek Szyprowski , Russell King - ARM Linux , Ulf Hansson , Tomeu Vizoso , Greg Kroah-Hartman , Kukjin Kim , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v4 1/3] driver core: handle -EPROBE_DEFER from bus_type.match() Date: Wed, 02 Dec 2015 08:21:41 +0100 Message-id: <1449040903-26674-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 In-reply-to: <1449040903-26674-1-git-send-email-m.szyprowski@samsung.com> References: <1449040903-26674-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrMLMWRmVeSWpSXmKPExsVy+t/xy7r8c+LCDE7vtbLYOGM9q0Xz4vVs Fq9fGFr0P37NbLHp8TVWi8u75rBZzDi/j8ni9mVei7VH7rJb9K29xGZxfG24A7dHS3MPm8eO u0sYPTat6mTzuHNtD5vH/rlr2D02L6n36NuyitHj8ya5AI4oLpuU1JzMstQifbsEroyZJ6Yx FWxTqTg25xRLA+NC2S5GTg4JAROJlf3tzBC2mMSFe+vZuhi5OIQEljJKXLg8hRnCaWKS+HL8 C1gVm4ChRNfbLjYQW0QgW2L+3m52EJtZ4AuTRNMWNxBbWMBfYtKT3WD1LAKqEu9W7GYCsXkF PCQO7PvHBrFNTuL/yxVgcU4BT4njJ86D2UJANb+Xn2CfwMi7gJFhFaNoamlyQXFSeq6RXnFi bnFpXrpecn7uJkZIUH7dwbj0mNUhRgEORiUe3hU8cWFCrIllxZW5hxglOJiVRHi9ZIBCvCmJ lVWpRfnxRaU5qcWHGKU5WJTEeWfueh8iJJCeWJKanZpakFoEk2Xi4JRqYDyn57NVfTGDfmm8 Lc+yybNmm2vH357/pTaj5at+fnG231Vxq/+eXnu7tI3cRGLvvBd7r//H9FN5ZJlAmc/xhEmX e1U7/1U96jBYUqbe36v7R1JepGxa2LR1UsEXnzy5xt1oqrdxwf+SM9WpOvUOoQnnd9c2/3kU GSsRNufPt/eHriq7yqXcVmIpzkg01GIuKk4EAIyfKt5GAgAA Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tomeu Vizoso Allow implementations of the match() callback in struct bus_type to return errors and if it's -EPROBE_DEFER then queue the device for deferred probing. This is useful to buses such as AMBA in which devices are registered before their matching information can be retrieved from the HW (typically because a clock driver hasn't probed yet). Signed-off-by: Tomeu Vizoso [changed if-else code structure, adjusted documentation to match the code, extended comments] Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson --- Documentation/driver-model/porting.txt | 6 ++++-- drivers/base/dd.c | 24 ++++++++++++++++++++++-- include/linux/device.h | 7 +++++-- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt index 92d86f7..453053f 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.txt @@ -340,8 +340,10 @@ comparison: int (*match)(struct device * dev, struct device_driver * drv); -match should return '1' if the driver supports the device, and '0' -otherwise. +match should return positive value if the driver supports the device, +and zero otherwise. It may also return error code (for example +-EPROBE_DEFER) if determining that given driver supports the device is +not possible. When a device is registered, the bus's list of drivers is iterated over. bus->match() is called for each one until a match is found. diff --git a/drivers/base/dd.c b/drivers/base/dd.c index a641cf3..793e915 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -490,6 +490,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) struct device_attach_data *data = _data; struct device *dev = data->dev; bool async_allowed; + int ret; /* * Check if device has already been claimed. This may @@ -500,8 +501,17 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) if (dev->driver) return -EBUSY; - if (!driver_match_device(drv, dev)) + ret = driver_match_device(drv, dev); + if (ret == 0) { + /* no match */ return 0; + } else if (ret == -EPROBE_DEFER) { + dev_dbg(dev, "Device match requests probe deferral\n"); + driver_deferred_probe_add(dev); + } else if (ret < 0) { + dev_dbg(dev, "Bus failed to match device: %d", ret); + return ret; + } /* ret > 0 means positive match */ async_allowed = driver_allows_async_probing(drv); @@ -621,6 +631,7 @@ void device_initial_probe(struct device *dev) static int __driver_attach(struct device *dev, void *data) { struct device_driver *drv = data; + int ret; /* * Lock device and try to bind to it. We drop the error @@ -632,8 +643,17 @@ static int __driver_attach(struct device *dev, void *data) * is an error. */ - if (!driver_match_device(drv, dev)) + ret = driver_match_device(drv, dev); + if (ret == 0) { + /* no match */ return 0; + } else if (ret == -EPROBE_DEFER) { + dev_dbg(dev, "Device match requests probe deferral\n"); + driver_deferred_probe_add(dev); + } else if (ret < 0) { + dev_dbg(dev, "Bus failed to match device: %d", ret); + return ret; + } /* ret > 0 means positive match */ if (dev->parent) /* Needed for USB */ device_lock(dev->parent); diff --git a/include/linux/device.h b/include/linux/device.h index b8f411b..69bea82 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -70,8 +70,11 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * @dev_groups: Default attributes of the devices on the bus. * @drv_groups: Default attributes of the device drivers on the bus. * @match: Called, perhaps multiple times, whenever a new device or driver - * is added for this bus. It should return a nonzero value if the - * given device can be handled by the given driver. + * is added for this bus. It should return a positive value if the + * given device can be handled by the given driver and zero + * otherwise. It may also return error code if determining that + * the driver supports the device is not possible. In case of + * -EPROBE_DEFER it will queue the device for deferred probing. * @uevent: Called when a device is added, removed, or a few other things * that generate uevents to add the environment variables. * @probe: Called when a new device or driver add to this bus, and callback