Skip to content

Commit

Permalink
spi/ath79: avoid multiple initialization of the SPI controller
Browse files Browse the repository at this point in the history
Currently we are initializing the SPI controller in
the chip select line function, and that function is
called once for each SPI device on the bus. If a
board has multiple SPI devices, the controller will
be initialized multiple times.

Introduce ath79_spi_{en,dis}able helper functions,
and call those from probe/response in order to avoid
the mutliple initialization of the controller.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
  • Loading branch information
Gabor Juhos authored and Grant Likely committed Feb 5, 2013
1 parent 95d7941 commit c4a31f4
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions drivers/spi/spi-ath79.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,8 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active)

}

static int ath79_spi_setup_cs(struct spi_device *spi)
static void ath79_spi_enable(struct ath79_spi *sp)
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
struct ath79_spi_controller_data *cdata;
int status;

cdata = spi->controller_data;
if (spi->chip_select && !cdata)
return -EINVAL;

/* enable GPIO mode */
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);

Expand All @@ -115,6 +107,24 @@ static int ath79_spi_setup_cs(struct spi_device *spi)

/* TODO: setup speed? */
ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
}

static void ath79_spi_disable(struct ath79_spi *sp)
{
/* restore CTRL register */
ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
/* disable GPIO mode */
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
}

static int ath79_spi_setup_cs(struct spi_device *spi)
{
struct ath79_spi_controller_data *cdata;
int status;

cdata = spi->controller_data;
if (spi->chip_select && !cdata)
return -EINVAL;

status = 0;
if (spi->chip_select) {
Expand All @@ -135,17 +145,10 @@ static int ath79_spi_setup_cs(struct spi_device *spi)

static void ath79_spi_cleanup_cs(struct spi_device *spi)
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);

if (spi->chip_select) {
struct ath79_spi_controller_data *cdata = spi->controller_data;
gpio_free(cdata->gpio);
}

/* restore CTRL register */
ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
/* disable GPIO mode */
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
}

static int ath79_spi_setup(struct spi_device *spi)
Expand Down Expand Up @@ -268,12 +271,15 @@ static int ath79_spi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
sp->rrw_delay);

ath79_spi_enable(sp);
ret = spi_bitbang_start(&sp->bitbang);
if (ret)
goto err_clk_disable;
goto err_disable;

return 0;

err_disable:
ath79_spi_disable(sp);
err_clk_disable:
clk_disable(sp->clk);
err_clk_put:
Expand All @@ -292,6 +298,7 @@ static int ath79_spi_remove(struct platform_device *pdev)
struct ath79_spi *sp = platform_get_drvdata(pdev);

spi_bitbang_stop(&sp->bitbang);
ath79_spi_disable(sp);
clk_disable(sp->clk);
clk_put(sp->clk);
iounmap(sp->base);
Expand Down

0 comments on commit c4a31f4

Please sign in to comment.