Skip to content

Commit

Permalink
spi: orion: Rework GPIO CS handling
Browse files Browse the repository at this point in the history
- Claim the GPIO from the driver, not via DT bindings or through the
  platform code
- Find an unused HW CS signal because Orion needs to drive one for each
  SPI transaction

The spi-orion.c was the only driver which supported (or cared about) the
CS GPIO, while it wasn't actually requesting it. This change means that
the DT bindings should stop hogging the GPIO CS pins because it's now
being handled by the driver.

Signed-off-by: Jan Kundrát <jan.kundrat@cesnet.cz>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Jan Kundrát authored and Mark Brown committed Feb 14, 2018
1 parent 7928b2c commit 5442486
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions drivers/spi/spi-orion.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct orion_spi {
struct clk *clk;
struct clk *axi_clk;
const struct orion_spi_dev *devdata;
int unused_hw_gpio;

struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS];
};
Expand Down Expand Up @@ -324,13 +325,13 @@ 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 = 0;
cs = orion_spi->unused_hw_gpio;
else
cs = spi->chip_select;

orion_spi = spi_master_get_devdata(spi->master);

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));
Expand Down Expand Up @@ -498,6 +499,9 @@ 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);
}

Expand Down Expand Up @@ -620,6 +624,7 @@ static int orion_spi_probe(struct platform_device *pdev)

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;
Expand Down Expand Up @@ -731,8 +736,44 @@ static int orion_spi_probe(struct platform_device *pdev)
if (status < 0)
goto out_rel_pm;

if (master->cs_gpios) {
int i;
for (i = 0; i < master->num_chipselect; ++i) {
char *gpio_name;

if (!gpio_is_valid(master->cs_gpios[i])) {
continue;
}

gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"%s-CS%d", dev_name(&pdev->dev), i);
if (!gpio_name) {
status = -ENOMEM;
goto out_rel_master;
}

status = devm_gpio_request(&pdev->dev,
master->cs_gpios[i], gpio_name);
if (status) {
dev_err(&pdev->dev,
"Can't request GPIO for CS %d\n",
master->cs_gpios[i]);
goto out_rel_master;
}
if (spi->unused_hw_gpio == -1) {
dev_info(&pdev->dev,
"Selected unused HW CS#%d "
"for any GPIO CSes\n", i);
spi->unused_hw_gpio = i;
}
}
}


return status;

out_rel_master:
spi_unregister_master(master);
out_rel_pm:
pm_runtime_disable(&pdev->dev);
out_rel_axi_clk:
Expand Down

0 comments on commit 5442486

Please sign in to comment.