diff options
author | Mark Brown <broonie@linaro.org> | 2013-06-26 11:21:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-26 11:21:06 -0400 |
commit | ed893559c9799df3b32051871c22017151394d82 (patch) | |
tree | 09b08825a81f00911a66b4c133fc9f00d6c4548d /drivers/spi | |
parent | 592cd34d9431736493c375b609f7f7d4458a8637 (diff) | |
parent | 913b19660e166e718d419cccd753c3990881f17c (diff) |
Merge remote-tracking branch 'spi/topic/xilinx' into spi-next
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-xilinx.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 96b392843814..fb56fcfdf65e 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 |
@@ -340,11 +341,12 @@ static const struct of_device_id xilinx_spi_of_match[] = { | |||
340 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | 341 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); |
341 | 342 | ||
342 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | 343 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, |
343 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) | 344 | u32 irq, s16 bus_num, int num_cs, int bits_per_word) |
344 | { | 345 | { |
345 | struct spi_master *master; | 346 | struct spi_master *master; |
346 | struct xilinx_spi *xspi; | 347 | struct xilinx_spi *xspi; |
347 | int ret; | 348 | int ret; |
349 | u32 tmp; | ||
348 | 350 | ||
349 | master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); | 351 | master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); |
350 | if (!master) | 352 | if (!master) |
@@ -376,13 +378,25 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | |||
376 | 378 | ||
377 | xspi->mem = *mem; | 379 | xspi->mem = *mem; |
378 | xspi->irq = irq; | 380 | xspi->irq = irq; |
379 | if (little_endian) { | 381 | |
380 | xspi->read_fn = xspi_read32; | 382 | /* |
381 | xspi->write_fn = xspi_write32; | 383 | * Detect endianess on the IP via loop bit in CR. Detection |
382 | } else { | 384 | * must be done before reset is sent because incorrect reset |
385 | * value generates error interrupt. | ||
386 | * Setup little endian helper functions first and try to use them | ||
387 | * and check if bit was correctly setup or not. | ||
388 | */ | ||
389 | xspi->read_fn = xspi_read32; | ||
390 | xspi->write_fn = xspi_write32; | ||
391 | |||
392 | xspi->write_fn(XSPI_CR_LOOP, xspi->regs + XSPI_CR_OFFSET); | ||
393 | tmp = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); | ||
394 | tmp &= XSPI_CR_LOOP; | ||
395 | if (tmp != XSPI_CR_LOOP) { | ||
383 | xspi->read_fn = xspi_read32_be; | 396 | xspi->read_fn = xspi_read32_be; |
384 | xspi->write_fn = xspi_write32_be; | 397 | xspi->write_fn = xspi_write32_be; |
385 | } | 398 | } |
399 | |||
386 | xspi->bits_per_word = bits_per_word; | 400 | xspi->bits_per_word = bits_per_word; |
387 | if (xspi->bits_per_word == 8) { | 401 | if (xspi->bits_per_word == 8) { |
388 | xspi->tx_fn = xspi_tx8; | 402 | xspi->tx_fn = xspi_tx8; |
@@ -446,14 +460,13 @@ static int xilinx_spi_probe(struct platform_device *dev) | |||
446 | { | 460 | { |
447 | struct xspi_platform_data *pdata; | 461 | struct xspi_platform_data *pdata; |
448 | struct resource *r; | 462 | struct resource *r; |
449 | int irq, num_cs = 0, little_endian = 0, bits_per_word = 8; | 463 | int irq, num_cs = 0, bits_per_word = 8; |
450 | struct spi_master *master; | 464 | struct spi_master *master; |
451 | u8 i; | 465 | u8 i; |
452 | 466 | ||
453 | pdata = dev->dev.platform_data; | 467 | pdata = dev->dev.platform_data; |
454 | if (pdata) { | 468 | if (pdata) { |
455 | num_cs = pdata->num_chipselect; | 469 | num_cs = pdata->num_chipselect; |
456 | little_endian = pdata->little_endian; | ||
457 | bits_per_word = pdata->bits_per_word; | 470 | bits_per_word = pdata->bits_per_word; |
458 | } | 471 | } |
459 | 472 | ||
@@ -485,7 +498,7 @@ static int xilinx_spi_probe(struct platform_device *dev) | |||
485 | return -ENXIO; | 498 | return -ENXIO; |
486 | 499 | ||
487 | master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, | 500 | master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, |
488 | little_endian, bits_per_word); | 501 | bits_per_word); |
489 | if (!master) | 502 | if (!master) |
490 | return -ENODEV; | 503 | return -ENODEV; |
491 | 504 | ||
@@ -501,7 +514,6 @@ static int xilinx_spi_probe(struct platform_device *dev) | |||
501 | static int xilinx_spi_remove(struct platform_device *dev) | 514 | static int xilinx_spi_remove(struct platform_device *dev) |
502 | { | 515 | { |
503 | xilinx_spi_deinit(platform_get_drvdata(dev)); | 516 | xilinx_spi_deinit(platform_get_drvdata(dev)); |
504 | platform_set_drvdata(dev, 0); | ||
505 | 517 | ||
506 | return 0; | 518 | return 0; |
507 | } | 519 | } |