aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-09-01 08:49:01 -0400
committerMark Brown <broonie@linaro.org>2013-09-01 08:49:01 -0400
commit4374f332d9fec26a1b377981f39881abff54941a (patch)
tree938f015e05045ee39747eb7ea585f71944270e45
parent45bb5065e11cd770fcf4afe9714ccea671333766 (diff)
parent2d0c6148e381b81f8e6783d24b724963a86364cc (diff)
Merge remote-tracking branch 'spi/topic/omap-100k' into spi-next
-rw-r--r--drivers/spi/spi-omap-100k.c276
1 files changed, 78 insertions, 198 deletions
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
index ee25670f8cfd..cdcc72c5d380 100644
--- a/drivers/spi/spi-omap-100k.c
+++ b/drivers/spi/spi-omap-100k.c
@@ -83,11 +83,6 @@
83#define SPI_SHUTDOWN 1 83#define SPI_SHUTDOWN 1
84 84
85struct omap1_spi100k { 85struct omap1_spi100k {
86 struct work_struct work;
87
88 /* lock protects queue and registers */
89 spinlock_t lock;
90 struct list_head msg_queue;
91 struct spi_master *master; 86 struct spi_master *master;
92 struct clk *ick; 87 struct clk *ick;
93 struct clk *fck; 88 struct clk *fck;
@@ -104,8 +99,6 @@ struct omap1_spi100k_cs {
104 int word_len; 99 int word_len;
105}; 100};
106 101
107static struct workqueue_struct *omap1_spi100k_wq;
108
109#define MOD_REG_BIT(val, mask, set) do { \ 102#define MOD_REG_BIT(val, mask, set) do { \
110 if (set) \ 103 if (set) \
111 val |= mask; \ 104 val |= mask; \
@@ -310,170 +303,102 @@ static int omap1_spi100k_setup(struct spi_device *spi)
310 303
311 spi100k_open(spi->master); 304 spi100k_open(spi->master);
312 305
313 clk_enable(spi100k->ick); 306 clk_prepare_enable(spi100k->ick);
314 clk_enable(spi100k->fck); 307 clk_prepare_enable(spi100k->fck);
315 308
316 ret = omap1_spi100k_setup_transfer(spi, NULL); 309 ret = omap1_spi100k_setup_transfer(spi, NULL);
317 310
318 clk_disable(spi100k->ick); 311 clk_disable_unprepare(spi100k->ick);
319 clk_disable(spi100k->fck); 312 clk_disable_unprepare(spi100k->fck);
320 313
321 return ret; 314 return ret;
322} 315}
323 316
324static void omap1_spi100k_work(struct work_struct *work) 317static int omap1_spi100k_prepare_hardware(struct spi_master *master)
325{ 318{
326 struct omap1_spi100k *spi100k; 319 struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
327 int status = 0;
328 320
329 spi100k = container_of(work, struct omap1_spi100k, work); 321 clk_prepare_enable(spi100k->ick);
330 spin_lock_irq(&spi100k->lock); 322 clk_prepare_enable(spi100k->fck);
331 323
332 clk_enable(spi100k->ick); 324 return 0;
333 clk_enable(spi100k->fck); 325}
334 326
335 /* We only enable one channel at a time -- the one whose message is 327static int omap1_spi100k_transfer_one_message(struct spi_master *master,
336 * at the head of the queue -- although this controller would gladly 328 struct spi_message *m)
337 * arbitrate among multiple channels. This corresponds to "single 329{
338 * channel" master mode. As a side effect, we need to manage the 330 struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
339 * chipselect with the FORCE bit ... CS != channel enable. 331 struct spi_device *spi = m->spi;
340 */ 332 struct spi_transfer *t = NULL;
341 while (!list_empty(&spi100k->msg_queue)) { 333 int cs_active = 0;
342 struct spi_message *m; 334 int par_override = 0;
343 struct spi_device *spi; 335 int status = 0;
344 struct spi_transfer *t = NULL; 336
345 int cs_active = 0; 337 list_for_each_entry(t, &m->transfers, transfer_list) {
346 struct omap1_spi100k_cs *cs; 338 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
347 int par_override = 0; 339 status = -EINVAL;
348 340 break;
349 m = container_of(spi100k->msg_queue.next, struct spi_message, 341 }
350 queue); 342 if (par_override || t->speed_hz || t->bits_per_word) {
351 343 par_override = 1;
352 list_del_init(&m->queue); 344 status = omap1_spi100k_setup_transfer(spi, t);
353 spin_unlock_irq(&spi100k->lock); 345 if (status < 0)
354
355 spi = m->spi;
356 cs = spi->controller_state;
357
358 list_for_each_entry(t, &m->transfers, transfer_list) {
359 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
360 status = -EINVAL;
361 break; 346 break;
362 } 347 if (!t->speed_hz && !t->bits_per_word)
363 if (par_override || t->speed_hz || t->bits_per_word) { 348 par_override = 0;
364 par_override = 1; 349 }
365 status = omap1_spi100k_setup_transfer(spi, t);
366 if (status < 0)
367 break;
368 if (!t->speed_hz && !t->bits_per_word)
369 par_override = 0;
370 }
371 350
372 if (!cs_active) { 351 if (!cs_active) {
373 omap1_spi100k_force_cs(spi100k, 1); 352 omap1_spi100k_force_cs(spi100k, 1);
374 cs_active = 1; 353 cs_active = 1;
375 } 354 }
376 355
377 if (t->len) { 356 if (t->len) {
378 unsigned count; 357 unsigned count;
379 358
380 count = omap1_spi100k_txrx_pio(spi, t); 359 count = omap1_spi100k_txrx_pio(spi, t);
381 m->actual_length += count; 360 m->actual_length += count;
382 361
383 if (count != t->len) { 362 if (count != t->len) {
384 status = -EIO; 363 status = -EIO;
385 break; 364 break;
386 }
387 } 365 }
366 }
388 367
389 if (t->delay_usecs) 368 if (t->delay_usecs)
390 udelay(t->delay_usecs); 369 udelay(t->delay_usecs);
391 370
392 /* ignore the "leave it on after last xfer" hint */ 371 /* ignore the "leave it on after last xfer" hint */
393 372
394 if (t->cs_change) { 373 if (t->cs_change) {
395 omap1_spi100k_force_cs(spi100k, 0); 374 omap1_spi100k_force_cs(spi100k, 0);
396 cs_active = 0; 375 cs_active = 0;
397 }
398 }
399
400 /* Restore defaults if they were overriden */
401 if (par_override) {
402 par_override = 0;
403 status = omap1_spi100k_setup_transfer(spi, NULL);
404 } 376 }
377 }
405 378
406 if (cs_active) 379 /* Restore defaults if they were overriden */
407 omap1_spi100k_force_cs(spi100k, 0); 380 if (par_override) {
381 par_override = 0;
382 status = omap1_spi100k_setup_transfer(spi, NULL);
383 }
408 384
409 m->status = status; 385 if (cs_active)
410 m->complete(m->context); 386 omap1_spi100k_force_cs(spi100k, 0);
411 387
412 spin_lock_irq(&spi100k->lock); 388 m->status = status;
413 }
414 389
415 clk_disable(spi100k->ick); 390 spi_finalize_current_message(master);
416 clk_disable(spi100k->fck);
417 spin_unlock_irq(&spi100k->lock);
418 391
419 if (status < 0) 392 return status;
420 printk(KERN_WARNING "spi transfer failed with %d\n", status);
421} 393}
422 394
423static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m) 395static int omap1_spi100k_unprepare_hardware(struct spi_master *master)
424{ 396{
425 struct omap1_spi100k *spi100k; 397 struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
426 unsigned long flags;
427 struct spi_transfer *t;
428
429 m->actual_length = 0;
430 m->status = -EINPROGRESS;
431
432 spi100k = spi_master_get_devdata(spi->master);
433
434 /* Don't accept new work if we're shutting down */
435 if (spi100k->state == SPI_SHUTDOWN)
436 return -ESHUTDOWN;
437
438 /* reject invalid messages and transfers */
439 if (list_empty(&m->transfers) || !m->complete)
440 return -EINVAL;
441
442 list_for_each_entry(t, &m->transfers, transfer_list) {
443 const void *tx_buf = t->tx_buf;
444 void *rx_buf = t->rx_buf;
445 unsigned len = t->len;
446
447 if (t->speed_hz > OMAP1_SPI100K_MAX_FREQ
448 || (len && !(rx_buf || tx_buf))) {
449 dev_dbg(&spi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
450 t->speed_hz,
451 len,
452 tx_buf ? "tx" : "",
453 rx_buf ? "rx" : "",
454 t->bits_per_word);
455 return -EINVAL;
456 }
457
458 if (t->speed_hz && t->speed_hz < OMAP1_SPI100K_MAX_FREQ/(1<<16)) {
459 dev_dbg(&spi->dev, "%d Hz max exceeds %d\n",
460 t->speed_hz,
461 OMAP1_SPI100K_MAX_FREQ/(1<<16));
462 return -EINVAL;
463 }
464
465 }
466
467 spin_lock_irqsave(&spi100k->lock, flags);
468 list_add_tail(&m->queue, &spi100k->msg_queue);
469 queue_work(omap1_spi100k_wq, &spi100k->work);
470 spin_unlock_irqrestore(&spi100k->lock, flags);
471 398
472 return 0; 399 clk_disable_unprepare(spi100k->ick);
473} 400 clk_disable_unprepare(spi100k->fck);
474 401
475static int omap1_spi100k_reset(struct omap1_spi100k *spi100k)
476{
477 return 0; 402 return 0;
478} 403}
479 404
@@ -496,11 +421,15 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
496 master->bus_num = pdev->id; 421 master->bus_num = pdev->id;
497 422
498 master->setup = omap1_spi100k_setup; 423 master->setup = omap1_spi100k_setup;
499 master->transfer = omap1_spi100k_transfer; 424 master->transfer_one_message = omap1_spi100k_transfer_one_message;
425 master->prepare_transfer_hardware = omap1_spi100k_prepare_hardware;
426 master->unprepare_transfer_hardware = omap1_spi100k_unprepare_hardware;
500 master->cleanup = NULL; 427 master->cleanup = NULL;
501 master->num_chipselect = 2; 428 master->num_chipselect = 2;
502 master->mode_bits = MODEBITS; 429 master->mode_bits = MODEBITS;
503 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); 430 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
431 master->min_speed_hz = OMAP1_SPI100K_MAX_FREQ/(1<<16);
432 master->max_speed_hz = OMAP1_SPI100K_MAX_FREQ;
504 433
505 platform_set_drvdata(pdev, master); 434 platform_set_drvdata(pdev, master);
506 435
@@ -514,40 +443,29 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
514 */ 443 */
515 spi100k->base = (void __iomem *) pdev->dev.platform_data; 444 spi100k->base = (void __iomem *) pdev->dev.platform_data;
516 445
517 INIT_WORK(&spi100k->work, omap1_spi100k_work); 446 spi100k->ick = devm_clk_get(&pdev->dev, "ick");
518
519 spin_lock_init(&spi100k->lock);
520 INIT_LIST_HEAD(&spi100k->msg_queue);
521 spi100k->ick = clk_get(&pdev->dev, "ick");
522 if (IS_ERR(spi100k->ick)) { 447 if (IS_ERR(spi100k->ick)) {
523 dev_dbg(&pdev->dev, "can't get spi100k_ick\n"); 448 dev_dbg(&pdev->dev, "can't get spi100k_ick\n");
524 status = PTR_ERR(spi100k->ick); 449 status = PTR_ERR(spi100k->ick);
525 goto err1; 450 goto err;
526 } 451 }
527 452
528 spi100k->fck = clk_get(&pdev->dev, "fck"); 453 spi100k->fck = devm_clk_get(&pdev->dev, "fck");
529 if (IS_ERR(spi100k->fck)) { 454 if (IS_ERR(spi100k->fck)) {
530 dev_dbg(&pdev->dev, "can't get spi100k_fck\n"); 455 dev_dbg(&pdev->dev, "can't get spi100k_fck\n");
531 status = PTR_ERR(spi100k->fck); 456 status = PTR_ERR(spi100k->fck);
532 goto err2; 457 goto err;
533 } 458 }
534 459
535 if (omap1_spi100k_reset(spi100k) < 0)
536 goto err3;
537
538 status = spi_register_master(master); 460 status = spi_register_master(master);
539 if (status < 0) 461 if (status < 0)
540 goto err3; 462 goto err;
541 463
542 spi100k->state = SPI_RUNNING; 464 spi100k->state = SPI_RUNNING;
543 465
544 return status; 466 return status;
545 467
546err3: 468err:
547 clk_put(spi100k->fck);
548err2:
549 clk_put(spi100k->ick);
550err1:
551 spi_master_put(master); 469 spi_master_put(master);
552 return status; 470 return status;
553} 471}
@@ -557,33 +475,14 @@ static int omap1_spi100k_remove(struct platform_device *pdev)
557 struct spi_master *master; 475 struct spi_master *master;
558 struct omap1_spi100k *spi100k; 476 struct omap1_spi100k *spi100k;
559 struct resource *r; 477 struct resource *r;
560 unsigned limit = 500;
561 unsigned long flags;
562 int status = 0; 478 int status = 0;
563 479
564 master = platform_get_drvdata(pdev); 480 master = platform_get_drvdata(pdev);
565 spi100k = spi_master_get_devdata(master); 481 spi100k = spi_master_get_devdata(master);
566 482
567 spin_lock_irqsave(&spi100k->lock, flags);
568
569 spi100k->state = SPI_SHUTDOWN;
570 while (!list_empty(&spi100k->msg_queue) && limit--) {
571 spin_unlock_irqrestore(&spi100k->lock, flags);
572 msleep(10);
573 spin_lock_irqsave(&spi100k->lock, flags);
574 }
575
576 if (!list_empty(&spi100k->msg_queue))
577 status = -EBUSY;
578
579 spin_unlock_irqrestore(&spi100k->lock, flags);
580
581 if (status != 0) 483 if (status != 0)
582 return status; 484 return status;
583 485
584 clk_put(spi100k->fck);
585 clk_put(spi100k->ick);
586
587 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 486 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
588 487
589 spi_unregister_master(master); 488 spi_unregister_master(master);
@@ -596,30 +495,11 @@ static struct platform_driver omap1_spi100k_driver = {
596 .name = "omap1_spi100k", 495 .name = "omap1_spi100k",
597 .owner = THIS_MODULE, 496 .owner = THIS_MODULE,
598 }, 497 },
498 .probe = omap1_spi100k_probe,
599 .remove = omap1_spi100k_remove, 499 .remove = omap1_spi100k_remove,
600}; 500};
601 501
602 502module_platform_driver(omap1_spi100k_driver);
603static int __init omap1_spi100k_init(void)
604{
605 omap1_spi100k_wq = create_singlethread_workqueue(
606 omap1_spi100k_driver.driver.name);
607
608 if (omap1_spi100k_wq == NULL)
609 return -1;
610
611 return platform_driver_probe(&omap1_spi100k_driver, omap1_spi100k_probe);
612}
613
614static void __exit omap1_spi100k_exit(void)
615{
616 platform_driver_unregister(&omap1_spi100k_driver);
617
618 destroy_workqueue(omap1_spi100k_wq);
619}
620
621module_init(omap1_spi100k_init);
622module_exit(omap1_spi100k_exit);
623 503
624MODULE_DESCRIPTION("OMAP7xx SPI 100k controller driver"); 504MODULE_DESCRIPTION("OMAP7xx SPI 100k controller driver");
625MODULE_AUTHOR("Fabrice Crohas <fcrohas@gmail.com>"); 505MODULE_AUTHOR("Fabrice Crohas <fcrohas@gmail.com>");