From patchwork Tue Aug 21 16:01:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roland Stigge X-Patchwork-Id: 1356311 Return-Path: X-Original-To: patchwork-spi-devel-general@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by patchwork2.kernel.org (Postfix) with ESMTP id 567BCDFB34 for ; Tue, 21 Aug 2012 16:01:47 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=sfs-ml-1.v29.ch3.sourceforge.com) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1T3qtn-0002un-2B; Tue, 21 Aug 2012 16:01:47 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1T3qtl-0002ua-Vl for spi-devel-general@lists.sourceforge.net; Tue, 21 Aug 2012 16:01:45 +0000 X-ACL-Warn: Received: from mail.work-microwave.de ([62.245.205.51] helo=work-microwave.de) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1T3qtk-00055a-Un for spi-devel-general@lists.sourceforge.net; Tue, 21 Aug 2012 16:01:45 +0000 Received: from rst-pc1.lan.work-microwave.de ([192.168.11.78]) (authenticated bits=0) by mail.work-microwave.de with ESMTP id q7LG1R7i011891 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 21 Aug 2012 17:01:28 +0100 Received: by rst-pc1.lan.work-microwave.de (Postfix, from userid 1000) id 360B5AE0A2; Tue, 21 Aug 2012 18:01:27 +0200 (CEST) From: Roland Stigge To: linus.walleij@linaro.org, aletes.xgr@gmail.com, broonie@opensource.wolfsonmicro.com, grant.likely@secretlab.ca, rob.herring@calxeda.com, rob@landley.net, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, spi-devel-general@lists.sourceforge.net, gabriel.fernandez@stericsson.com, lee.jones@linaro.org, viresh.kumar@linaro.org, sachin.verma@st.co Subject: [PATCH v5 2/2] spi/pl022: Add devicetree support Date: Tue, 21 Aug 2012 18:01:25 +0200 Message-Id: <1345564885-11970-1-git-send-email-stigge@antcom.de> X-Mailer: git-send-email 1.7.10.4 X-FEAS-SYSTEM-WL: rst@work-microwave.de, 192.168.11.78 X-Spam-Score: -0.1 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.2 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain 0.2 AWL AWL: From: address is in the auto white-list X-Headers-End: 1T3qtk-00055a-Un Cc: Roland Stigge X-BeenThere: spi-devel-general@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux SPI core/device drivers discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: spi-devel-general-bounces@lists.sourceforge.net This patch adds device tree support to the spi-pl022 driver. Based on the initial patch by Alexandre Pereira da Silva Signed-off-by: Roland Stigge Acked-By: Alexandre Pereira da Silva --- Documentation/devicetree/bindings/spi/spi_pl022.txt | 15 +++ drivers/spi/spi-pl022.c | 79 +++++++++++++++++--- 2 files changed, 85 insertions(+), 9 deletions(-) ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ --- linux-2.6.orig/Documentation/devicetree/bindings/spi/spi_pl022.txt +++ linux-2.6/Documentation/devicetree/bindings/spi/spi_pl022.txt @@ -6,7 +6,22 @@ Required properties: - interrupts : Should contain SPI controller interrupt Optional properties: +- num-cs : total number of chipselects - cs-gpios : should specify GPIOs used for chipselects. The gpios will be referred to as reg = in the SPI child nodes. If unspecified, a single SPI device without a chip select can be used. +SPI slave nodes must be children of the SPI master node and can +contain the following properties. + +- pl022,interface : interface type: + 0: SPI + 1: Texas Instruments Synchronous Serial Frame Format + 2: Microwire (Half Duplex) +- pl022,com-mode : polling, interrupt or dma +- pl022,rx-level-trig : Rx FIFO watermark level +- pl022,tx-level-trig : Tx FIFO watermark level +- pl022,ctrl-len : Microwire interface: Control length +- pl022,wait-state : Microwire interface: Wait state +- pl022,duplex : Microwire interface: Full/Half duplex + --- linux-2.6.orig/drivers/spi/spi-pl022.c +++ linux-2.6/drivers/spi/spi-pl022.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * This macro is used to define some register default values. @@ -1778,12 +1779,14 @@ static const struct pl022_config_chip pl static int pl022_setup(struct spi_device *spi) { struct pl022_config_chip const *chip_info; + struct pl022_config_chip chip_info_dt; struct chip_data *chip; struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0}; int status = 0; struct pl022 *pl022 = spi_master_get_devdata(spi->master); unsigned int bits = spi->bits_per_word; u32 tmp; + struct device_node *np = spi->dev.of_node; if (!spi->max_speed_hz) return -EINVAL; @@ -1806,10 +1809,32 @@ static int pl022_setup(struct spi_device chip_info = spi->controller_data; if (chip_info == NULL) { - chip_info = &pl022_default_chip_info; - /* spi_board_info.controller_data not is supplied */ - dev_dbg(&spi->dev, - "using default controller_data settings\n"); + if (np) { + chip_info_dt = pl022_default_chip_info; + + chip_info_dt.hierarchy = SSP_MASTER; + of_property_read_u32(np, "pl022,interface", + &chip_info_dt.iface); + of_property_read_u32(np, "pl022,com-mode", + &chip_info_dt.com_mode); + of_property_read_u32(np, "pl022,rx-level-trig", + &chip_info_dt.rx_lev_trig); + of_property_read_u32(np, "pl022,tx-level-trig", + &chip_info_dt.tx_lev_trig); + of_property_read_u32(np, "pl022,ctrl-len", + &chip_info_dt.ctrl_len); + of_property_read_u32(np, "pl022,wait-state", + &chip_info_dt.wait_state); + of_property_read_u32(np, "pl022,duplex", + &chip_info_dt.duplex); + + chip_info = &chip_info_dt; + } else { + chip_info = &pl022_default_chip_info; + /* spi_board_info.controller_data not is supplied */ + dev_dbg(&spi->dev, + "using default controller_data settings\n"); + } } else dev_dbg(&spi->dev, "using user supplied controller_data settings\n"); @@ -2006,7 +2031,8 @@ pl022_probe(struct amba_device *adev, co struct pl022_ssp_controller *platform_info = adev->dev.platform_data; struct spi_master *master; struct pl022 *pl022 = NULL; /*Data for this driver */ - int status = 0, i; + struct device_node *np = adev->dev.of_node; + int status = 0, i, num_cs; dev_info(&adev->dev, "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); @@ -2016,9 +2042,19 @@ pl022_probe(struct amba_device *adev, co goto err_no_pdata; } + if (platform_info->num_chipselect) { + num_cs = platform_info->num_chipselect; + } else if (IS_ENABLED(CONFIG_OF)) { + of_property_read_u32(np, "num-cs", &num_cs); + } else { + dev_err(&adev->dev, "probe: no chip select defined\n"); + status = -ENODEV; + goto err_no_pdata; + } + /* Allocate master with space for data */ master = spi_alloc_master(dev, sizeof(struct pl022) + sizeof(int) * - platform_info->num_chipselect); + num_cs); if (master == NULL) { dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); status = -ENOMEM; @@ -2037,17 +2073,41 @@ pl022_probe(struct amba_device *adev, co * on this board */ master->bus_num = platform_info->bus_id; - master->num_chipselect = platform_info->num_chipselect; + master->num_chipselect = num_cs; master->cleanup = pl022_cleanup; master->setup = pl022_setup; master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; master->transfer_one_message = pl022_transfer_one_message; master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; master->rt = platform_info->rt; + master->dev.of_node = dev->of_node; - if (platform_info->num_chipselect && platform_info->chipselects) - for (i = 0; i < platform_info->num_chipselect; i++) + if (platform_info->num_chipselect && platform_info->chipselects) { + for (i = 0; i < num_cs; i++) pl022->chipselect[i] = platform_info->chipselects[i]; + } else if (IS_ENABLED(CONFIG_OF)) { + for (i = 0; i < num_cs; i++) { + int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); + + if (cs_gpio == -EPROBE_DEFER) { + status = -EPROBE_DEFER; + goto err_no_gpio; + } + + pl022->chipselect[i] = cs_gpio; + + if (gpio_is_valid(cs_gpio)) { + if (gpio_request(cs_gpio, "ssp-pl022")) + dev_err(&adev->dev, + "could not request %d gpio\n", + cs_gpio); + else if (gpio_direction_output(cs_gpio, 1)) + dev_err(&adev->dev, + "could set gpio %d as output\n", + cs_gpio); + } + } + } /* * Supports mode 0-3, loopback, and active low CS. Transfers are @@ -2157,6 +2217,7 @@ pl022_probe(struct amba_device *adev, co err_no_ioremap: amba_release_regions(adev); err_no_ioregion: + err_no_gpio: spi_master_put(master); err_no_master: err_no_pdata: