From patchwork Sun May 3 10:30:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barry Song <21cnbao@gmail.com> X-Patchwork-Id: 6320731 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 06AAC9F374 for ; Sun, 3 May 2015 10:26:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1852B203B8 for ; Sun, 3 May 2015 10:26:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C3C7203C1 for ; Sun, 3 May 2015 10:26:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751169AbbECK0o (ORCPT ); Sun, 3 May 2015 06:26:44 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:35938 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751451AbbECK0n (ORCPT ); Sun, 3 May 2015 06:26:43 -0400 Received: by pabsx10 with SMTP id sx10so135185546pab.3 for ; Sun, 03 May 2015 03:26:43 -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; bh=jEvRwXDu9lbJNkX1E8UZi/7vXZiTOeeKEsNhqKD6ssI=; b=Su6dyfM0TjGakhSY/LG72y4Ztog2Jgu7gLE+suw5COwQ0XW6wiiz5bTRtRRIdD/CH7 2l3JoGnYJ+7qBVxgX/hBHZAdazGQ5m5gNJrPRkWOmrILuaDitPiRQKZEfS0SnUSTaphO Eyvp2zu1La2HgM4FZa8hRSJO+CPepnA6lLQY643myfAu5rZTfEFyJRHCAPCW4WGxNyZM IvhauxWhfaYidpy+is55WPS+731UcWWkmwwot3a4nluZXfA+8GTDtnM2k6DTQ0uO81UU 3aEWEQC0m9X3qjOnTMQbuPCnFmsN6u48UPV6ExFWEf9mPsKZHccRuwCBwMqNteJRmynq XbAg== X-Received: by 10.68.136.42 with SMTP id px10mr33442825pbb.19.1430648803244; Sun, 03 May 2015 03:26:43 -0700 (PDT) Received: from ip-172-31-29-47.ap-northeast-1.compute.internal (ec2-54-65-106-64.ap-northeast-1.compute.amazonaws.com. [54.65.106.64]) by mx.google.com with ESMTPSA id nz7sm4423065pbb.40.2015.05.03.03.26.40 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 03 May 2015 03:26:42 -0700 (PDT) From: Barry Song <21cnbao@gmail.com> To: broonie@kernel.org, linux-spi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, workgroup.linux@csr.com, swingboard@gmail.com, Qipan Li , Barry Song Subject: [PATCH v2] spi: sirf: request and free cs gpio in setup and cleanup callbacks Date: Sun, 3 May 2015 10:30:12 +0000 Message-Id: <1430649012-1694-1-git-send-email-21cnbao@gmail.com> 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-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, 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: Qipan Li move spi controller's gpio request work out from probe() to spi device register stage, so after spi device register spi controller can deactive device's gpio chipselect. old code can't do it because gpio request has not be done until device register is finised in spi_bitbang_start. and add cleanup function to free CS gpio. Signed-off-by: Qipan Li Signed-off-by: Barry Song --- -v2: rebase on v4.1-rc1 drivers/spi/spi-sirf.c | 55 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index a50ee9b..a69ccb7 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -631,14 +631,47 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) static int spi_sirfsoc_setup(struct spi_device *spi) { struct sirfsoc_spi *sspi; + int ret = 0; sspi = spi_master_get_devdata(spi->master); if (spi->cs_gpio == -ENOENT) sspi->hw_cs = true; - else + else { sspi->hw_cs = false; - return spi_sirfsoc_setup_transfer(spi, NULL); + if (!spi_get_ctldata(spi)) { + void *cs = kmalloc(sizeof(int), GFP_KERNEL); + if (!cs) { + ret = -ENOMEM; + goto exit; + } + ret = gpio_is_valid(spi->cs_gpio); + if (!ret) { + dev_err(&spi->dev, "no valid gpio\n"); + ret = -ENOENT; + goto exit; + } + ret = gpio_request(spi->cs_gpio, DRIVER_NAME); + if (ret) { + dev_err(&spi->dev, "failed to request gpio\n"); + goto exit; + } + spi_set_ctldata(spi, cs); + } + } + writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | SIRFSOC_SPI_CS_IO_MODE, + sspi->base + SIRFSOC_SPI_CTRL); + spi_sirfsoc_chipselect(spi, BITBANG_CS_INACTIVE); +exit: + return ret; +} + +static void spi_sirfsoc_cleanup(struct spi_device *spi) +{ + if (spi_get_ctldata(spi)) { + gpio_free(spi->cs_gpio); + kfree(spi_get_ctldata(spi)); + } } static int spi_sirfsoc_probe(struct platform_device *pdev) @@ -647,7 +680,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) struct spi_master *master; struct resource *mem_res; int irq; - int i, ret; + int ret; ret = device_reset(&pdev->dev); if (ret) { @@ -685,6 +718,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer; sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; sspi->bitbang.master->setup = spi_sirfsoc_setup; + sspi->bitbang.master->cleanup = spi_sirfsoc_cleanup; master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) | @@ -733,21 +767,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) ret = spi_bitbang_start(&sspi->bitbang); if (ret) goto free_dummypage; - for (i = 0; master->cs_gpios && i < master->num_chipselect; i++) { - if (master->cs_gpios[i] == -ENOENT) - continue; - if (!gpio_is_valid(master->cs_gpios[i])) { - dev_err(&pdev->dev, "no valid gpio\n"); - ret = -EINVAL; - goto free_dummypage; - } - ret = devm_gpio_request(&pdev->dev, - master->cs_gpios[i], DRIVER_NAME); - if (ret) { - dev_err(&pdev->dev, "failed to request gpio\n"); - goto free_dummypage; - } - } dev_info(&pdev->dev, "registerred, bus number = %d\n", master->bus_num); return 0;