Skip to content

Commit

Permalink
spi/davinci: add OF support for the spi controller
Browse files Browse the repository at this point in the history
This adds OF support to DaVinci SPI controller to configure platform
data through device bindings. Also replaces clk_enable() with
of clk_prepare_enable() as well as clk_disable() with
clk_disable_unprepare().

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
  • Loading branch information
Murali Karicheri authored and Grant Likely committed Feb 5, 2013
1 parent 830379e commit aae7147
Showing 1 changed file with 88 additions and 14 deletions.
102 changes: 88 additions & 14 deletions drivers/spi/spi-davinci.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/edma.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -135,7 +137,7 @@ struct davinci_spi {
int dma_rx_chnum;
int dma_tx_chnum;

struct davinci_spi_platform_data *pdata;
struct davinci_spi_platform_data pdata;

void (*get_rx)(u32 rx_data, struct davinci_spi *);
u32 (*get_tx)(struct davinci_spi *);
Expand Down Expand Up @@ -213,7 +215,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
bool gpio_chipsel = false;

dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
pdata = &dspi->pdata;

if (pdata->chip_sel && chip_sel < pdata->num_chipselect &&
pdata->chip_sel[chip_sel] != SPI_INTERN_CS)
Expand Down Expand Up @@ -392,7 +394,7 @@ static int davinci_spi_setup(struct spi_device *spi)
struct davinci_spi_platform_data *pdata;

dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
pdata = &dspi->pdata;

/* if bits per word length is zero then set it default 8 */
if (!spi->bits_per_word)
Expand Down Expand Up @@ -534,7 +536,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
struct scatterlist sg_rx, sg_tx;

dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
pdata = &dspi->pdata;
spicfg = (struct davinci_spi_config *)spi->controller_data;
if (!spicfg)
spicfg = &davinci_spi_default_cfg;
Expand Down Expand Up @@ -758,6 +760,70 @@ static int davinci_spi_request_dma(struct davinci_spi *dspi)
return r;
}

#if defined(CONFIG_OF)
static const struct of_device_id davinci_spi_of_match[] = {
{
.compatible = "ti,dm644x-spi",
},
{
.compatible = "ti,da8xx-spi",
.data = (void *)SPI_VERSION_2,
},
{ },
};
MODULE_DEVICE_TABLE(of, davini_spi_of_match);

/**
* spi_davinci_get_pdata - Get platform data from DTS binding
* @pdev: ptr to platform data
* @dspi: ptr to driver data
*
* Parses and populates pdata in dspi from device tree bindings.
*
* NOTE: Not all platform data params are supported currently.
*/
static int spi_davinci_get_pdata(struct platform_device *pdev,
struct davinci_spi *dspi)
{
struct device_node *node = pdev->dev.of_node;
struct davinci_spi_platform_data *pdata;
unsigned int num_cs, intr_line = 0;
const struct of_device_id *match;

pdata = &dspi->pdata;

pdata->version = SPI_VERSION_1;
match = of_match_device(of_match_ptr(davinci_spi_of_match),
&pdev->dev);
if (!match)
return -ENODEV;

/* match data has the SPI version number for SPI_VERSION_2 */
if (match->data == (void *)SPI_VERSION_2)
pdata->version = SPI_VERSION_2;

/*
* default num_cs is 1 and all chipsel are internal to the chip
* indicated by chip_sel being NULL. GPIO based CS is not
* supported yet in DT bindings.
*/
num_cs = 1;
of_property_read_u32(node, "num-cs", &num_cs);
pdata->num_chipselect = num_cs;
of_property_read_u32(node, "ti,davinci-spi-intr-line", &intr_line);
pdata->intr_line = intr_line;
return 0;
}
#else
#define davinci_spi_of_match NULL
static struct davinci_spi_platform_data
*spi_davinci_get_pdata(struct platform_device *pdev,
struct davinci_spi *dspi)
{
return -ENODEV;
}
#endif

/**
* davinci_spi_probe - probe function for SPI Master Controller
* @pdev: platform_device structure which contains plateform specific data
Expand All @@ -780,12 +846,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
int i = 0, ret = 0;
u32 spipc0;

pdata = pdev->dev.platform_data;
if (pdata == NULL) {
ret = -ENODEV;
goto err;
}

master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi));
if (master == NULL) {
ret = -ENOMEM;
Expand All @@ -800,14 +860,26 @@ static int davinci_spi_probe(struct platform_device *pdev)
goto free_master;
}

if (pdev->dev.platform_data) {
pdata = pdev->dev.platform_data;
dspi->pdata = *pdata;
} else {
/* update dspi pdata with that from the DT */
ret = spi_davinci_get_pdata(pdev, dspi);
if (ret < 0)
goto free_master;
}

/* pdata in dspi is now updated and point pdata to that */
pdata = &dspi->pdata;

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
ret = -ENOENT;
goto free_master;
}

dspi->pbase = r->start;
dspi->pdata = pdata;

mem = request_mem_region(r->start, resource_size(r), pdev->name);
if (mem == NULL) {
Expand Down Expand Up @@ -843,8 +915,9 @@ static int davinci_spi_probe(struct platform_device *pdev)
ret = -ENODEV;
goto put_master;
}
clk_enable(dspi->clk);
clk_prepare_enable(dspi->clk);

master->dev.of_node = pdev->dev.of_node;
master->bus_num = pdev->id;
master->num_chipselect = pdata->num_chipselect;
master->setup = davinci_spi_setup;
Expand Down Expand Up @@ -927,7 +1000,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
dma_release_channel(dspi->dma_rx);
dma_release_channel(dspi->dma_tx);
free_clk:
clk_disable(dspi->clk);
clk_disable_unprepare(dspi->clk);
clk_put(dspi->clk);
put_master:
spi_master_put(master);
Expand Down Expand Up @@ -963,7 +1036,7 @@ static int davinci_spi_remove(struct platform_device *pdev)

spi_bitbang_stop(&dspi->bitbang);

clk_disable(dspi->clk);
clk_disable_unprepare(dspi->clk);
clk_put(dspi->clk);
spi_master_put(master);
free_irq(dspi->irq, dspi);
Expand All @@ -978,6 +1051,7 @@ static struct platform_driver davinci_spi_driver = {
.driver = {
.name = "spi_davinci",
.owner = THIS_MODULE,
.of_match_table = davinci_spi_of_match,
},
.probe = davinci_spi_probe,
.remove = davinci_spi_remove,
Expand Down

0 comments on commit aae7147

Please sign in to comment.