From patchwork Fri Jun 24 14:20:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Suchanek X-Patchwork-Id: 9197607 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 21BDA6088F for ; Fri, 24 Jun 2016 14:21:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F4AC284B0 for ; Fri, 24 Jun 2016 14:21:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EEE6F284BC; Fri, 24 Jun 2016 14:21:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8FBE8284B8 for ; Fri, 24 Jun 2016 14:21:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751450AbcFXOVK (ORCPT ); Fri, 24 Jun 2016 10:21:10 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:35474 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751508AbcFXOVI (ORCPT ); Fri, 24 Jun 2016 10:21:08 -0400 Received: by mail-wm0-f66.google.com with SMTP id a66so5377517wme.2; Fri, 24 Jun 2016 07:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=R6WPOpqP8qcBTQNw75XTkrhP/7Hk+pdDY3bP1kXbwHs=; b=aeASRUiTUmpUlSKAtNyLn4D0uuc7xwIgxNdr3Q2uIUj7Jhcd/AXSQWVlob/vCr7mgA mIA4zzRxqiMXSFQfM2PWcxipdOD1hPgXtW4YDexj/pI+NZkE93qBQhhsbTWnm3rd41xr 83W29DfhWhbcpbCNMBmcGOPIgPSZ16DXC98m/07CI8cK/eJljh6nzjoBeeX/VRyqkxKn YyM8XqTsQN7Nanf8YmIkWemUX2wKPLIyVYCRpp7WCMSd7M44eg+Nt8thuSMkAzGtGtMr 5LZ91AhBWjIyw+cdy9FmLy3aPaeO04ZaCtv0gC7u6OD9TBV021KnTusNFRHg0oEaSPRH EorQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=R6WPOpqP8qcBTQNw75XTkrhP/7Hk+pdDY3bP1kXbwHs=; b=RPmBwsyukZURax0WCUm8jwWuc4HPdpybnL/nIzVWUKX/L4u0kkf00UKjwb//RHETp5 U7FYK67vcPr2RVQlOKUcM3DqH0AY3mX8KXL13gGxhgJZyMrEUHTgnG3O1bvHMPZAtt0W /qltwA2xoWgtNJtcmRxBX/ubtzadwby1U4Tty1r+GvbyLUbCKqdoo0WRgi+0EzoX3OtE TWo64wMCFq5qIWn/JltBoHN0eoaWqIcIBT0mp3lTwCmq4HQkjx3Pkki00yDhnvMGh9h2 f4+2qVF4aG+AC7wipmOrEDbzpgEQsU0qoKII4RVYaGyYt3eIPeSbNr6zOqmXfC8Q1bZF pD9w== X-Gm-Message-State: ALyK8tLUSYv7I3+/myoL44hp9NwFORekfAKcN6Yo5aP/HfP7teQbJhl/zBm89OosUtKGqQ== X-Received: by 10.194.179.38 with SMTP id dd6mr3925245wjc.93.1466778066386; Fri, 24 Jun 2016 07:21:06 -0700 (PDT) Received: from iscsi.burning-in.hell ([179.43.146.230]) by smtp.gmail.com with ESMTPSA id 124sm3369074wml.12.2016.06.24.07.20.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Jun 2016 07:21:05 -0700 (PDT) From: Michal Suchanek To: Greg Kroah-Hartman , Mark Brown , Ingo Molnar , Andrew Morton , Kees Cook , Thomas Gleixner , Dan Williams , Tejun Heo , "Paul E. McKenney" , Davidlohr Bueso , Andrey Ryabinin , Nikolay Aleksandrov , Dmitry Vyukov , Adrien Schildknecht , linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org Cc: Michal Suchanek Subject: [PATCH 3/3] drivers core: allow id match override when manually binding driver Date: Fri, 24 Jun 2016 16:20:34 +0200 Message-Id: <5e0397742f887f656d67bb0d61c8e10782c0e5af.1466696079.git.hramrach@gmail.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This allows binding spidev on any slave device by hand using sysfs without adding superfluous compatibles or any other needless complication. Note that any slave driver that requires configuration will fail to probe anyway. Only a driver that binds to anything can be bound successfully. Signed-off-by: Michal Suchanek --- drivers/base/Kconfig.debug | 14 +++++++++ drivers/base/bus.c | 72 +++++++++++++++++++++++++++++++++++++++++++++- lib/Kconfig.debug | 2 ++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 drivers/base/Kconfig.debug diff --git a/drivers/base/Kconfig.debug b/drivers/base/Kconfig.debug new file mode 100644 index 0000000..e21d3cc --- /dev/null +++ b/drivers/base/Kconfig.debug @@ -0,0 +1,14 @@ +menuconfig DRIVER_MATCH_OVERRIDE + bool "Allow manual driver binding to override id match (DANGEROUS)" + default n + help + When binding a driver manually bypass the check of driver id table + against device id in driver core. This can be useful for development + or on buses that don't provide reliable device identification. + +config DRIVER_MATCH_OVERRIDE_BUSES + string "Specify buses for which id matching will be overridden" + default "spi" + depends on DRIVER_MATCH_OVERRIDE + help + space separated bus names diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 6470eb8..752c2a0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -199,6 +199,73 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, } static DRIVER_ATTR_WO(unbind); +#ifdef CONFIG_DRIVER_MATCH_OVERRIDE_BUSES + +/* nul separated "" terminated strings */ +static const char *driver_override_buses; + +static inline void init_overrides(void) +{ + const char *buses_str = CONFIG_DRIVER_MATCH_OVERRIDE_BUSES; + char *transcript; + int i, len = strlen(buses_str); + + if (!len) + return; + + transcript = kzalloc(len + 1, GFP_KERNEL); + if (!transcript) + return; + driver_override_buses = transcript; + + for (i = 0; i < len; i++) { + + while (buses_str[i] == ' ') + i++; + + if (buses_str[i]) { + const char *name_start = buses_str + i; + const char *name_end = strchrnul(name_start, ' '); + int name_len = name_end - name_start; + + strncpy(transcript, name_start, name_len); + i += name_len; + transcript += name_len; + transcript++; + } + } +} + +static inline bool driver_match_override(struct device_driver *drv, + struct device *dev) +{ + struct bus_type *bus = bus_get(drv->bus); + const char *cmp_name = driver_override_buses; + + while (cmp_name && *cmp_name) { + if (!strcmp(bus->name, cmp_name)) { + pr_notice("Overriding id match on manual driver binding:\n bus: %s driver: %s device: %s\n", + bus->name, drv->name, dev_name(dev)); + return true; + } + cmp_name += strlen(cmp_name); + cmp_name++; + } + + return false; +} + +#else /*CONFIG_DRIVER_MATCH_OVERRIDE_BUSES*/ + +static inline void init_overrides(void) +{} + +static inline bool driver_match_override(struct device_driver *drv, + struct device *dev) +{ return false; } + +#endif + /* * Manually attach a device to a driver. * Note: the driver must want to bind to the device, @@ -212,7 +279,8 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, int err = -ENODEV; dev = bus_find_device_by_name(bus, NULL, buf); - if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { + if (dev && dev->driver == NULL && (driver_match_device(drv, dev) + || driver_match_override(drv, dev))) { if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_lock(dev); @@ -1280,5 +1348,7 @@ int __init buses_init(void) if (!system_kset) return -ENOMEM; + init_overrides(); + return 0; } diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1e9a607..f388212 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2002,3 +2002,5 @@ config IO_STRICT_DEVMEM if the driver using a given range cannot be disabled. If in doubt, say Y. + +source drivers/base/Kconfig.debug