Commit f48dc6b9 authored by Linus Walleij's avatar Linus Walleij Committed by Mark Brown

spi: Retire legacy GPIO handling

All drivers using GPIOs as chip select have been rewritten to use
GPIO descriptors passing the ->use_gpio_descriptors flag. Retire
the code and fields used by the legacy GPIO API.

Do not drop the ->use_gpio_descriptors flag: it now only indicates
that we want to use GPIOs in addition to native chip selects.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20220210231954.807904-1-linus.walleij@linaro.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5790597d
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h> #include <linux/spi/spi-mem.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
...@@ -542,7 +541,6 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr) ...@@ -542,7 +541,6 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr)
spi->dev.parent = &ctlr->dev; spi->dev.parent = &ctlr->dev;
spi->dev.bus = &spi_bus_type; spi->dev.bus = &spi_bus_type;
spi->dev.release = spidev_release; spi->dev.release = spidev_release;
spi->cs_gpio = -ENOENT;
spi->mode = ctlr->buswidth_override_bits; spi->mode = ctlr->buswidth_override_bits;
spin_lock_init(&spi->statistics.lock); spin_lock_init(&spi->statistics.lock);
...@@ -606,11 +604,8 @@ static int __spi_add_device(struct spi_device *spi) ...@@ -606,11 +604,8 @@ static int __spi_add_device(struct spi_device *spi)
return -ENODEV; return -ENODEV;
} }
/* Descriptors take precedence */
if (ctlr->cs_gpiods) if (ctlr->cs_gpiods)
spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select]; spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
else if (ctlr->cs_gpios)
spi->cs_gpio = ctlr->cs_gpios[spi->chip_select];
/* /*
* Drivers may modify this initial i/o setup, but will * Drivers may modify this initial i/o setup, but will
...@@ -940,17 +935,15 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) ...@@ -940,17 +935,15 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
spi->controller->last_cs_enable = enable; spi->controller->last_cs_enable = enable;
spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) {
!spi->controller->set_cs_timing) && !activate) {
spi_delay_exec(&spi->cs_hold, NULL); spi_delay_exec(&spi->cs_hold, NULL);
} }
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
enable = !enable; enable = !enable;
if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) {
if (!(spi->mode & SPI_NO_CS)) {
if (spi->cs_gpiod) { if (spi->cs_gpiod) {
if (!(spi->mode & SPI_NO_CS)) {
/* /*
* Historically ACPI has no means of the GPIO polarity and * Historically ACPI has no means of the GPIO polarity and
* thus the SPISerialBus() resource defines it on the per-chip * thus the SPISerialBus() resource defines it on the per-chip
...@@ -966,13 +959,6 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) ...@@ -966,13 +959,6 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
else else
/* Polarity handled by GPIO library */ /* Polarity handled by GPIO library */
gpiod_set_value_cansleep(spi->cs_gpiod, activate); gpiod_set_value_cansleep(spi->cs_gpiod, activate);
} else {
/*
* Invert the enable line, as active low is
* default for SPI.
*/
gpio_set_value_cansleep(spi->cs_gpio, !enable);
}
} }
/* Some SPI masters need both GPIO CS & slave_select */ /* Some SPI masters need both GPIO CS & slave_select */
if ((spi->controller->flags & SPI_MASTER_GPIO_SS) && if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
...@@ -982,8 +968,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) ...@@ -982,8 +968,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
spi->controller->set_cs(spi, !enable); spi->controller->set_cs(spi, !enable);
} }
if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || if (spi->cs_gpiod || !spi->controller->set_cs_timing) {
!spi->controller->set_cs_timing) {
if (activate) if (activate)
spi_delay_exec(&spi->cs_setup, NULL); spi_delay_exec(&spi->cs_setup, NULL);
else else
...@@ -2827,46 +2812,6 @@ struct spi_controller *__devm_spi_alloc_controller(struct device *dev, ...@@ -2827,46 +2812,6 @@ struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
} }
EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller); EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller);
#ifdef CONFIG_OF
static int of_spi_get_gpio_numbers(struct spi_controller *ctlr)
{
int nb, i, *cs;
struct device_node *np = ctlr->dev.of_node;
if (!np)
return 0;
nb = of_gpio_named_count(np, "cs-gpios");
ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect);
/* Return error only for an incorrectly formed cs-gpios property */
if (nb == 0 || nb == -ENOENT)
return 0;
else if (nb < 0)
return nb;
cs = devm_kcalloc(&ctlr->dev, ctlr->num_chipselect, sizeof(int),
GFP_KERNEL);
ctlr->cs_gpios = cs;
if (!ctlr->cs_gpios)
return -ENOMEM;
for (i = 0; i < ctlr->num_chipselect; i++)
cs[i] = -ENOENT;
for (i = 0; i < nb; i++)
cs[i] = of_get_named_gpio(np, "cs-gpios", i);
return 0;
}
#else
static int of_spi_get_gpio_numbers(struct spi_controller *ctlr)
{
return 0;
}
#endif
/** /**
* spi_get_gpio_descs() - grab chip select GPIOs for the master * spi_get_gpio_descs() - grab chip select GPIOs for the master
* @ctlr: The SPI master to grab GPIO descriptors for * @ctlr: The SPI master to grab GPIO descriptors for
...@@ -3051,8 +2996,7 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -3051,8 +2996,7 @@ int spi_register_controller(struct spi_controller *ctlr)
*/ */
dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num);
if (!spi_controller_is_slave(ctlr)) { if (!spi_controller_is_slave(ctlr) && ctlr->use_gpio_descriptors) {
if (ctlr->use_gpio_descriptors) {
status = spi_get_gpio_descs(ctlr); status = spi_get_gpio_descs(ctlr);
if (status) if (status)
goto free_bus_id; goto free_bus_id;
...@@ -3061,12 +3005,6 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -3061,12 +3005,6 @@ int spi_register_controller(struct spi_controller *ctlr)
* supports SPI_CS_HIGH if need be. * supports SPI_CS_HIGH if need be.
*/ */
ctlr->mode_bits |= SPI_CS_HIGH; ctlr->mode_bits |= SPI_CS_HIGH;
} else {
/* Legacy code path for GPIOs from DT */
status = of_spi_get_gpio_numbers(ctlr);
if (status)
goto free_bus_id;
}
} }
/* /*
...@@ -3555,12 +3493,6 @@ int spi_setup(struct spi_device *spi) ...@@ -3555,12 +3493,6 @@ int spi_setup(struct spi_device *spi)
*/ */
bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD | bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD |
SPI_NO_TX | SPI_NO_RX); SPI_NO_TX | SPI_NO_RX);
/*
* Nothing prevents from working with active-high CS in case if it
* is driven by GPIO.
*/
if (gpio_is_valid(spi->cs_gpio))
bad_bits &= ~SPI_CS_HIGH;
ugly_bits = bad_bits & ugly_bits = bad_bits &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL |
SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL); SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL);
...@@ -3686,8 +3618,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) ...@@ -3686,8 +3618,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
* cs_change is set for each transfer. * cs_change is set for each transfer.
*/ */
if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) || if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
spi->cs_gpiod || spi->cs_gpiod)) {
gpio_is_valid(spi->cs_gpio))) {
size_t maxsize; size_t maxsize;
int ret; int ret;
......
...@@ -137,9 +137,6 @@ extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer); ...@@ -137,9 +137,6 @@ extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer);
* for driver coldplugging, and in uevents used for hotplugging * for driver coldplugging, and in uevents used for hotplugging
* @driver_override: If the name of a driver is written to this attribute, then * @driver_override: If the name of a driver is written to this attribute, then
* the device will bind to the named driver and only the named driver. * the device will bind to the named driver and only the named driver.
* @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 * @cs_gpiod: gpio descriptor of the chipselect line (optional, NULL when
* not using a GPIO line) * not using a GPIO line)
* @word_delay: delay to be inserted between consecutive * @word_delay: delay to be inserted between consecutive
...@@ -186,7 +183,6 @@ struct spi_device { ...@@ -186,7 +183,6 @@ struct spi_device {
void *controller_data; void *controller_data;
char modalias[SPI_NAME_SIZE]; char modalias[SPI_NAME_SIZE];
const char *driver_override; const char *driver_override;
int cs_gpio; /* LEGACY: chip select gpio */
struct gpio_desc *cs_gpiod; /* chip select gpio desc */ struct gpio_desc *cs_gpiod; /* chip select gpio desc */
struct spi_delay word_delay; /* inter-word delay */ struct spi_delay word_delay; /* inter-word delay */
/* CS delays */ /* CS delays */
...@@ -418,17 +414,12 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch ...@@ -418,17 +414,12 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
* controller has native support for memory like operations. * controller has native support for memory like operations.
* @unprepare_message: undo any work done by prepare_message(). * @unprepare_message: undo any work done by prepare_message().
* @slave_abort: abort the ongoing transfer request on an SPI slave controller * @slave_abort: abort the ongoing transfer request on an SPI slave controller
* @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 * @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 * number. Any individual value may be NULL for CS lines that
* are not GPIOs (driven by the SPI controller itself). * are not GPIOs (driven by the SPI controller itself).
* @use_gpio_descriptors: Turns on the code in the SPI core to parse and grab * @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 * GPIO descriptors. This will fill in @cs_gpiods and SPI devices will have
* driver. This will fill in @cs_gpiods and @cs_gpios should not be used, * the cs_gpiod assigned if a GPIO line is found for the chipselect.
* and SPI devices will have the cs_gpiod assigned rather than cs_gpio.
* @unused_native_cs: When cs_gpiods is used, spi_register_controller() will * @unused_native_cs: When cs_gpiods is used, spi_register_controller() will
* fill in this field with the first unused native CS, to be used by SPI * fill in this field with the first unused native CS, to be used by SPI
* controller drivers that need to drive a native CS when using GPIO CS. * controller drivers that need to drive a native CS when using GPIO CS.
...@@ -642,7 +633,6 @@ struct spi_controller { ...@@ -642,7 +633,6 @@ struct spi_controller {
const struct spi_controller_mem_ops *mem_ops; const struct spi_controller_mem_ops *mem_ops;
/* gpio chip select */ /* gpio chip select */
int *cs_gpios;
struct gpio_desc **cs_gpiods; struct gpio_desc **cs_gpiods;
bool use_gpio_descriptors; bool use_gpio_descriptors;
s8 unused_native_cs; s8 unused_native_cs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment