summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-orion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-orion.c')
-rw-r--r--drivers/spi/spi-orion.c70
1 files changed, 16 insertions, 54 deletions
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 1f59beb7d27e..43f73db22f21 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -17,10 +17,8 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
-#include <linux/of_gpio.h>
#include <linux/clk.h>
#include <linux/sizes.h>
-#include <linux/gpio.h>
#include <asm/unaligned.h>
#define DRIVER_NAME "orion_spi"
@@ -98,7 +96,6 @@ struct orion_spi {
struct clk *clk;
struct clk *axi_clk;
const struct orion_spi_dev *devdata;
- int unused_hw_gpio;
struct orion_child_options child[ORION_NUM_CHIPSELECTS];
};
@@ -325,20 +322,27 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
static void orion_spi_set_cs(struct spi_device *spi, bool enable)
{
struct orion_spi *orion_spi;
- int cs;
orion_spi = spi_master_get_devdata(spi->master);
- if (gpio_is_valid(spi->cs_gpio))
- cs = orion_spi->unused_hw_gpio;
- else
- cs = spi->chip_select;
-
+ /*
+ * If this line is using a GPIO to control chip select, this internal
+ * .set_cs() function will still be called, so we clear any previous
+ * chip select. The CS we activate will not have any elecrical effect,
+ * as it is handled by a GPIO, but that doesn't matter. What we need
+ * is to deassert the old chip select and assert some other chip select.
+ */
orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
- ORION_SPI_CS(cs));
+ ORION_SPI_CS(spi->chip_select));
- /* Chip select logic is inverted from spi_set_cs */
+ /*
+ * Chip select logic is inverted from spi_set_cs(). For lines using a
+ * GPIO to do chip select SPI_CS_HIGH is enforced and inversion happens
+ * in the GPIO library, but we don't care about that, because in those
+ * cases we are dealing with an unused native CS anyways so the polarity
+ * doesn't matter.
+ */
if (!enable)
orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
else
@@ -503,9 +507,6 @@ static int orion_spi_transfer_one(struct spi_master *master,
static int orion_spi_setup(struct spi_device *spi)
{
- if (gpio_is_valid(spi->cs_gpio)) {
- gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
- }
return orion_spi_setup_transfer(spi, NULL);
}
@@ -622,13 +623,13 @@ static int orion_spi_probe(struct platform_device *pdev)
master->setup = orion_spi_setup;
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
master->auto_runtime_pm = true;
+ master->use_gpio_descriptors = true;
master->flags = SPI_MASTER_GPIO_SS;
platform_set_drvdata(pdev, master);
spi = spi_master_get_devdata(master);
spi->master = master;
- spi->unused_hw_gpio = -1;
of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
@@ -683,7 +684,6 @@ static int orion_spi_probe(struct platform_device *pdev)
for_each_available_child_of_node(pdev->dev.of_node, np) {
struct orion_direct_acc *dir_acc;
u32 cs;
- int cs_gpio;
/* Get chip-select number from the "reg" property */
status = of_property_read_u32(np, "reg", &cs);
@@ -695,44 +695,6 @@ static int orion_spi_probe(struct platform_device *pdev)
}
/*
- * Initialize the CS GPIO:
- * - properly request the actual GPIO signal
- * - de-assert the logical signal so that all GPIO CS lines
- * are inactive when probing for slaves
- * - find an unused physical CS which will be driven for any
- * slave which uses a CS GPIO
- */
- cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", cs);
- if (cs_gpio > 0) {
- char *gpio_name;
- int cs_flags;
-
- if (spi->unused_hw_gpio == -1) {
- dev_info(&pdev->dev,
- "Selected unused HW CS#%d for any GPIO CSes\n",
- cs);
- spi->unused_hw_gpio = cs;
- }
-
- gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
- "%s-CS%d", dev_name(&pdev->dev), cs);
- if (!gpio_name) {
- status = -ENOMEM;
- goto out_rel_axi_clk;
- }
-
- cs_flags = of_property_read_bool(np, "spi-cs-high") ?
- GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
- status = devm_gpio_request_one(&pdev->dev, cs_gpio,
- cs_flags, gpio_name);
- if (status) {
- dev_err(&pdev->dev,
- "Can't request GPIO for CS %d\n", cs);
- goto out_rel_axi_clk;
- }
- }
-
- /*
* Check if an address is configured for this SPI device. If
* not, the MBus mapping via the 'ranges' property in the 'soc'
* node is not configured and this device should not use the