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: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20220210231954.807904-1-linus.walleij@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
5790597d71
commit
f48dc6b966
@ -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)
|
|||||||
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)
|
|||||||
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,39 +935,30 @@ 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->cs_gpiod) {
|
||||||
if (!(spi->mode & SPI_NO_CS)) {
|
if (!(spi->mode & SPI_NO_CS)) {
|
||||||
if (spi->cs_gpiod) {
|
/*
|
||||||
/*
|
* 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
|
* basis. In order to avoid a chain of negations, the GPIO
|
||||||
* basis. In order to avoid a chain of negations, the GPIO
|
* polarity is considered being Active High. Even for the cases
|
||||||
* polarity is considered being Active High. Even for the cases
|
* when _DSD() is involved (in the updated versions of ACPI)
|
||||||
* when _DSD() is involved (in the updated versions of ACPI)
|
* the GPIO CS polarity must be defined Active High to avoid
|
||||||
* the GPIO CS polarity must be defined Active High to avoid
|
* ambiguity. That's why we use enable, that takes SPI_CS_HIGH
|
||||||
* ambiguity. That's why we use enable, that takes SPI_CS_HIGH
|
* into account.
|
||||||
* into account.
|
*/
|
||||||
*/
|
if (has_acpi_companion(&spi->dev))
|
||||||
if (has_acpi_companion(&spi->dev))
|
gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
|
||||||
gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
|
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)
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
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,22 +2996,15 @@ 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;
|
/*
|
||||||
/*
|
* A controller using GPIO descriptors always
|
||||||
* A controller using GPIO descriptors always
|
* 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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
* 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);
|
|||||||
* 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 {
|
|||||||
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
|
|||||||
* 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 {
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user