From patchwork Wed Aug 16 16:02:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 9904099 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 1D41B600CA for ; Wed, 16 Aug 2017 16:02:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0E3F328A0D for ; Wed, 16 Aug 2017 16:02:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F3D3D28A16; Wed, 16 Aug 2017 16:02:41 +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_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham 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 374C528A02 for ; Wed, 16 Aug 2017 16:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752130AbdHPQCj (ORCPT ); Wed, 16 Aug 2017 12:02:39 -0400 Received: from heliosphere.sirena.org.uk ([172.104.155.198]:57820 "EHLO heliosphere.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752113AbdHPQCZ (ORCPT ); Wed, 16 Aug 2017 12:02:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sirena.org.uk; s=20170815-heliosphere; h=Date:Message-Id:In-Reply-To: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:References: List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner: List-Archive; bh=o5oD19iz8YZwJGCN78Mv3Wh0GqO6WliXKqMy8rJlOQY=; b=bC0TZBhID8yn /tmX02o0QtMNXSzA12D+XKowm7wCHmWMQcqamnaNPcFpFvsu8swEkdEbKkRiaXc44Mt4nCpFRoVxS ANx/jbrAePcy/Cai1JemfN1EdfwheGw20yCUmcpae0a981Sfg/IedzSSgirg4/vfMXZb4F1bZdvNS IA0S0=; Received: from debutante.sirena.org.uk ([2001:470:1f1d:6b5::3] helo=debutante) by heliosphere.sirena.org.uk with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1di0ly-0004zD-U8; Wed, 16 Aug 2017 16:02:22 +0000 Received: from broonie by debutante with local (Exim 4.89) (envelope-from ) id 1di0ly-0003WF-HD; Wed, 16 Aug 2017 17:02:22 +0100 From: Mark Brown To: Suniel Mahesh Cc: Karthik Tummala , Karthik Tummala , Mark Brown , linux-spi@vger.kernel.org Subject: Applied "spi: Pick spi bus number from Linux idr or spi alias" to the spi tree In-Reply-To: Message-Id: Date: Wed, 16 Aug 2017 17:02:22 +0100 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 The patch spi: Pick spi bus number from Linux idr or spi alias has been applied to the spi tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark From 9b61e302210eba55768962f2f11e96bb508c2408 Mon Sep 17 00:00:00 2001 From: Suniel Mahesh Date: Thu, 3 Aug 2017 10:05:57 +0530 Subject: [PATCH] spi: Pick spi bus number from Linux idr or spi alias Modify existing code, for automatically picking the spi bus number based on Linux idr scheme as mentioned in FIXME. This patch does the following: (a) Remove the now unnecessary code which was allocating bus numbers using ATOMIC_INIT and atomic_dec_return macros. (b) If we have an alias, pick the bus number from alias ID (c) Convert to linux idr interface Signed-off-by: Suniel Mahesh Signed-off-by: Karthik Tummala Tested-by: Karthik Tummala Signed-off-by: Mark Brown --- drivers/spi/spi.c | 71 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index aed78093b130..b851888a0a0b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -40,9 +40,13 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include +#define SPI_DYN_FIRST_BUS_NUM 0 + +static DEFINE_IDR(spi_master_idr); static void spidev_release(struct device *dev) { @@ -420,6 +424,7 @@ static LIST_HEAD(spi_controller_list); /* * Used to protect add/del opertion for board_info list and * spi_controller list, and their matching process + * also used to protect object of type struct idr */ static DEFINE_MUTEX(board_lock); @@ -2051,11 +2056,10 @@ static int of_spi_register_master(struct spi_controller *ctlr) */ int spi_register_controller(struct spi_controller *ctlr) { - static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); struct device *dev = ctlr->dev.parent; struct boardinfo *bi; int status = -ENODEV; - int dynamic = 0; + int id; if (!dev) return -ENODEV; @@ -2071,17 +2075,29 @@ int spi_register_controller(struct spi_controller *ctlr) */ if (ctlr->num_chipselect == 0) return -EINVAL; - - if ((ctlr->bus_num < 0) && ctlr->dev.of_node) - ctlr->bus_num = of_alias_get_id(ctlr->dev.of_node, "spi"); - - /* convention: dynamically assigned bus IDs count down from the max */ + + /* allocate dynamic bus number using Linux idr */ + if ((ctlr->bus_num < 0) && ctlr->dev.of_node) { + id = of_alias_get_id(ctlr->dev.of_node, "spi"); + if (id >= 0) { + ctlr->bus_num = id; + mutex_lock(&board_lock); + id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num, + ctlr->bus_num + 1, GFP_KERNEL); + mutex_unlock(&board_lock); + if (WARN(id < 0, "couldn't get idr")) + return id == -ENOSPC ? -EBUSY : id; + } + } if (ctlr->bus_num < 0) { - /* FIXME switch to an IDR based scheme, something like - * I2C now uses, so we can't run out of "dynamic" IDs - */ - ctlr->bus_num = atomic_dec_return(&dyn_bus_id); - dynamic = 1; + mutex_lock(&board_lock); + id = idr_alloc(&spi_master_idr, ctlr, + SPI_DYN_FIRST_BUS_NUM, 0, GFP_KERNEL); + mutex_unlock(&board_lock); + if (WARN(id < 0, "couldn't get idr")) + return id; + + ctlr->bus_num = id; } INIT_LIST_HEAD(&ctlr->queue); @@ -2099,11 +2115,16 @@ int spi_register_controller(struct spi_controller *ctlr) */ dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); status = device_add(&ctlr->dev); - if (status < 0) + if (status < 0) { + /* free bus id */ + mutex_lock(&board_lock); + idr_remove(&spi_master_idr, ctlr->bus_num); + mutex_unlock(&board_lock); goto done; - dev_dbg(dev, "registered %s %s%s\n", + } + dev_dbg(dev, "registered %s %s\n", spi_controller_is_slave(ctlr) ? "slave" : "master", - dev_name(&ctlr->dev), dynamic ? " (dynamic)" : ""); + dev_name(&ctlr->dev)); /* If we're using a queued driver, start the queue */ if (ctlr->transfer) @@ -2112,6 +2133,10 @@ int spi_register_controller(struct spi_controller *ctlr) status = spi_controller_initialize_queue(ctlr); if (status) { device_del(&ctlr->dev); + /* free bus id */ + mutex_lock(&board_lock); + idr_remove(&spi_master_idr, ctlr->bus_num); + mutex_unlock(&board_lock); goto done; } } @@ -2190,8 +2215,20 @@ static int __unregister(struct device *dev, void *null) */ void spi_unregister_controller(struct spi_controller *ctlr) { + struct spi_controller *found; int dummy; + /* First make sure that this controller was ever added */ + mutex_lock(&board_lock); + found = idr_find(&spi_master_idr, ctlr->bus_num); + mutex_unlock(&board_lock); + if (found != ctlr) { + dev_dbg(&ctlr->dev, + "attempting to delete unregistered controller [%s]\n", + dev_name(&ctlr->dev)); + return; + } + if (ctlr->queued) { if (spi_destroy_queue(ctlr)) dev_err(&ctlr->dev, "queue remove failed\n"); @@ -2203,6 +2240,10 @@ void spi_unregister_controller(struct spi_controller *ctlr) dummy = device_for_each_child(&ctlr->dev, NULL, __unregister); device_unregister(&ctlr->dev); + /* free bus id */ + mutex_lock(&board_lock); + idr_remove(&spi_master_idr, ctlr->bus_num); + mutex_unlock(&board_lock); } EXPORT_SYMBOL_GPL(spi_unregister_controller);