diff options
author | Michal Simek <michal.simek@xilinx.com> | 2013-06-04 10:02:36 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-04 13:37:35 -0400 |
commit | 082339bc63cccf8ea49b1f3cf4ee39ce00742849 (patch) | |
tree | 870667862ca5d9d06ecc9233ea1f79a44f1b948d /drivers/spi/spi-xilinx.c | |
parent | d683b96b072dc4680fc74964eca77e6a23d1fa6e (diff) |
spi: spi-xilinx: Add run run-time endian detection
Do not load endian value from platform data
and rather autodetect it.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-xilinx.c')
-rw-r--r-- | drivers/spi/spi-xilinx.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index e1d769607425..bb6ae4ee7dea 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | #define XSPI_CR_OFFSET 0x60 /* Control Register */ | 31 | #define XSPI_CR_OFFSET 0x60 /* Control Register */ |
32 | 32 | ||
33 | #define XSPI_CR_LOOP 0x01 | ||
33 | #define XSPI_CR_ENABLE 0x02 | 34 | #define XSPI_CR_ENABLE 0x02 |
34 | #define XSPI_CR_MASTER_MODE 0x04 | 35 | #define XSPI_CR_MASTER_MODE 0x04 |
35 | #define XSPI_CR_CPOL 0x08 | 36 | #define XSPI_CR_CPOL 0x08 |
@@ -359,11 +360,12 @@ static const struct of_device_id xilinx_spi_of_match[] = { | |||
359 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | 360 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); |
360 | 361 | ||
361 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | 362 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, |
362 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) | 363 | u32 irq, s16 bus_num, int num_cs, int bits_per_word) |
363 | { | 364 | { |
364 | struct spi_master *master; | 365 | struct spi_master *master; |
365 | struct xilinx_spi *xspi; | 366 | struct xilinx_spi *xspi; |
366 | int ret; | 367 | int ret; |
368 | u32 tmp; | ||
367 | 369 | ||
368 | master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); | 370 | master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); |
369 | if (!master) | 371 | if (!master) |
@@ -396,13 +398,25 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | |||
396 | 398 | ||
397 | xspi->mem = *mem; | 399 | xspi->mem = *mem; |
398 | xspi->irq = irq; | 400 | xspi->irq = irq; |
399 | if (little_endian) { | 401 | |
400 | xspi->read_fn = xspi_read32; | 402 | /* |
401 | xspi->write_fn = xspi_write32; | 403 | * Detect endianess on the IP via loop bit in CR. Detection |
402 | } else { | 404 | * must be done before reset is sent because incorrect reset |
405 | * value generates error interrupt. | ||
406 | * Setup little endian helper functions first and try to use them | ||
407 | * and check if bit was correctly setup or not. | ||
408 | */ | ||
409 | xspi->read_fn = xspi_read32; | ||
410 | xspi->write_fn = xspi_write32; | ||
411 | |||
412 | xspi->write_fn(XSPI_CR_LOOP, xspi->regs + XSPI_CR_OFFSET); | ||
413 | tmp = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); | ||
414 | tmp &= XSPI_CR_LOOP; | ||
415 | if (tmp != XSPI_CR_LOOP) { | ||
403 | xspi->read_fn = xspi_read32_be; | 416 | xspi->read_fn = xspi_read32_be; |
404 | xspi->write_fn = xspi_write32_be; | 417 | xspi->write_fn = xspi_write32_be; |
405 | } | 418 | } |
419 | |||
406 | xspi->bits_per_word = bits_per_word; | 420 | xspi->bits_per_word = bits_per_word; |
407 | if (xspi->bits_per_word == 8) { | 421 | if (xspi->bits_per_word == 8) { |
408 | xspi->tx_fn = xspi_tx8; | 422 | xspi->tx_fn = xspi_tx8; |
@@ -466,14 +480,13 @@ static int xilinx_spi_probe(struct platform_device *dev) | |||
466 | { | 480 | { |
467 | struct xspi_platform_data *pdata; | 481 | struct xspi_platform_data *pdata; |
468 | struct resource *r; | 482 | struct resource *r; |
469 | int irq, num_cs = 0, little_endian = 0, bits_per_word = 8; | 483 | int irq, num_cs = 0, bits_per_word = 8; |
470 | struct spi_master *master; | 484 | struct spi_master *master; |
471 | u8 i; | 485 | u8 i; |
472 | 486 | ||
473 | pdata = dev->dev.platform_data; | 487 | pdata = dev->dev.platform_data; |
474 | if (pdata) { | 488 | if (pdata) { |
475 | num_cs = pdata->num_chipselect; | 489 | num_cs = pdata->num_chipselect; |
476 | little_endian = pdata->little_endian; | ||
477 | bits_per_word = pdata->bits_per_word; | 490 | bits_per_word = pdata->bits_per_word; |
478 | } | 491 | } |
479 | 492 | ||
@@ -505,7 +518,7 @@ static int xilinx_spi_probe(struct platform_device *dev) | |||
505 | return -ENXIO; | 518 | return -ENXIO; |
506 | 519 | ||
507 | master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, | 520 | master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, |
508 | little_endian, bits_per_word); | 521 | bits_per_word); |
509 | if (!master) | 522 | if (!master) |
510 | return -ENODEV; | 523 | return -ENODEV; |
511 | 524 | ||