aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/mpc52xx_spi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-14 13:22:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-14 13:22:11 -0500
commit478e4e9d7a618379676b17e64583ff3622f2fec5 (patch)
tree1f25c96499abbb0d0b47f75aa92134209fcc4ee8 /drivers/spi/mpc52xx_spi.c
parent2205afa7d13ec716935dfd4b8ff71059ee7aeb0c (diff)
parent965346e3b99e2c5f51bd1325ddd0257227000355 (diff)
Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6
* 'next-spi' of git://git.secretlab.ca/git/linux-2.6: (23 commits) spi: fix probe/remove section markings Add OMAP spi100k driver spi-imx: don't access struct device directly but use dev_get_platdata spi-imx: Add mx25 support spi-imx: use positive logic to distinguish cpu variants spi-imx: correct check for platform_get_irq failing ARM: NUC900: Add spi driver support for nuc900 spi: SuperH MSIOF SPI Master driver V2 spi: fix spidev compilation failure when VERBOSE is defined spi/au1550_spi: fix setupxfer not to override cfg with zeros spi/mpc8xxx: don't use __exit_p to wrap plat_mpc8xxx_spi_remove spi/i.MX: fix broken error handling for gpio_request spi/i.mx: drain MXC SPI transfer buffer when probing device MAINTAINERS: add SPI co-maintainer. spi/xilinx_spi: fix incorrect casting spi/mpc52xx-spi: minor cleanups xilinx_spi: add a platform driver using the xilinx_spi common module. xilinx_spi: add support for the DS570 IP. xilinx_spi: Switch to iomem functions and support little endian. xilinx_spi: Split into of driver and generic part. ...
Diffstat (limited to 'drivers/spi/mpc52xx_spi.c')
-rw-r--r--drivers/spi/mpc52xx_spi.c86
1 files changed, 72 insertions, 14 deletions
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c
index ef8379b2c172..45bfe6458173 100644
--- a/drivers/spi/mpc52xx_spi.c
+++ b/drivers/spi/mpc52xx_spi.c
@@ -18,9 +18,9 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/spi/mpc52xx_spi.h>
22#include <linux/of_spi.h> 21#include <linux/of_spi.h>
23#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/of_gpio.h>
24#include <asm/time.h> 24#include <asm/time.h>
25#include <asm/mpc52xx.h> 25#include <asm/mpc52xx.h>
26 26
@@ -53,7 +53,7 @@ MODULE_LICENSE("GPL");
53/* FSM state return values */ 53/* FSM state return values */
54#define FSM_STOP 0 /* Nothing more for the state machine to */ 54#define FSM_STOP 0 /* Nothing more for the state machine to */
55 /* do. If something interesting happens */ 55 /* do. If something interesting happens */
56 /* then and IRQ will be received */ 56 /* then an IRQ will be received */
57#define FSM_POLL 1 /* need to poll for completion, an IRQ is */ 57#define FSM_POLL 1 /* need to poll for completion, an IRQ is */
58 /* not expected */ 58 /* not expected */
59#define FSM_CONTINUE 2 /* Keep iterating the state machine */ 59#define FSM_CONTINUE 2 /* Keep iterating the state machine */
@@ -61,13 +61,12 @@ MODULE_LICENSE("GPL");
61/* Driver internal data */ 61/* Driver internal data */
62struct mpc52xx_spi { 62struct mpc52xx_spi {
63 struct spi_master *master; 63 struct spi_master *master;
64 u32 sysclk;
65 void __iomem *regs; 64 void __iomem *regs;
66 int irq0; /* MODF irq */ 65 int irq0; /* MODF irq */
67 int irq1; /* SPIF irq */ 66 int irq1; /* SPIF irq */
68 int ipb_freq; 67 unsigned int ipb_freq;
69 68
70 /* Statistics */ 69 /* Statistics; not used now, but will be reintroduced for debugfs */
71 int msg_count; 70 int msg_count;
72 int wcol_count; 71 int wcol_count;
73 int wcol_ticks; 72 int wcol_ticks;
@@ -79,7 +78,6 @@ struct mpc52xx_spi {
79 spinlock_t lock; 78 spinlock_t lock;
80 struct work_struct work; 79 struct work_struct work;
81 80
82
83 /* Details of current transfer (length, and buffer pointers) */ 81 /* Details of current transfer (length, and buffer pointers) */
84 struct spi_message *message; /* current message */ 82 struct spi_message *message; /* current message */
85 struct spi_transfer *transfer; /* current transfer */ 83 struct spi_transfer *transfer; /* current transfer */
@@ -89,6 +87,8 @@ struct mpc52xx_spi {
89 u8 *rx_buf; 87 u8 *rx_buf;
90 const u8 *tx_buf; 88 const u8 *tx_buf;
91 int cs_change; 89 int cs_change;
90 int gpio_cs_count;
91 unsigned int *gpio_cs;
92}; 92};
93 93
94/* 94/*
@@ -96,7 +96,13 @@ struct mpc52xx_spi {
96 */ 96 */
97static void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value) 97static void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value)
98{ 98{
99 out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08); 99 int cs;
100
101 if (ms->gpio_cs_count > 0) {
102 cs = ms->message->spi->chip_select;
103 gpio_set_value(ms->gpio_cs[cs], value ? 0 : 1);
104 } else
105 out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08);
100} 106}
101 107
102/* 108/*
@@ -221,7 +227,7 @@ static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms,
221 ms->wcol_tx_timestamp = get_tbl(); 227 ms->wcol_tx_timestamp = get_tbl();
222 data = 0; 228 data = 0;
223 if (ms->tx_buf) 229 if (ms->tx_buf)
224 data = *(ms->tx_buf-1); 230 data = *(ms->tx_buf - 1);
225 out_8(ms->regs + SPI_DATA, data); /* try again */ 231 out_8(ms->regs + SPI_DATA, data); /* try again */
226 return FSM_CONTINUE; 232 return FSM_CONTINUE;
227 } else if (status & SPI_STATUS_MODF) { 233 } else if (status & SPI_STATUS_MODF) {
@@ -390,7 +396,9 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
390 struct spi_master *master; 396 struct spi_master *master;
391 struct mpc52xx_spi *ms; 397 struct mpc52xx_spi *ms;
392 void __iomem *regs; 398 void __iomem *regs;
393 int rc; 399 u8 ctrl1;
400 int rc, i = 0;
401 int gpio_cs;
394 402
395 /* MMIO registers */ 403 /* MMIO registers */
396 dev_dbg(&op->dev, "probing mpc5200 SPI device\n"); 404 dev_dbg(&op->dev, "probing mpc5200 SPI device\n");
@@ -399,7 +407,8 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
399 return -ENODEV; 407 return -ENODEV;
400 408
401 /* initialize the device */ 409 /* initialize the device */
402 out_8(regs+SPI_CTRL1, SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR); 410 ctrl1 = SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR;
411 out_8(regs + SPI_CTRL1, ctrl1);
403 out_8(regs + SPI_CTRL2, 0x0); 412 out_8(regs + SPI_CTRL2, 0x0);
404 out_8(regs + SPI_DATADIR, 0xe); /* Set output pins */ 413 out_8(regs + SPI_DATADIR, 0xe); /* Set output pins */
405 out_8(regs + SPI_PORTDATA, 0x8); /* Deassert /SS signal */ 414 out_8(regs + SPI_PORTDATA, 0x8); /* Deassert /SS signal */
@@ -409,6 +418,8 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
409 * on the SPI bus. This fault will also occur if the SPI signals 418 * on the SPI bus. This fault will also occur if the SPI signals
410 * are not connected to any pins (port_config setting) */ 419 * are not connected to any pins (port_config setting) */
411 in_8(regs + SPI_STATUS); 420 in_8(regs + SPI_STATUS);
421 out_8(regs + SPI_CTRL1, ctrl1);
422
412 in_8(regs + SPI_DATA); 423 in_8(regs + SPI_DATA);
413 if (in_8(regs + SPI_STATUS) & SPI_STATUS_MODF) { 424 if (in_8(regs + SPI_STATUS) & SPI_STATUS_MODF) {
414 dev_err(&op->dev, "mode fault; is port_config correct?\n"); 425 dev_err(&op->dev, "mode fault; is port_config correct?\n");
@@ -422,10 +433,12 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
422 rc = -ENOMEM; 433 rc = -ENOMEM;
423 goto err_alloc; 434 goto err_alloc;
424 } 435 }
436
425 master->bus_num = -1; 437 master->bus_num = -1;
426 master->num_chipselect = 1;
427 master->setup = mpc52xx_spi_setup; 438 master->setup = mpc52xx_spi_setup;
428 master->transfer = mpc52xx_spi_transfer; 439 master->transfer = mpc52xx_spi_transfer;
440 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
441
429 dev_set_drvdata(&op->dev, master); 442 dev_set_drvdata(&op->dev, master);
430 443
431 ms = spi_master_get_devdata(master); 444 ms = spi_master_get_devdata(master);
@@ -435,16 +448,51 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
435 ms->irq1 = irq_of_parse_and_map(op->node, 1); 448 ms->irq1 = irq_of_parse_and_map(op->node, 1);
436 ms->state = mpc52xx_spi_fsmstate_idle; 449 ms->state = mpc52xx_spi_fsmstate_idle;
437 ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node); 450 ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node);
451 ms->gpio_cs_count = of_gpio_count(op->node);
452 if (ms->gpio_cs_count > 0) {
453 master->num_chipselect = ms->gpio_cs_count;
454 ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int),
455 GFP_KERNEL);
456 if (!ms->gpio_cs) {
457 rc = -ENOMEM;
458 goto err_alloc;
459 }
460
461 for (i = 0; i < ms->gpio_cs_count; i++) {
462 gpio_cs = of_get_gpio(op->node, i);
463 if (gpio_cs < 0) {
464 dev_err(&op->dev,
465 "could not parse the gpio field "
466 "in oftree\n");
467 rc = -ENODEV;
468 goto err_gpio;
469 }
470
471 rc = gpio_request(gpio_cs, dev_name(&op->dev));
472 if (rc) {
473 dev_err(&op->dev,
474 "can't request spi cs gpio #%d "
475 "on gpio line %d\n", i, gpio_cs);
476 goto err_gpio;
477 }
478
479 gpio_direction_output(gpio_cs, 1);
480 ms->gpio_cs[i] = gpio_cs;
481 }
482 } else {
483 master->num_chipselect = 1;
484 }
485
438 spin_lock_init(&ms->lock); 486 spin_lock_init(&ms->lock);
439 INIT_LIST_HEAD(&ms->queue); 487 INIT_LIST_HEAD(&ms->queue);
440 INIT_WORK(&ms->work, mpc52xx_spi_wq); 488 INIT_WORK(&ms->work, mpc52xx_spi_wq);
441 489
442 /* Decide if interrupts can be used */ 490 /* Decide if interrupts can be used */
443 if (ms->irq0 && ms->irq1) { 491 if (ms->irq0 && ms->irq1) {
444 rc = request_irq(ms->irq0, mpc52xx_spi_irq, IRQF_SAMPLE_RANDOM, 492 rc = request_irq(ms->irq0, mpc52xx_spi_irq, 0,
445 "mpc5200-spi-modf", ms); 493 "mpc5200-spi-modf", ms);
446 rc |= request_irq(ms->irq1, mpc52xx_spi_irq, IRQF_SAMPLE_RANDOM, 494 rc |= request_irq(ms->irq1, mpc52xx_spi_irq, 0,
447 "mpc5200-spi-spiF", ms); 495 "mpc5200-spi-spif", ms);
448 if (rc) { 496 if (rc) {
449 free_irq(ms->irq0, ms); 497 free_irq(ms->irq0, ms);
450 free_irq(ms->irq1, ms); 498 free_irq(ms->irq1, ms);
@@ -471,6 +519,11 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
471 err_register: 519 err_register:
472 dev_err(&ms->master->dev, "initialization failed\n"); 520 dev_err(&ms->master->dev, "initialization failed\n");
473 spi_master_put(master); 521 spi_master_put(master);
522 err_gpio:
523 while (i-- > 0)
524 gpio_free(ms->gpio_cs[i]);
525
526 kfree(ms->gpio_cs);
474 err_alloc: 527 err_alloc:
475 err_init: 528 err_init:
476 iounmap(regs); 529 iounmap(regs);
@@ -481,10 +534,15 @@ static int __devexit mpc52xx_spi_remove(struct of_device *op)
481{ 534{
482 struct spi_master *master = dev_get_drvdata(&op->dev); 535 struct spi_master *master = dev_get_drvdata(&op->dev);
483 struct mpc52xx_spi *ms = spi_master_get_devdata(master); 536 struct mpc52xx_spi *ms = spi_master_get_devdata(master);
537 int i;
484 538
485 free_irq(ms->irq0, ms); 539 free_irq(ms->irq0, ms);
486 free_irq(ms->irq1, ms); 540 free_irq(ms->irq1, ms);
487 541
542 for (i = 0; i < ms->gpio_cs_count; i++)
543 gpio_free(ms->gpio_cs[i]);
544
545 kfree(ms->gpio_cs);
488 spi_unregister_master(master); 546 spi_unregister_master(master);
489 spi_master_put(master); 547 spi_master_put(master);
490 iounmap(ms->regs); 548 iounmap(ms->regs);