aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-s3c64xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-s3c64xx.c')
-rw-r--r--drivers/spi/spi-s3c64xx.c264
1 files changed, 128 insertions, 136 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 512b8893893b..4c4b0a1219a7 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -205,7 +205,6 @@ struct s3c64xx_spi_driver_data {
205#endif 205#endif
206 struct s3c64xx_spi_port_config *port_conf; 206 struct s3c64xx_spi_port_config *port_conf;
207 unsigned int port_id; 207 unsigned int port_id;
208 unsigned long gpios[4];
209 bool cs_gpio; 208 bool cs_gpio;
210}; 209};
211 210
@@ -559,25 +558,18 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
559static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, 558static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
560 struct spi_device *spi) 559 struct spi_device *spi)
561{ 560{
562 struct s3c64xx_spi_csinfo *cs;
563
564 if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ 561 if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */
565 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 562 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
566 /* Deselect the last toggled device */ 563 /* Deselect the last toggled device */
567 cs = sdd->tgl_spi->controller_data; 564 if (spi->cs_gpio >= 0)
568 if (sdd->cs_gpio) 565 gpio_set_value(spi->cs_gpio,
569 gpio_set_value(cs->line,
570 spi->mode & SPI_CS_HIGH ? 0 : 1); 566 spi->mode & SPI_CS_HIGH ? 0 : 1);
571 } 567 }
572 sdd->tgl_spi = NULL; 568 sdd->tgl_spi = NULL;
573 } 569 }
574 570
575 cs = spi->controller_data; 571 if (spi->cs_gpio >= 0)
576 if (sdd->cs_gpio) 572 gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 1 : 0);
577 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
578
579 /* Start the signals */
580 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
581} 573}
582 574
583static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, 575static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
@@ -702,16 +694,11 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
702static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, 694static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
703 struct spi_device *spi) 695 struct spi_device *spi)
704{ 696{
705 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
706
707 if (sdd->tgl_spi == spi) 697 if (sdd->tgl_spi == spi)
708 sdd->tgl_spi = NULL; 698 sdd->tgl_spi = NULL;
709 699
710 if (sdd->cs_gpio) 700 if (spi->cs_gpio >= 0)
711 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); 701 gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
712
713 /* Quiese the signals */
714 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
715} 702}
716 703
717static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 704static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
@@ -862,16 +849,12 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
862 } 849 }
863} 850}
864 851
865static int s3c64xx_spi_transfer_one_message(struct spi_master *master, 852static int s3c64xx_spi_prepare_message(struct spi_master *master,
866 struct spi_message *msg) 853 struct spi_message *msg)
867{ 854{
868 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 855 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
869 struct spi_device *spi = msg->spi; 856 struct spi_device *spi = msg->spi;
870 struct s3c64xx_spi_csinfo *cs = spi->controller_data; 857 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
871 struct spi_transfer *xfer;
872 int status = 0, cs_toggle = 0;
873 u32 speed;
874 u8 bpw;
875 858
876 /* If Master's(controller) state differs from that needed by Slave */ 859 /* If Master's(controller) state differs from that needed by Slave */
877 if (sdd->cur_speed != spi->max_speed_hz 860 if (sdd->cur_speed != spi->max_speed_hz
@@ -887,106 +870,98 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
887 if (s3c64xx_spi_map_mssg(sdd, msg)) { 870 if (s3c64xx_spi_map_mssg(sdd, msg)) {
888 dev_err(&spi->dev, 871 dev_err(&spi->dev,
889 "Xfer: Unable to map message buffers!\n"); 872 "Xfer: Unable to map message buffers!\n");
890 status = -ENOMEM; 873 return -ENOMEM;
891 goto out;
892 } 874 }
893 875
894 /* Configure feedback delay */ 876 /* Configure feedback delay */
895 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); 877 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
896 878
897 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 879 return 0;
898 880}
899 unsigned long flags;
900 int use_dma;
901
902 INIT_COMPLETION(sdd->xfer_completion);
903
904 /* Only BPW and Speed may change across transfers */
905 bpw = xfer->bits_per_word;
906 speed = xfer->speed_hz ? : spi->max_speed_hz;
907
908 if (xfer->len % (bpw / 8)) {
909 dev_err(&spi->dev,
910 "Xfer length(%u) not a multiple of word size(%u)\n",
911 xfer->len, bpw / 8);
912 status = -EIO;
913 goto out;
914 }
915 881
916 if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { 882static int s3c64xx_spi_transfer_one(struct spi_master *master,
917 sdd->cur_bpw = bpw; 883 struct spi_device *spi,
918 sdd->cur_speed = speed; 884 struct spi_transfer *xfer)
919 s3c64xx_spi_config(sdd); 885{
920 } 886 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
887 int status;
888 u32 speed;
889 u8 bpw;
890 unsigned long flags;
891 int use_dma;
921 892
922 /* Polling method for xfers not bigger than FIFO capacity */ 893 reinit_completion(&sdd->xfer_completion);
923 use_dma = 0;
924 if (!is_polling(sdd) &&
925 (sdd->rx_dma.ch && sdd->tx_dma.ch &&
926 (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))))
927 use_dma = 1;
928 894
929 spin_lock_irqsave(&sdd->lock, flags); 895 /* Only BPW and Speed may change across transfers */
896 bpw = xfer->bits_per_word;
897 speed = xfer->speed_hz ? : spi->max_speed_hz;
930 898
931 /* Pending only which is to be done */ 899 if (xfer->len % (bpw / 8)) {
932 sdd->state &= ~RXBUSY; 900 dev_err(&spi->dev,
933 sdd->state &= ~TXBUSY; 901 "Xfer length(%u) not a multiple of word size(%u)\n",
902 xfer->len, bpw / 8);
903 return -EIO;
904 }
934 905
935 enable_datapath(sdd, spi, xfer, use_dma); 906 if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
907 sdd->cur_bpw = bpw;
908 sdd->cur_speed = speed;
909 s3c64xx_spi_config(sdd);
910 }
936 911
937 /* Slave Select */ 912 /* Polling method for xfers not bigger than FIFO capacity */
938 enable_cs(sdd, spi); 913 use_dma = 0;
914 if (!is_polling(sdd) &&
915 (sdd->rx_dma.ch && sdd->tx_dma.ch &&
916 (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))))
917 use_dma = 1;
939 918
940 spin_unlock_irqrestore(&sdd->lock, flags); 919 spin_lock_irqsave(&sdd->lock, flags);
941 920
942 status = wait_for_xfer(sdd, xfer, use_dma); 921 /* Pending only which is to be done */
922 sdd->state &= ~RXBUSY;
923 sdd->state &= ~TXBUSY;
943 924
944 if (status) { 925 enable_datapath(sdd, spi, xfer, use_dma);
945 dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
946 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
947 (sdd->state & RXBUSY) ? 'f' : 'p',
948 (sdd->state & TXBUSY) ? 'f' : 'p',
949 xfer->len);
950 926
951 if (use_dma) { 927 /* Start the signals */
952 if (xfer->tx_buf != NULL 928 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
953 && (sdd->state & TXBUSY))
954 s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma);
955 if (xfer->rx_buf != NULL
956 && (sdd->state & RXBUSY))
957 s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma);
958 }
959 929
960 goto out; 930 /* Start the signals */
961 } 931 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
962 932
963 if (xfer->delay_usecs) 933 spin_unlock_irqrestore(&sdd->lock, flags);
964 udelay(xfer->delay_usecs);
965 934
966 if (xfer->cs_change) { 935 status = wait_for_xfer(sdd, xfer, use_dma);
967 /* Hint that the next mssg is gonna be 936
968 for the same device */ 937 if (status) {
969 if (list_is_last(&xfer->transfer_list, 938 dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
970 &msg->transfers)) 939 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
971 cs_toggle = 1; 940 (sdd->state & RXBUSY) ? 'f' : 'p',
941 (sdd->state & TXBUSY) ? 'f' : 'p',
942 xfer->len);
943
944 if (use_dma) {
945 if (xfer->tx_buf != NULL
946 && (sdd->state & TXBUSY))
947 s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma);
948 if (xfer->rx_buf != NULL
949 && (sdd->state & RXBUSY))
950 s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma);
972 } 951 }
973 952 } else {
974 msg->actual_length += xfer->len;
975
976 flush_fifo(sdd); 953 flush_fifo(sdd);
977 } 954 }
978 955
979out: 956 return status;
980 if (!cs_toggle || status) 957}
981 disable_cs(sdd, spi);
982 else
983 sdd->tgl_spi = spi;
984
985 s3c64xx_spi_unmap_mssg(sdd, msg);
986 958
987 msg->status = status; 959static int s3c64xx_spi_unprepare_message(struct spi_master *master,
960 struct spi_message *msg)
961{
962 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
988 963
989 spi_finalize_current_message(master); 964 s3c64xx_spi_unmap_mssg(sdd, msg);
990 965
991 return 0; 966 return 0;
992} 967}
@@ -1071,6 +1046,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
1071 cs->line, err); 1046 cs->line, err);
1072 goto err_gpio_req; 1047 goto err_gpio_req;
1073 } 1048 }
1049
1050 spi->cs_gpio = cs->line;
1074 } 1051 }
1075 1052
1076 spi_set_ctldata(spi, cs); 1053 spi_set_ctldata(spi, cs);
@@ -1117,11 +1094,14 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
1117 } 1094 }
1118 1095
1119 pm_runtime_put(&sdd->pdev->dev); 1096 pm_runtime_put(&sdd->pdev->dev);
1097 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
1120 disable_cs(sdd, spi); 1098 disable_cs(sdd, spi);
1121 return 0; 1099 return 0;
1122 1100
1123setup_exit: 1101setup_exit:
1102 pm_runtime_put(&sdd->pdev->dev);
1124 /* setup() returns with device de-selected */ 1103 /* setup() returns with device de-selected */
1104 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
1125 disable_cs(sdd, spi); 1105 disable_cs(sdd, spi);
1126 1106
1127 gpio_free(cs->line); 1107 gpio_free(cs->line);
@@ -1140,8 +1120,8 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi)
1140 struct s3c64xx_spi_driver_data *sdd; 1120 struct s3c64xx_spi_driver_data *sdd;
1141 1121
1142 sdd = spi_master_get_devdata(spi->master); 1122 sdd = spi_master_get_devdata(spi->master);
1143 if (cs && sdd->cs_gpio) { 1123 if (spi->cs_gpio) {
1144 gpio_free(cs->line); 1124 gpio_free(spi->cs_gpio);
1145 if (spi->dev.of_node) 1125 if (spi->dev.of_node)
1146 kfree(cs); 1126 kfree(cs);
1147 } 1127 }
@@ -1359,7 +1339,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
1359 master->setup = s3c64xx_spi_setup; 1339 master->setup = s3c64xx_spi_setup;
1360 master->cleanup = s3c64xx_spi_cleanup; 1340 master->cleanup = s3c64xx_spi_cleanup;
1361 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; 1341 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
1362 master->transfer_one_message = s3c64xx_spi_transfer_one_message; 1342 master->prepare_message = s3c64xx_spi_prepare_message;
1343 master->transfer_one = s3c64xx_spi_transfer_one;
1344 master->unprepare_message = s3c64xx_spi_unprepare_message;
1363 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; 1345 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
1364 master->num_chipselect = sci->num_cs; 1346 master->num_chipselect = sci->num_cs;
1365 master->dma_alignment = 8; 1347 master->dma_alignment = 8;
@@ -1428,9 +1410,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
1428 S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, 1410 S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
1429 sdd->regs + S3C64XX_SPI_INT_EN); 1411 sdd->regs + S3C64XX_SPI_INT_EN);
1430 1412
1431 if (spi_register_master(master)) { 1413 pm_runtime_set_active(&pdev->dev);
1432 dev_err(&pdev->dev, "cannot register SPI master\n"); 1414 pm_runtime_enable(&pdev->dev);
1433 ret = -EBUSY; 1415
1416 ret = devm_spi_register_master(&pdev->dev, master);
1417 if (ret != 0) {
1418 dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret);
1434 goto err3; 1419 goto err3;
1435 } 1420 }
1436 1421
@@ -1440,8 +1425,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
1440 mem_res, 1425 mem_res,
1441 sdd->rx_dma.dmach, sdd->tx_dma.dmach); 1426 sdd->rx_dma.dmach, sdd->tx_dma.dmach);
1442 1427
1443 pm_runtime_enable(&pdev->dev);
1444
1445 return 0; 1428 return 0;
1446 1429
1447err3: 1430err3:
@@ -1461,16 +1444,12 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1461 1444
1462 pm_runtime_disable(&pdev->dev); 1445 pm_runtime_disable(&pdev->dev);
1463 1446
1464 spi_unregister_master(master);
1465
1466 writel(0, sdd->regs + S3C64XX_SPI_INT_EN); 1447 writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
1467 1448
1468 clk_disable_unprepare(sdd->src_clk); 1449 clk_disable_unprepare(sdd->src_clk);
1469 1450
1470 clk_disable_unprepare(sdd->clk); 1451 clk_disable_unprepare(sdd->clk);
1471 1452
1472 spi_master_put(master);
1473
1474 return 0; 1453 return 0;
1475} 1454}
1476 1455
@@ -1480,11 +1459,14 @@ static int s3c64xx_spi_suspend(struct device *dev)
1480 struct spi_master *master = dev_get_drvdata(dev); 1459 struct spi_master *master = dev_get_drvdata(dev);
1481 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1460 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1482 1461
1483 spi_master_suspend(master); 1462 int ret = spi_master_suspend(master);
1463 if (ret)
1464 return ret;
1484 1465
1485 /* Disable the clock */ 1466 if (!pm_runtime_suspended(dev)) {
1486 clk_disable_unprepare(sdd->src_clk); 1467 clk_disable_unprepare(sdd->clk);
1487 clk_disable_unprepare(sdd->clk); 1468 clk_disable_unprepare(sdd->src_clk);
1469 }
1488 1470
1489 sdd->cur_speed = 0; /* Output Clock is stopped */ 1471 sdd->cur_speed = 0; /* Output Clock is stopped */
1490 1472
@@ -1500,15 +1482,14 @@ static int s3c64xx_spi_resume(struct device *dev)
1500 if (sci->cfg_gpio) 1482 if (sci->cfg_gpio)
1501 sci->cfg_gpio(); 1483 sci->cfg_gpio();
1502 1484
1503 /* Enable the clock */ 1485 if (!pm_runtime_suspended(dev)) {
1504 clk_prepare_enable(sdd->src_clk); 1486 clk_prepare_enable(sdd->src_clk);
1505 clk_prepare_enable(sdd->clk); 1487 clk_prepare_enable(sdd->clk);
1488 }
1506 1489
1507 s3c64xx_spi_hwinit(sdd, sdd->port_id); 1490 s3c64xx_spi_hwinit(sdd, sdd->port_id);
1508 1491
1509 spi_master_resume(master); 1492 return spi_master_resume(master);
1510
1511 return 0;
1512} 1493}
1513#endif /* CONFIG_PM_SLEEP */ 1494#endif /* CONFIG_PM_SLEEP */
1514 1495
@@ -1528,9 +1509,17 @@ static int s3c64xx_spi_runtime_resume(struct device *dev)
1528{ 1509{
1529 struct spi_master *master = dev_get_drvdata(dev); 1510 struct spi_master *master = dev_get_drvdata(dev);
1530 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1511 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1512 int ret;
1531 1513
1532 clk_prepare_enable(sdd->src_clk); 1514 ret = clk_prepare_enable(sdd->src_clk);
1533 clk_prepare_enable(sdd->clk); 1515 if (ret != 0)
1516 return ret;
1517
1518 ret = clk_prepare_enable(sdd->clk);
1519 if (ret != 0) {
1520 clk_disable_unprepare(sdd->src_clk);
1521 return ret;
1522 }
1534 1523
1535 return 0; 1524 return 0;
1536} 1525}
@@ -1616,6 +1605,18 @@ static struct platform_device_id s3c64xx_spi_driver_ids[] = {
1616}; 1605};
1617 1606
1618static const struct of_device_id s3c64xx_spi_dt_match[] = { 1607static const struct of_device_id s3c64xx_spi_dt_match[] = {
1608 { .compatible = "samsung,s3c2443-spi",
1609 .data = (void *)&s3c2443_spi_port_config,
1610 },
1611 { .compatible = "samsung,s3c6410-spi",
1612 .data = (void *)&s3c6410_spi_port_config,
1613 },
1614 { .compatible = "samsung,s5pc100-spi",
1615 .data = (void *)&s5pc100_spi_port_config,
1616 },
1617 { .compatible = "samsung,s5pv210-spi",
1618 .data = (void *)&s5pv210_spi_port_config,
1619 },
1619 { .compatible = "samsung,exynos4210-spi", 1620 { .compatible = "samsung,exynos4210-spi",
1620 .data = (void *)&exynos4_spi_port_config, 1621 .data = (void *)&exynos4_spi_port_config,
1621 }, 1622 },
@@ -1633,22 +1634,13 @@ static struct platform_driver s3c64xx_spi_driver = {
1633 .pm = &s3c64xx_spi_pm, 1634 .pm = &s3c64xx_spi_pm,
1634 .of_match_table = of_match_ptr(s3c64xx_spi_dt_match), 1635 .of_match_table = of_match_ptr(s3c64xx_spi_dt_match),
1635 }, 1636 },
1637 .probe = s3c64xx_spi_probe,
1636 .remove = s3c64xx_spi_remove, 1638 .remove = s3c64xx_spi_remove,
1637 .id_table = s3c64xx_spi_driver_ids, 1639 .id_table = s3c64xx_spi_driver_ids,
1638}; 1640};
1639MODULE_ALIAS("platform:s3c64xx-spi"); 1641MODULE_ALIAS("platform:s3c64xx-spi");
1640 1642
1641static int __init s3c64xx_spi_init(void) 1643module_platform_driver(s3c64xx_spi_driver);
1642{
1643 return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe);
1644}
1645subsys_initcall(s3c64xx_spi_init);
1646
1647static void __exit s3c64xx_spi_exit(void)
1648{
1649 platform_driver_unregister(&s3c64xx_spi_driver);
1650}
1651module_exit(s3c64xx_spi_exit);
1652 1644
1653MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>"); 1645MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1654MODULE_DESCRIPTION("S3C64XX SPI Controller Driver"); 1646MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");