From patchwork Thu Aug 3 04:35:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suniel Mahesh X-Patchwork-Id: 9878133 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 CD45C6037D for ; Thu, 3 Aug 2017 04:36:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BD0C72883F for ; Thu, 3 Aug 2017 04:36:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B1C7028844; Thu, 3 Aug 2017 04:36:22 +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.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, 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 4019E2883F for ; Thu, 3 Aug 2017 04:36:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751262AbdHCEgJ (ORCPT ); Thu, 3 Aug 2017 00:36:09 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:33828 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751241AbdHCEgI (ORCPT ); Thu, 3 Aug 2017 00:36:08 -0400 Received: by mail-pf0-f193.google.com with SMTP id t86so407424pfe.1 for ; Wed, 02 Aug 2017 21:36:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=techveda-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=gbRt8IOnVC7KSnNz5bEROAmhB4wQ54LSy6xD2+ooDa8=; b=GXmstWfU8cE/OfCcI7Y4I8cIfiGvMRv+A9NUdJeL2bCv/nrw1AEWIJwEKWJAViudO9 Zi7p1gYuxLDmqpY2MO4DPuEbg92kyaIS+RFliy+DZXdHunF0vpgFD+K6AXPwzmkyhnwW USqKVZZhC6jqMqFO5OwOD0nasBEpebu/G+K7JsRn7yIcBL0GHoRhDjBJtsfEXi72l+M6 +FWTY2N4t3cZ3dA0HyqLCawjdDZ9prVyBf/Ni8W0M3M1Kq5VmJvJzD8e1M9Ha42bOeL+ 58UYVXuf3uIFWsaANW5WCxEfGAl92x+yw3K4ht05oAKf+rfL/ybDL4njiakNHTXvMzfm 7iZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=gbRt8IOnVC7KSnNz5bEROAmhB4wQ54LSy6xD2+ooDa8=; b=eC5lYbHpw3IgLEC5kiD1EPJBiCVYqYxHFmOYzjIckoK9eh9skbTU9nWkt6kTUh9bW7 Ohx7Saccj5AeBYix+PEzdMPPOTxDPx2FSjTzE4xt9f9msPKDusPMhAMRl2in9p81b8qr aAG0edEMV6Ig+Vs0mSSHccxCL6iqTDYS5Uvugb8XHvvw6AiMg2EsRPdnXMJ6c3TvxBph z/KP0vnhV1zqlF1qFN62j/e3Gdss928XWBAFrezM71GPJsn3SnZu8EblKENcI9CxGINt dPz3JutXvJtJh5cAmfDypjp6x4FOJ6oOuyXmIPikfTYlk6HNdUn6ZsWmc9PMGQO8HfNA zDVA== X-Gm-Message-State: AIVw110RuppJ2zVa0/KxZzXSHDxlVX//u/TuTOfcfkLYtMO6XDup9hwp DDsLCPIvuWHeXXOZ X-Received: by 10.84.238.199 with SMTP id l7mr427812pln.267.1501734967435; Wed, 02 Aug 2017 21:36:07 -0700 (PDT) Received: from localhost.localdomain ([124.123.42.5]) by smtp.gmail.com with ESMTPSA id p10sm13317443pfk.103.2017.08.02.21.36.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 02 Aug 2017 21:36:06 -0700 (PDT) From: sunil.m@techveda.org To: broonie@kernel.org Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, karthik@techveda.org, Suniel Mahesh Subject: [PATCH] drivers: spi: Pick spi bus number from Linux idr or spi alias Date: Thu, 3 Aug 2017 10:05:57 +0530 Message-Id: <1501734957-20725-1-git-send-email-sunil.m@techveda.org> X-Mailer: git-send-email 1.9.1 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 From: Suniel Mahesh 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 macro's. (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 --- Note: - Patch was compile tested and built(ARCH=arm) on next-20170802. - Patch was hardware tested on AM335x (McSPI controller) with memory chips as slaves. - Added spi aliases in aliases node, device tree and tested. - No build/run-time issues reported. --- 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 ec69293..17bec04d 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 @@ struct boardinfo { /* * 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); @@ -2046,11 +2051,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; @@ -2066,17 +2070,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); @@ -2094,11 +2110,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) @@ -2107,6 +2128,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; } } @@ -2185,8 +2210,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"); @@ -2198,6 +2235,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);