]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
spi: oc-tiny: Use GPIO descriptors
authorLinus Walleij <linus.walleij@linaro.org>
Thu, 5 Dec 2019 09:24:11 +0000 (10:24 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 27 Dec 2019 01:08:11 +0000 (01:08 +0000)
Switch the OC Tiny driver over to handling CS GPIOs using
GPIO descriptors in the core.

This driver is entirely relying on GPIOs to be used for
chipselect, so let the core pick these out using either
device tree or machine descriptors.

There are no in-tree users of this driver so no board files
need to be patched, out-of-tree boardfiles can use machine
descriptor tables, c.f. commit 1dfbf334f123.

Cc: Thomas Chou <thomas@wytron.com.tw>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20191205092411.64341-1-linus.walleij@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-oc-tiny.c
include/linux/spi/spi_oc_tiny.h

index e2331eb7b47a515ca12387782e417620461ab1af..9df7c5979c299efe2d8a4efc9709af7d2f714e64 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/spi/spi_bitbang.h>
 #include <linux/spi/spi_oc_tiny.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
 #include <linux/of.h>
 
 #define DRV_NAME "spi_oc_tiny"
@@ -50,8 +49,6 @@ struct tiny_spi {
        unsigned int txc, rxc;
        const u8 *txp;
        u8 *rxp;
-       int gpio_cs_count;
-       int *gpio_cs;
 };
 
 static inline struct tiny_spi *tiny_spi_to_hw(struct spi_device *sdev)
@@ -66,16 +63,6 @@ static unsigned int tiny_spi_baud(struct spi_device *spi, unsigned int hz)
        return min(DIV_ROUND_UP(hw->freq, hz * 2), (1U << hw->baudwidth)) - 1;
 }
 
-static void tiny_spi_chipselect(struct spi_device *spi, int is_active)
-{
-       struct tiny_spi *hw = tiny_spi_to_hw(spi);
-
-       if (hw->gpio_cs_count > 0) {
-               gpio_set_value(hw->gpio_cs[spi->chip_select],
-                       (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
-       }
-}
-
 static int tiny_spi_setup_transfer(struct spi_device *spi,
                                   struct spi_transfer *t)
 {
@@ -203,24 +190,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
 {
        struct tiny_spi *hw = platform_get_drvdata(pdev);
        struct device_node *np = pdev->dev.of_node;
-       unsigned int i;
        u32 val;
 
        if (!np)
                return 0;
-       hw->gpio_cs_count = of_gpio_count(np);
-       if (hw->gpio_cs_count > 0) {
-               hw->gpio_cs = devm_kcalloc(&pdev->dev,
-                               hw->gpio_cs_count, sizeof(unsigned int),
-                               GFP_KERNEL);
-               if (!hw->gpio_cs)
-                       return -ENOMEM;
-       }
-       for (i = 0; i < hw->gpio_cs_count; i++) {
-               hw->gpio_cs[i] = of_get_gpio_flags(np, i, NULL);
-               if (hw->gpio_cs[i] < 0)
-                       return -ENODEV;
-       }
        hw->bitbang.master->dev.of_node = pdev->dev.of_node;
        if (!of_property_read_u32(np, "clock-frequency", &val))
                hw->freq = val;
@@ -240,7 +213,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
        struct tiny_spi_platform_data *platp = dev_get_platdata(&pdev->dev);
        struct tiny_spi *hw;
        struct spi_master *master;
-       unsigned int i;
        int err = -ENODEV;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct tiny_spi));
@@ -249,9 +221,9 @@ static int tiny_spi_probe(struct platform_device *pdev)
 
        /* setup the master state. */
        master->bus_num = pdev->id;
-       master->num_chipselect = 255;
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
        master->setup = tiny_spi_setup;
+       master->use_gpio_descriptors = true;
 
        hw = spi_master_get_devdata(master);
        platform_set_drvdata(pdev, hw);
@@ -259,7 +231,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
        /* setup the state for the bitbang driver */
        hw->bitbang.master = master;
        hw->bitbang.setup_transfer = tiny_spi_setup_transfer;
-       hw->bitbang.chipselect = tiny_spi_chipselect;
        hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs;
 
        /* find and map our resources */
@@ -279,12 +250,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
        }
        /* find platform data */
        if (platp) {
-               hw->gpio_cs_count = platp->gpio_cs_count;
-               hw->gpio_cs = platp->gpio_cs;
-               if (platp->gpio_cs_count && !platp->gpio_cs) {
-                       err = -EBUSY;
-                       goto exit;
-               }
                hw->freq = platp->freq;
                hw->baudwidth = platp->baudwidth;
        } else {
@@ -292,13 +257,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
                if (err)
                        goto exit;
        }
-       for (i = 0; i < hw->gpio_cs_count; i++) {
-               err = gpio_request(hw->gpio_cs[i], dev_name(&pdev->dev));
-               if (err)
-                       goto exit_gpio;
-               gpio_direction_output(hw->gpio_cs[i], 1);
-       }
-       hw->bitbang.master->num_chipselect = max(1, hw->gpio_cs_count);
 
        /* register our spi controller */
        err = spi_bitbang_start(&hw->bitbang);
@@ -308,9 +266,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
 
        return 0;
 
-exit_gpio:
-       while (i-- > 0)
-               gpio_free(hw->gpio_cs[i]);
 exit:
        spi_master_put(master);
        return err;
@@ -320,11 +275,8 @@ static int tiny_spi_remove(struct platform_device *pdev)
 {
        struct tiny_spi *hw = platform_get_drvdata(pdev);
        struct spi_master *master = hw->bitbang.master;
-       unsigned int i;
 
        spi_bitbang_stop(&hw->bitbang);
-       for (i = 0; i < hw->gpio_cs_count; i++)
-               gpio_free(hw->gpio_cs[i]);
        spi_master_put(master);
        return 0;
 }
index a3ecf2feadf20402e00f88b1634dbfd34497ad4f..284872ac130c0b806d658e21175dfae61ed5c0ca 100644 (file)
@@ -6,16 +6,12 @@
  * struct tiny_spi_platform_data - platform data of the OpenCores tiny SPI
  * @freq:      input clock freq to the core.
  * @baudwidth: baud rate divider width of the core.
- * @gpio_cs_count:     number of gpio pins used for chipselect.
- * @gpio_cs:   array of gpio pins used for chipselect.
  *
  * freq and baudwidth are used only if the divider is programmable.
  */
 struct tiny_spi_platform_data {
        unsigned int freq;
        unsigned int baudwidth;
-       unsigned int gpio_cs_count;
-       int *gpio_cs;
 };
 
 #endif /* _LINUX_SPI_SPI_OC_TINY_H */