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

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


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5790597d
Loading
Loading
Loading
Loading
+28 −97
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/pm_runtime.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.bus = &spi_bus_type;
	spi->dev.release = spidev_release;
	spi->cs_gpio = -ENOENT;
	spi->mode = ctlr->buswidth_override_bits;

	spin_lock_init(&spi->statistics.lock);
@@ -606,11 +604,8 @@ static int __spi_add_device(struct spi_device *spi)
		return -ENODEV;
	}

	/* Descriptors take precedence */
	if (ctlr->cs_gpiods)
		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
@@ -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_mode_high = spi->mode & SPI_CS_HIGH;

	if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
	    !spi->controller->set_cs_timing) && !activate) {
	if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) {
		spi_delay_exec(&spi->cs_hold, NULL);
	}

	if (spi->mode & SPI_CS_HIGH)
		enable = !enable;

	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) {
		if (!(spi->mode & SPI_NO_CS)) {
	if (spi->cs_gpiod) {
		if (!(spi->mode & SPI_NO_CS)) {
			/*
			 * Historically ACPI has no means of the GPIO polarity and
			 * 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)
			else
				/* Polarity handled by GPIO library */
				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 */
		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);
	}

	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
	    !spi->controller->set_cs_timing) {
	if (spi->cs_gpiod || !spi->controller->set_cs_timing) {
		if (activate)
			spi_delay_exec(&spi->cs_setup, NULL);
		else
@@ -2827,46 +2812,6 @@ struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
}
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
 * @ctlr: The SPI master to grab GPIO descriptors for
@@ -3051,8 +2996,7 @@ int spi_register_controller(struct spi_controller *ctlr)
	 */
	dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num);

	if (!spi_controller_is_slave(ctlr)) {
		if (ctlr->use_gpio_descriptors) {
	if (!spi_controller_is_slave(ctlr) && ctlr->use_gpio_descriptors) {
		status = spi_get_gpio_descs(ctlr);
		if (status)
			goto free_bus_id;
@@ -3061,12 +3005,6 @@ int spi_register_controller(struct spi_controller *ctlr)
		 * supports SPI_CS_HIGH if need be.
		 */
		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 |
				 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 &
		    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_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.
	 */
	if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
					  spi->cs_gpiod ||
					  gpio_is_valid(spi->cs_gpio))) {
					  spi->cs_gpiod)) {
		size_t maxsize;
		int ret;

+2 −12
Original line number Diff line number Diff line
@@ -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
 * @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.
 * @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)
 * @word_delay: delay to be inserted between consecutive
@@ -186,7 +183,6 @@ struct spi_device {
	void			*controller_data;
	char			modalias[SPI_NAME_SIZE];
	const char		*driver_override;
	int			cs_gpio;	/* LEGACY: chip select gpio */
	struct gpio_desc	*cs_gpiod;	/* chip select gpio desc */
	struct spi_delay	word_delay; /* inter-word delay */
	/* 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.
 * @unprepare_message: undo any work done by prepare_message().
 * @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
 *	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.
 *	GPIO descriptors. This will fill in @cs_gpiods and SPI devices will have
 *	the cs_gpiod assigned if a GPIO line is found for the chipselect.
 * @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
 *	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;

	/* gpio chip select */
	int			*cs_gpios;
	struct gpio_desc	**cs_gpiods;
	bool			use_gpio_descriptors;
	s8			unused_native_cs;