devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 2/2] spi/pl022: Add devicetree support
@ 2012-08-21 16:01 Roland Stigge
  2012-08-21 16:12 ` Alexandre Pereira da Silva
  2012-08-22 11:15 ` Linus Walleij
  0 siblings, 2 replies; 3+ messages in thread
From: Roland Stigge @ 2012-08-21 16:01 UTC (permalink / raw)
  To: linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	aletes.xgr-Re5JQEeQqe8AvxtiuMwx3w,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, rob-VoJi6FS/r0vR7s880joybQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	gabriel.fernandez-0IS4wlFg1OjSUeElwK9/Pw,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	viresh.kumar-QSEj5FYQhm4dnm+yROfE0A, sachin.verma-lpHj6iFQ3dU
  Cc: Roland Stigge

This patch adds device tree support to the spi-pl022 driver.

Based on the initial patch by Alexandre Pereira da Silva <aletes.xgr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Signed-off-by: Roland Stigge <stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
---

 Documentation/devicetree/bindings/spi/spi_pl022.txt |   15 +++
 drivers/spi/spi-pl022.c                             |   79 +++++++++++++++++---
 2 files changed, 85 insertions(+), 9 deletions(-)

--- 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 = <index> 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 <linux/scatterlist.h>
 #include <linux/pm_runtime.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 /*
  * 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:

------------------------------------------------------------------------------
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/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v5 2/2] spi/pl022: Add devicetree support
  2012-08-21 16:01 [PATCH v5 2/2] spi/pl022: Add devicetree support Roland Stigge
@ 2012-08-21 16:12 ` Alexandre Pereira da Silva
  2012-08-22 11:15 ` Linus Walleij
  1 sibling, 0 replies; 3+ messages in thread
From: Alexandre Pereira da Silva @ 2012-08-21 16:12 UTC (permalink / raw)
  To: Roland Stigge
  Cc: linus.walleij, broonie, grant.likely, rob.herring, rob,
	devicetree-discuss, linux-doc, linux-kernel, spi-devel-general,
	gabriel.fernandez, lee.jones, viresh.kumar, sachin.verma

On Tue, Aug 21, 2012 at 1:01 PM, Roland Stigge <stigge@antcom.de> wrote:
> This patch adds device tree support to the spi-pl022 driver.
>
> Based on the initial patch by Alexandre Pereira da Silva <aletes.xgr@gmail.com>
>
> Signed-off-by: Roland Stigge <stigge@antcom.de>

Acked-By: Alexandre Pereira da Silva <aletes.xgr@gmail.com>

> ---
>
>  Documentation/devicetree/bindings/spi/spi_pl022.txt |   15 +++
>  drivers/spi/spi-pl022.c                             |   79 +++++++++++++++++---
>  2 files changed, 85 insertions(+), 9 deletions(-)
>
> --- 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 = <index> 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 <linux/scatterlist.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/gpio.h>
> +#include <linux/of_gpio.h>
>
>  /*
>   * 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:

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v5 2/2] spi/pl022: Add devicetree support
  2012-08-21 16:01 [PATCH v5 2/2] spi/pl022: Add devicetree support Roland Stigge
  2012-08-21 16:12 ` Alexandre Pereira da Silva
@ 2012-08-22 11:15 ` Linus Walleij
  1 sibling, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2012-08-22 11:15 UTC (permalink / raw)
  To: Roland Stigge
  Cc: aletes.xgr, broonie, grant.likely, rob.herring, rob,
	devicetree-discuss, linux-doc, linux-kernel, spi-devel-general,
	gabriel.fernandez, lee.jones, viresh.kumar, sachin.verma

On Tue, Aug 21, 2012 at 6:01 PM, Roland Stigge <stigge@antcom.de> wrote:

> This patch adds device tree support to the spi-pl022 driver.
(...)

> --- 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

I don't know if it's proper to duplicate but atleast *also* patch
Documentation/devicetree/bindings/gpio/gpio.txt to indicate that
this is a generic property on all GPIO drivers.

The rest looks good.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-08-22 11:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-21 16:01 [PATCH v5 2/2] spi/pl022: Add devicetree support Roland Stigge
2012-08-21 16:12 ` Alexandre Pereira da Silva
2012-08-22 11:15 ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).