aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-orion.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/spi/spi-orion.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/spi/spi-orion.c')
-rw-r--r--drivers/spi/spi-orion.c290
1 files changed, 165 insertions, 125 deletions
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index b7e718254b1..9421a390a5e 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -16,9 +16,7 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/module.h> 19#include <linux/spi/orion_spi.h>
20#include <linux/of.h>
21#include <linux/clk.h>
22#include <asm/unaligned.h> 20#include <asm/unaligned.h>
23 21
24#define DRIVER_NAME "orion_spi" 22#define DRIVER_NAME "orion_spi"
@@ -32,21 +30,25 @@
32#define ORION_SPI_DATA_IN_REG 0x0c 30#define ORION_SPI_DATA_IN_REG 0x0c
33#define ORION_SPI_INT_CAUSE_REG 0x10 31#define ORION_SPI_INT_CAUSE_REG 0x10
34 32
35#define ORION_SPI_MODE_CPOL (1 << 11)
36#define ORION_SPI_MODE_CPHA (1 << 12)
37#define ORION_SPI_IF_8_16_BIT_MODE (1 << 5) 33#define ORION_SPI_IF_8_16_BIT_MODE (1 << 5)
38#define ORION_SPI_CLK_PRESCALE_MASK 0x1F 34#define ORION_SPI_CLK_PRESCALE_MASK 0x1F
39#define ORION_SPI_MODE_MASK (ORION_SPI_MODE_CPOL | \
40 ORION_SPI_MODE_CPHA)
41 35
42struct orion_spi { 36struct orion_spi {
37 struct work_struct work;
38
39 /* Lock access to transfer list. */
40 spinlock_t lock;
41
42 struct list_head msg_queue;
43 struct spi_master *master; 43 struct spi_master *master;
44 void __iomem *base; 44 void __iomem *base;
45 unsigned int max_speed; 45 unsigned int max_speed;
46 unsigned int min_speed; 46 unsigned int min_speed;
47 struct clk *clk; 47 struct orion_spi_info *spi_info;
48}; 48};
49 49
50static struct workqueue_struct *orion_spi_wq;
51
50static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) 52static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
51{ 53{
52 return orion_spi->base + reg; 54 return orion_spi->base + reg;
@@ -101,7 +103,7 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
101 103
102 orion_spi = spi_master_get_devdata(spi->master); 104 orion_spi = spi_master_get_devdata(spi->master);
103 105
104 tclk_hz = clk_get_rate(orion_spi->clk); 106 tclk_hz = orion_spi->spi_info->tclk;
105 107
106 /* 108 /*
107 * the supported rates are: 4,6,8...30 109 * the supported rates are: 4,6,8...30
@@ -127,23 +129,6 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
127 return 0; 129 return 0;
128} 130}
129 131
130static void
131orion_spi_mode_set(struct spi_device *spi)
132{
133 u32 reg;
134 struct orion_spi *orion_spi;
135
136 orion_spi = spi_master_get_devdata(spi->master);
137
138 reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
139 reg &= ~ORION_SPI_MODE_MASK;
140 if (spi->mode & SPI_CPOL)
141 reg |= ORION_SPI_MODE_CPOL;
142 if (spi->mode & SPI_CPHA)
143 reg |= ORION_SPI_MODE_CPHA;
144 writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
145}
146
147/* 132/*
148 * called only when no transfer is active on the bus 133 * called only when no transfer is active on the bus
149 */ 134 */
@@ -163,8 +148,6 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
163 if ((t != NULL) && t->bits_per_word) 148 if ((t != NULL) && t->bits_per_word)
164 bits_per_word = t->bits_per_word; 149 bits_per_word = t->bits_per_word;
165 150
166 orion_spi_mode_set(spi);
167
168 rc = orion_spi_baudrate_set(spi, speed); 151 rc = orion_spi_baudrate_set(spi, speed);
169 if (rc) 152 if (rc)
170 return rc; 153 return rc;
@@ -292,78 +275,73 @@ out:
292} 275}
293 276
294 277
295static int orion_spi_transfer_one_message(struct spi_master *master, 278static void orion_spi_work(struct work_struct *work)
296 struct spi_message *m)
297{ 279{
298 struct orion_spi *orion_spi = spi_master_get_devdata(master); 280 struct orion_spi *orion_spi =
299 struct spi_device *spi = m->spi; 281 container_of(work, struct orion_spi, work);
300 struct spi_transfer *t = NULL;
301 int par_override = 0;
302 int status = 0;
303 int cs_active = 0;
304 282
305 /* Load defaults */ 283 spin_lock_irq(&orion_spi->lock);
306 status = orion_spi_setup_transfer(spi, NULL); 284 while (!list_empty(&orion_spi->msg_queue)) {
285 struct spi_message *m;
286 struct spi_device *spi;
287 struct spi_transfer *t = NULL;
288 int par_override = 0;
289 int status = 0;
290 int cs_active = 0;
307 291
308 if (status < 0) 292 m = container_of(orion_spi->msg_queue.next, struct spi_message,
309 goto msg_done; 293 queue);
310 294
311 list_for_each_entry(t, &m->transfers, transfer_list) { 295 list_del_init(&m->queue);
312 /* make sure buffer length is even when working in 16 296 spin_unlock_irq(&orion_spi->lock);
313 * bit mode*/
314 if ((t->bits_per_word == 16) && (t->len & 1)) {
315 dev_err(&spi->dev,
316 "message rejected : "
317 "odd data length %d while in 16 bit mode\n",
318 t->len);
319 status = -EIO;
320 goto msg_done;
321 }
322 297
323 if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { 298 spi = m->spi;
324 dev_err(&spi->dev,
325 "message rejected : "
326 "device min speed (%d Hz) exceeds "
327 "required transfer speed (%d Hz)\n",
328 orion_spi->min_speed, t->speed_hz);
329 status = -EIO;
330 goto msg_done;
331 }
332 299
333 if (par_override || t->speed_hz || t->bits_per_word) { 300 /* Load defaults */
334 par_override = 1; 301 status = orion_spi_setup_transfer(spi, NULL);
335 status = orion_spi_setup_transfer(spi, t);
336 if (status < 0)
337 break;
338 if (!t->speed_hz && !t->bits_per_word)
339 par_override = 0;
340 }
341 302
342 if (!cs_active) { 303 if (status < 0)
343 orion_spi_set_cs(orion_spi, 1); 304 goto msg_done;
344 cs_active = 1;
345 }
346
347 if (t->len)
348 m->actual_length += orion_spi_write_read(spi, t);
349
350 if (t->delay_usecs)
351 udelay(t->delay_usecs);
352 305
353 if (t->cs_change) { 306 list_for_each_entry(t, &m->transfers, transfer_list) {
354 orion_spi_set_cs(orion_spi, 0); 307 if (par_override || t->speed_hz || t->bits_per_word) {
355 cs_active = 0; 308 par_override = 1;
309 status = orion_spi_setup_transfer(spi, t);
310 if (status < 0)
311 break;
312 if (!t->speed_hz && !t->bits_per_word)
313 par_override = 0;
314 }
315
316 if (!cs_active) {
317 orion_spi_set_cs(orion_spi, 1);
318 cs_active = 1;
319 }
320
321 if (t->len)
322 m->actual_length +=
323 orion_spi_write_read(spi, t);
324
325 if (t->delay_usecs)
326 udelay(t->delay_usecs);
327
328 if (t->cs_change) {
329 orion_spi_set_cs(orion_spi, 0);
330 cs_active = 0;
331 }
356 } 332 }
357 }
358 333
359msg_done: 334msg_done:
360 if (cs_active) 335 if (cs_active)
361 orion_spi_set_cs(orion_spi, 0); 336 orion_spi_set_cs(orion_spi, 0);
362 337
363 m->status = status; 338 m->status = status;
364 spi_finalize_current_message(master); 339 m->complete(m->context);
365 340
366 return 0; 341 spin_lock_irq(&orion_spi->lock);
342 }
343
344 spin_unlock_irq(&orion_spi->lock);
367} 345}
368 346
369static int __init orion_spi_reset(struct orion_spi *orion_spi) 347static int __init orion_spi_reset(struct orion_spi *orion_spi)
@@ -380,6 +358,11 @@ static int orion_spi_setup(struct spi_device *spi)
380 358
381 orion_spi = spi_master_get_devdata(spi->master); 359 orion_spi = spi_master_get_devdata(spi->master);
382 360
361 /* Fix ac timing if required. */
362 if (orion_spi->spi_info->enable_clock_fix)
363 orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
364 (1 << 14));
365
383 if ((spi->max_speed_hz == 0) 366 if ((spi->max_speed_hz == 0)
384 || (spi->max_speed_hz > orion_spi->max_speed)) 367 || (spi->max_speed_hz > orion_spi->max_speed))
385 spi->max_speed_hz = orion_spi->max_speed; 368 spi->max_speed_hz = orion_spi->max_speed;
@@ -396,15 +379,84 @@ static int orion_spi_setup(struct spi_device *spi)
396 return 0; 379 return 0;
397} 380}
398 381
382static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m)
383{
384 struct orion_spi *orion_spi;
385 struct spi_transfer *t = NULL;
386 unsigned long flags;
387
388 m->actual_length = 0;
389 m->status = 0;
390
391 /* reject invalid messages and transfers */
392 if (list_empty(&m->transfers) || !m->complete)
393 return -EINVAL;
394
395 orion_spi = spi_master_get_devdata(spi->master);
396
397 list_for_each_entry(t, &m->transfers, transfer_list) {
398 unsigned int bits_per_word = spi->bits_per_word;
399
400 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
401 dev_err(&spi->dev,
402 "message rejected : "
403 "invalid transfer data buffers\n");
404 goto msg_rejected;
405 }
406
407 if (t->bits_per_word)
408 bits_per_word = t->bits_per_word;
409
410 if ((bits_per_word != 8) && (bits_per_word != 16)) {
411 dev_err(&spi->dev,
412 "message rejected : "
413 "invalid transfer bits_per_word (%d bits)\n",
414 bits_per_word);
415 goto msg_rejected;
416 }
417 /*make sure buffer length is even when working in 16 bit mode*/
418 if ((t->bits_per_word == 16) && (t->len & 1)) {
419 dev_err(&spi->dev,
420 "message rejected : "
421 "odd data length (%d) while in 16 bit mode\n",
422 t->len);
423 goto msg_rejected;
424 }
425
426 if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
427 dev_err(&spi->dev,
428 "message rejected : "
429 "device min speed (%d Hz) exceeds "
430 "required transfer speed (%d Hz)\n",
431 orion_spi->min_speed, t->speed_hz);
432 goto msg_rejected;
433 }
434 }
435
436
437 spin_lock_irqsave(&orion_spi->lock, flags);
438 list_add_tail(&m->queue, &orion_spi->msg_queue);
439 queue_work(orion_spi_wq, &orion_spi->work);
440 spin_unlock_irqrestore(&orion_spi->lock, flags);
441
442 return 0;
443msg_rejected:
444 /* Message rejected and not queued */
445 m->status = -EINVAL;
446 if (m->complete)
447 m->complete(m->context);
448 return -EINVAL;
449}
450
399static int __init orion_spi_probe(struct platform_device *pdev) 451static int __init orion_spi_probe(struct platform_device *pdev)
400{ 452{
401 struct spi_master *master; 453 struct spi_master *master;
402 struct orion_spi *spi; 454 struct orion_spi *spi;
403 struct resource *r; 455 struct resource *r;
404 unsigned long tclk_hz; 456 struct orion_spi_info *spi_info;
405 int status = 0; 457 int status = 0;
406 const u32 *iprop; 458
407 int size; 459 spi_info = pdev->dev.platform_data;
408 460
409 master = spi_alloc_master(&pdev->dev, sizeof *spi); 461 master = spi_alloc_master(&pdev->dev, sizeof *spi);
410 if (master == NULL) { 462 if (master == NULL) {
@@ -414,54 +466,44 @@ static int __init orion_spi_probe(struct platform_device *pdev)
414 466
415 if (pdev->id != -1) 467 if (pdev->id != -1)
416 master->bus_num = pdev->id; 468 master->bus_num = pdev->id;
417 if (pdev->dev.of_node) {
418 iprop = of_get_property(pdev->dev.of_node, "cell-index",
419 &size);
420 if (iprop && size == sizeof(*iprop))
421 master->bus_num = *iprop;
422 }
423 469
424 /* we support only mode 0, and no options */ 470 /* we support only mode 0, and no options */
425 master->mode_bits = SPI_CPHA | SPI_CPOL; 471 master->mode_bits = 0;
426 472
427 master->setup = orion_spi_setup; 473 master->setup = orion_spi_setup;
428 master->transfer_one_message = orion_spi_transfer_one_message; 474 master->transfer = orion_spi_transfer;
429 master->num_chipselect = ORION_NUM_CHIPSELECTS; 475 master->num_chipselect = ORION_NUM_CHIPSELECTS;
430 476
431 dev_set_drvdata(&pdev->dev, master); 477 dev_set_drvdata(&pdev->dev, master);
432 478
433 spi = spi_master_get_devdata(master); 479 spi = spi_master_get_devdata(master);
434 spi->master = master; 480 spi->master = master;
481 spi->spi_info = spi_info;
435 482
436 spi->clk = clk_get(&pdev->dev, NULL); 483 spi->max_speed = DIV_ROUND_UP(spi_info->tclk, 4);
437 if (IS_ERR(spi->clk)) { 484 spi->min_speed = DIV_ROUND_UP(spi_info->tclk, 30);
438 status = PTR_ERR(spi->clk);
439 goto out;
440 }
441
442 clk_prepare(spi->clk);
443 clk_enable(spi->clk);
444 tclk_hz = clk_get_rate(spi->clk);
445 spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
446 spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
447 485
448 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 486 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
449 if (r == NULL) { 487 if (r == NULL) {
450 status = -ENODEV; 488 status = -ENODEV;
451 goto out_rel_clk; 489 goto out;
452 } 490 }
453 491
454 if (!request_mem_region(r->start, resource_size(r), 492 if (!request_mem_region(r->start, resource_size(r),
455 dev_name(&pdev->dev))) { 493 dev_name(&pdev->dev))) {
456 status = -EBUSY; 494 status = -EBUSY;
457 goto out_rel_clk; 495 goto out;
458 } 496 }
459 spi->base = ioremap(r->start, SZ_1K); 497 spi->base = ioremap(r->start, SZ_1K);
460 498
499 INIT_WORK(&spi->work, orion_spi_work);
500
501 spin_lock_init(&spi->lock);
502 INIT_LIST_HEAD(&spi->msg_queue);
503
461 if (orion_spi_reset(spi) < 0) 504 if (orion_spi_reset(spi) < 0)
462 goto out_rel_mem; 505 goto out_rel_mem;
463 506
464 master->dev.of_node = pdev->dev.of_node;
465 status = spi_register_master(master); 507 status = spi_register_master(master);
466 if (status < 0) 508 if (status < 0)
467 goto out_rel_mem; 509 goto out_rel_mem;
@@ -470,9 +512,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
470 512
471out_rel_mem: 513out_rel_mem:
472 release_mem_region(r->start, resource_size(r)); 514 release_mem_region(r->start, resource_size(r));
473out_rel_clk: 515
474 clk_disable_unprepare(spi->clk);
475 clk_put(spi->clk);
476out: 516out:
477 spi_master_put(master); 517 spi_master_put(master);
478 return status; 518 return status;
@@ -482,14 +522,13 @@ out:
482static int __exit orion_spi_remove(struct platform_device *pdev) 522static int __exit orion_spi_remove(struct platform_device *pdev)
483{ 523{
484 struct spi_master *master; 524 struct spi_master *master;
485 struct resource *r;
486 struct orion_spi *spi; 525 struct orion_spi *spi;
526 struct resource *r;
487 527
488 master = dev_get_drvdata(&pdev->dev); 528 master = dev_get_drvdata(&pdev->dev);
489 spi = spi_master_get_devdata(master); 529 spi = spi_master_get_devdata(master);
490 530
491 clk_disable_unprepare(spi->clk); 531 cancel_work_sync(&spi->work);
492 clk_put(spi->clk);
493 532
494 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 533 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
495 release_mem_region(r->start, resource_size(r)); 534 release_mem_region(r->start, resource_size(r));
@@ -501,30 +540,31 @@ static int __exit orion_spi_remove(struct platform_device *pdev)
501 540
502MODULE_ALIAS("platform:" DRIVER_NAME); 541MODULE_ALIAS("platform:" DRIVER_NAME);
503 542
504static const struct of_device_id orion_spi_of_match_table[] = {
505 { .compatible = "marvell,orion-spi", },
506 {}
507};
508MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);
509
510static struct platform_driver orion_spi_driver = { 543static struct platform_driver orion_spi_driver = {
511 .driver = { 544 .driver = {
512 .name = DRIVER_NAME, 545 .name = DRIVER_NAME,
513 .owner = THIS_MODULE, 546 .owner = THIS_MODULE,
514 .of_match_table = of_match_ptr(orion_spi_of_match_table),
515 }, 547 },
516 .remove = __exit_p(orion_spi_remove), 548 .remove = __exit_p(orion_spi_remove),
517}; 549};
518 550
519static int __init orion_spi_init(void) 551static int __init orion_spi_init(void)
520{ 552{
553 orion_spi_wq = create_singlethread_workqueue(
554 orion_spi_driver.driver.name);
555 if (orion_spi_wq == NULL)
556 return -ENOMEM;
557
521 return platform_driver_probe(&orion_spi_driver, orion_spi_probe); 558 return platform_driver_probe(&orion_spi_driver, orion_spi_probe);
522} 559}
523module_init(orion_spi_init); 560module_init(orion_spi_init);
524 561
525static void __exit orion_spi_exit(void) 562static void __exit orion_spi_exit(void)
526{ 563{
564 flush_workqueue(orion_spi_wq);
527 platform_driver_unregister(&orion_spi_driver); 565 platform_driver_unregister(&orion_spi_driver);
566
567 destroy_workqueue(orion_spi_wq);
528} 568}
529module_exit(orion_spi_exit); 569module_exit(orion_spi_exit);
530 570