Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756363AbbLANfl (ORCPT ); Tue, 1 Dec 2015 08:35:41 -0500 Received: from mailout3.w1.samsung.com ([210.118.77.13]:43225 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756218AbbLANej (ORCPT ); Tue, 1 Dec 2015 08:34:39 -0500 X-AuditID: cbfec7f5-f79b16d000005389-d1-565da1ec1d8a 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 v3 1/3] driver core: handle -EPROBE_DEFER from bus_type.match() Date: Tue, 01 Dec 2015 14:34:24 +0100 Message-id: <1448976866-7892-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 In-reply-to: <1448976866-7892-1-git-send-email-m.szyprowski@samsung.com> References: <1448976866-7892-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrMLMWRmVeSWpSXmKPExsVy+t/xy7pvFsaGGZz7rWWxccZ6VovmxevZ LF6/MLTof/ya2WLT42usFpd3zWGzmHF+H5PF7cu8FmuP3GW36Ft7ic3i+NpwB26PluYeNo8d d5cwemxa1cnmcefaHjaP/XPXsHtsXlLv0bdlFaPH501yARxRXDYpqTmZZalF+nYJXBl7G/ay FExVrDi46gpjA+MlqS5GTg4JAROJm1M+s0PYYhIX7q1n62Lk4hASWMoocfjTNCiniUli1s/T bCBVbAKGEl1vu8BsEYFsifl7u8G6mQW+MEk0bXEDsYUF/CW2ntwHVsMioCrxaMYusBpeAXeJ jsa7zBDb5CT+v1zBBGJzCnhITNtxDqxGCKhm7ZqZrBMYeRcwMqxiFE0tTS4oTkrPNdIrTswt Ls1L10vOz93ECAnKrzsYlx6zOsQowMGoxMMrsTYmTIg1say4MvcQowQHs5IIr3R1bJgQb0pi ZVVqUX58UWlOavEhRmkOFiVx3pm73ocICaQnlqRmp6YWpBbBZJk4OKUaGCtWBM34OMf1S6Lj 3je+ObnT+GuqWV7Kfu9Nf1V8I+Lk6v023J9ePnji88deomyW+E9TkSmczm+vhKmIfDxU6Hu6 uld8X1+ETYVdnndMnhVvdlDJnNpTcTmVB5ktCxc61948YyzFtiyIrT0milWAJaiZR53rktbR RWF33wp6flJ7ZBh/pIFFiaU4I9FQi7moOBEAZc8lJEYCAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4380 Lines: 115 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] Signed-off-by: Marek Szyprowski --- Documentation/driver-model/porting.txt | 6 ++++-- drivers/base/dd.c | 24 ++++++++++++++++++++++-- include/linux/device.h | 2 +- 3 files changed, 27 insertions(+), 5 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..d4e7d1f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -70,7 +70,7 @@ 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 + * is added for this bus. It should return a positive value if the * given device can be handled by the given driver. * @uevent: Called when a device is added, removed, or a few other things * that generate uevents to add the environment variables. -- 1.9.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/