aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/spi
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2019-01-07 16:51:50 +0100
committerMark Brown <broonie@kernel.org>2019-01-09 12:39:25 +0000
commitf3186dd876697e696d07136623d5cf0a6fb0bc0f (patch)
treecbce9c9f8eb45c0e0fc1f34c8691b6006150e47b /include/linux/spi
parentspi/trace: include buffer contents in traces (diff)
downloadlinux-dev-f3186dd876697e696d07136623d5cf0a6fb0bc0f.tar.xz
linux-dev-f3186dd876697e696d07136623d5cf0a6fb0bc0f.zip
spi: Optionally use GPIO descriptors for CS GPIOs
This augments the SPI core to optionally use GPIO descriptors for chip select on a per-master-driver opt-in basis. Drivers using this will rely on the SPI core to look up GPIO descriptors associated with the device, such as when using device tree or board files with GPIO descriptor tables. When getting descriptors from the device tree, this will in turn activate the code in gpiolib that was added in commit 6953c57ab172 ("gpio: of: Handle SPI chipselect legacy bindings") which means that these descriptors are aware of the active low semantics that is the default for SPI CS GPIO lines and we can assume that all of these are "active high" and thus assign SPI_CS_HIGH to all CS lines on the DT path. The previously used gpio_set_value() would call down into gpiod_set_raw_value() and ignore the polarity inversion semantics. It seems like many drivers go to great lengths to set up the CS GPIO line as non-asserted, respecting SPI_CS_HIGH. We pull this out of the SPI drivers and into the core, and by simply requesting the line as GPIOD_OUT_LOW when retrieveing it from the device and relying on the gpiolib to handle any inversion semantics. This way a lot of code can be simplified and removed in each converted driver. The end goal after dealing with each driver in turn, is to delete the non-descriptor path (of_spi_register_master() for example) and let the core deal with only descriptors. The different SPI drivers have complex interactions with the core so we cannot simply change them all over, we need to use a stepwise, bisectable approach so that each driver can be converted and fixed in isolation. This patch has the intended side effect of adding support for ACPI GPIOs as it starts relying on gpiod_get_*() to get the GPIO handle associated with the device. Cc: Linuxarm <linuxarm@huawei.com> Acked-by: Jonathan Cameron <jonathan.cameron@huawei.com> Tested-by: Fangjian (Turing) <f.fangjian@huawei.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'include/linux/spi')
-rw-r--r--include/linux/spi/spi.h23
1 files changed, 19 insertions, 4 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 314d922ca607..916bba47d156 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -12,6 +12,7 @@
#include <linux/kthread.h>
#include <linux/completion.h>
#include <linux/scatterlist.h>
+#include <linux/gpio/consumer.h>
struct dma_chan;
struct property_entry;
@@ -116,7 +117,10 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
* @modalias: Name of the driver to use with this device, or an alias
* for that name. This appears in the sysfs "modalias" attribute
* for driver coldplugging, and in uevents used for hotplugging
- * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when
+ * @cs_gpio: LEGACY: gpio number of the chipselect line (optional, -ENOENT when
+ * not using a GPIO line) use cs_gpiod in new drivers by opting in on
+ * the spi_master.
+ * @cs_gpiod: gpio descriptor of the chipselect line (optional, NULL when
* not using a GPIO line)
*
* @statistics: statistics for the spi_device
@@ -163,7 +167,8 @@ struct spi_device {
void *controller_data;
char modalias[SPI_NAME_SIZE];
const char *driver_override;
- int cs_gpio; /* chip select gpio */
+ int cs_gpio; /* LEGACY: chip select gpio */
+ struct gpio_desc *cs_gpiod; /* chip select gpio desc */
/* the statistics */
struct spi_statistics statistics;
@@ -376,9 +381,17 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* controller has native support for memory like operations.
* @unprepare_message: undo any work done by prepare_message().
* @slave_abort: abort the ongoing transfer request on an SPI slave controller
- * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
- * number. Any individual value may be -ENOENT for CS lines that
+ * @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per
+ * CS number. Any individual value may be -ENOENT for CS lines that
+ * are not GPIOs (driven by the SPI controller itself). Use the cs_gpiods
+ * in new drivers.
+ * @cs_gpiods: Array of GPIO descs to use as chip select lines; one per CS
+ * number. Any individual value may be NULL for CS lines that
* are not GPIOs (driven by the SPI controller itself).
+ * @use_gpio_descriptors: Turns on the code in the SPI core to parse and grab
+ * GPIO descriptors rather than using global GPIO numbers grabbed by the
+ * driver. This will fill in @cs_gpiods and @cs_gpios should not be used,
+ * and SPI devices will have the cs_gpiod assigned rather than cs_gpio.
* @statistics: statistics for the spi_controller
* @dma_tx: DMA transmit channel
* @dma_rx: DMA receive channel
@@ -557,6 +570,8 @@ struct spi_controller {
/* gpio chip select */
int *cs_gpios;
+ struct gpio_desc **cs_gpiods;
+ bool use_gpio_descriptors;
/* statistics */
struct spi_statistics statistics;