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.c89
1 files changed, 38 insertions, 51 deletions
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 88a456dba967..97365815a729 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -28,7 +28,7 @@
28#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
29 29
30#include <mach/dma.h> 30#include <mach/dma.h>
31#include <plat/spi.h> 31#include <plat/s3c64xx-spi.h>
32 32
33/* Registers and bit-fields */ 33/* Registers and bit-fields */
34 34
@@ -137,6 +137,7 @@
137/** 137/**
138 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. 138 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
139 * @clk: Pointer to the spi clock. 139 * @clk: Pointer to the spi clock.
140 * @src_clk: Pointer to the clock used to generate SPI signals.
140 * @master: Pointer to the SPI Protocol master. 141 * @master: Pointer to the SPI Protocol master.
141 * @workqueue: Work queue for the SPI xfer requests. 142 * @workqueue: Work queue for the SPI xfer requests.
142 * @cntrlr_info: Platform specific data for the controller this driver manages. 143 * @cntrlr_info: Platform specific data for the controller this driver manages.
@@ -157,10 +158,11 @@
157struct s3c64xx_spi_driver_data { 158struct s3c64xx_spi_driver_data {
158 void __iomem *regs; 159 void __iomem *regs;
159 struct clk *clk; 160 struct clk *clk;
161 struct clk *src_clk;
160 struct platform_device *pdev; 162 struct platform_device *pdev;
161 struct spi_master *master; 163 struct spi_master *master;
162 struct workqueue_struct *workqueue; 164 struct workqueue_struct *workqueue;
163 struct s3c64xx_spi_cntrlr_info *cntrlr_info; 165 struct s3c64xx_spi_info *cntrlr_info;
164 struct spi_device *tgl_spi; 166 struct spi_device *tgl_spi;
165 struct work_struct work; 167 struct work_struct work;
166 struct list_head queue; 168 struct list_head queue;
@@ -180,7 +182,7 @@ static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
180 182
181static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) 183static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
182{ 184{
183 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 185 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
184 void __iomem *regs = sdd->regs; 186 void __iomem *regs = sdd->regs;
185 unsigned long loops; 187 unsigned long loops;
186 u32 val; 188 u32 val;
@@ -225,7 +227,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
225 struct spi_device *spi, 227 struct spi_device *spi,
226 struct spi_transfer *xfer, int dma_mode) 228 struct spi_transfer *xfer, int dma_mode)
227{ 229{
228 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 230 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
229 void __iomem *regs = sdd->regs; 231 void __iomem *regs = sdd->regs;
230 u32 modecfg, chcfg; 232 u32 modecfg, chcfg;
231 233
@@ -298,19 +300,20 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
298 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 300 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
299 /* Deselect the last toggled device */ 301 /* Deselect the last toggled device */
300 cs = sdd->tgl_spi->controller_data; 302 cs = sdd->tgl_spi->controller_data;
301 cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); 303 cs->set_level(cs->line,
304 spi->mode & SPI_CS_HIGH ? 0 : 1);
302 } 305 }
303 sdd->tgl_spi = NULL; 306 sdd->tgl_spi = NULL;
304 } 307 }
305 308
306 cs = spi->controller_data; 309 cs = spi->controller_data;
307 cs->set_level(spi->mode & SPI_CS_HIGH ? 1 : 0); 310 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
308} 311}
309 312
310static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, 313static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
311 struct spi_transfer *xfer, int dma_mode) 314 struct spi_transfer *xfer, int dma_mode)
312{ 315{
313 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 316 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
314 void __iomem *regs = sdd->regs; 317 void __iomem *regs = sdd->regs;
315 unsigned long val; 318 unsigned long val;
316 int ms; 319 int ms;
@@ -384,12 +387,11 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
384 if (sdd->tgl_spi == spi) 387 if (sdd->tgl_spi == spi)
385 sdd->tgl_spi = NULL; 388 sdd->tgl_spi = NULL;
386 389
387 cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); 390 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
388} 391}
389 392
390static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 393static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
391{ 394{
392 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
393 void __iomem *regs = sdd->regs; 395 void __iomem *regs = sdd->regs;
394 u32 val; 396 u32 val;
395 397
@@ -435,7 +437,7 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
435 /* Configure Clock */ 437 /* Configure Clock */
436 val = readl(regs + S3C64XX_SPI_CLK_CFG); 438 val = readl(regs + S3C64XX_SPI_CLK_CFG);
437 val &= ~S3C64XX_SPI_PSR_MASK; 439 val &= ~S3C64XX_SPI_PSR_MASK;
438 val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1) 440 val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1)
439 & S3C64XX_SPI_PSR_MASK); 441 & S3C64XX_SPI_PSR_MASK);
440 writel(val, regs + S3C64XX_SPI_CLK_CFG); 442 writel(val, regs + S3C64XX_SPI_CLK_CFG);
441 443
@@ -558,7 +560,7 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
558static void handle_msg(struct s3c64xx_spi_driver_data *sdd, 560static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
559 struct spi_message *msg) 561 struct spi_message *msg)
560{ 562{
561 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 563 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
562 struct spi_device *spi = msg->spi; 564 struct spi_device *spi = msg->spi;
563 struct s3c64xx_spi_csinfo *cs = spi->controller_data; 565 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
564 struct spi_transfer *xfer; 566 struct spi_transfer *xfer;
@@ -632,8 +634,8 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
632 S3C64XX_SPI_DEACT(sdd); 634 S3C64XX_SPI_DEACT(sdd);
633 635
634 if (status) { 636 if (status) {
635 dev_err(&spi->dev, "I/O Error: \ 637 dev_err(&spi->dev, "I/O Error: "
636 rx-%d tx-%d res:rx-%c tx-%c len-%d\n", 638 "rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
637 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, 639 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
638 (sdd->state & RXBUSY) ? 'f' : 'p', 640 (sdd->state & RXBUSY) ? 'f' : 'p',
639 (sdd->state & TXBUSY) ? 'f' : 'p', 641 (sdd->state & TXBUSY) ? 'f' : 'p',
@@ -786,7 +788,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
786{ 788{
787 struct s3c64xx_spi_csinfo *cs = spi->controller_data; 789 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
788 struct s3c64xx_spi_driver_data *sdd; 790 struct s3c64xx_spi_driver_data *sdd;
789 struct s3c64xx_spi_cntrlr_info *sci; 791 struct s3c64xx_spi_info *sci;
790 struct spi_message *msg; 792 struct spi_message *msg;
791 u32 psr, speed; 793 u32 psr, speed;
792 unsigned long flags; 794 unsigned long flags;
@@ -831,17 +833,17 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
831 } 833 }
832 834
833 /* Check if we can provide the requested rate */ 835 /* Check if we can provide the requested rate */
834 speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */ 836 speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1); /* Max possible */
835 837
836 if (spi->max_speed_hz > speed) 838 if (spi->max_speed_hz > speed)
837 spi->max_speed_hz = speed; 839 spi->max_speed_hz = speed;
838 840
839 psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1; 841 psr = clk_get_rate(sdd->src_clk) / 2 / spi->max_speed_hz - 1;
840 psr &= S3C64XX_SPI_PSR_MASK; 842 psr &= S3C64XX_SPI_PSR_MASK;
841 if (psr == S3C64XX_SPI_PSR_MASK) 843 if (psr == S3C64XX_SPI_PSR_MASK)
842 psr--; 844 psr--;
843 845
844 speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); 846 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
845 if (spi->max_speed_hz < speed) { 847 if (spi->max_speed_hz < speed) {
846 if (psr+1 < S3C64XX_SPI_PSR_MASK) { 848 if (psr+1 < S3C64XX_SPI_PSR_MASK) {
847 psr++; 849 psr++;
@@ -851,7 +853,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
851 } 853 }
852 } 854 }
853 855
854 speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); 856 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
855 if (spi->max_speed_hz >= speed) 857 if (spi->max_speed_hz >= speed)
856 spi->max_speed_hz = speed; 858 spi->max_speed_hz = speed;
857 else 859 else
@@ -867,7 +869,7 @@ setup_exit:
867 869
868static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) 870static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
869{ 871{
870 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 872 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
871 void __iomem *regs = sdd->regs; 873 void __iomem *regs = sdd->regs;
872 unsigned int val; 874 unsigned int val;
873 875
@@ -902,7 +904,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
902{ 904{
903 struct resource *mem_res, *dmatx_res, *dmarx_res; 905 struct resource *mem_res, *dmatx_res, *dmarx_res;
904 struct s3c64xx_spi_driver_data *sdd; 906 struct s3c64xx_spi_driver_data *sdd;
905 struct s3c64xx_spi_cntrlr_info *sci; 907 struct s3c64xx_spi_info *sci;
906 struct spi_master *master; 908 struct spi_master *master;
907 int ret; 909 int ret;
908 910
@@ -1000,18 +1002,15 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1000 goto err4; 1002 goto err4;
1001 } 1003 }
1002 1004
1003 if (sci->src_clk_nr == S3C64XX_SPI_SRCCLK_PCLK) 1005 sdd->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
1004 sci->src_clk = sdd->clk; 1006 if (IS_ERR(sdd->src_clk)) {
1005 else
1006 sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
1007 if (IS_ERR(sci->src_clk)) {
1008 dev_err(&pdev->dev, 1007 dev_err(&pdev->dev,
1009 "Unable to acquire clock '%s'\n", sci->src_clk_name); 1008 "Unable to acquire clock '%s'\n", sci->src_clk_name);
1010 ret = PTR_ERR(sci->src_clk); 1009 ret = PTR_ERR(sdd->src_clk);
1011 goto err5; 1010 goto err5;
1012 } 1011 }
1013 1012
1014 if (sci->src_clk != sdd->clk && clk_enable(sci->src_clk)) { 1013 if (clk_enable(sdd->src_clk)) {
1015 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", 1014 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n",
1016 sci->src_clk_name); 1015 sci->src_clk_name);
1017 ret = -EBUSY; 1016 ret = -EBUSY;
@@ -1040,11 +1039,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1040 goto err8; 1039 goto err8;
1041 } 1040 }
1042 1041
1043 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d \ 1042 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
1044 with %d Slaves attached\n", 1043 "with %d Slaves attached\n",
1045 pdev->id, master->num_chipselect); 1044 pdev->id, master->num_chipselect);
1046 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\ 1045 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
1047 \tDMA=[Rx-%d, Tx-%d]\n",
1048 mem_res->end, mem_res->start, 1046 mem_res->end, mem_res->start,
1049 sdd->rx_dmach, sdd->tx_dmach); 1047 sdd->rx_dmach, sdd->tx_dmach);
1050 1048
@@ -1053,11 +1051,9 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1053err8: 1051err8:
1054 destroy_workqueue(sdd->workqueue); 1052 destroy_workqueue(sdd->workqueue);
1055err7: 1053err7:
1056 if (sci->src_clk != sdd->clk) 1054 clk_disable(sdd->src_clk);
1057 clk_disable(sci->src_clk);
1058err6: 1055err6:
1059 if (sci->src_clk != sdd->clk) 1056 clk_put(sdd->src_clk);
1060 clk_put(sci->src_clk);
1061err5: 1057err5:
1062 clk_disable(sdd->clk); 1058 clk_disable(sdd->clk);
1063err4: 1059err4:
@@ -1078,7 +1074,6 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1078{ 1074{
1079 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1075 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1080 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1076 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1081 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
1082 struct resource *mem_res; 1077 struct resource *mem_res;
1083 unsigned long flags; 1078 unsigned long flags;
1084 1079
@@ -1093,11 +1088,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1093 1088
1094 destroy_workqueue(sdd->workqueue); 1089 destroy_workqueue(sdd->workqueue);
1095 1090
1096 if (sci->src_clk != sdd->clk) 1091 clk_disable(sdd->src_clk);
1097 clk_disable(sci->src_clk); 1092 clk_put(sdd->src_clk);
1098
1099 if (sci->src_clk != sdd->clk)
1100 clk_put(sci->src_clk);
1101 1093
1102 clk_disable(sdd->clk); 1094 clk_disable(sdd->clk);
1103 clk_put(sdd->clk); 1095 clk_put(sdd->clk);
@@ -1105,7 +1097,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1105 iounmap((void *) sdd->regs); 1097 iounmap((void *) sdd->regs);
1106 1098
1107 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1099 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1108 release_mem_region(mem_res->start, resource_size(mem_res)); 1100 if (mem_res != NULL)
1101 release_mem_region(mem_res->start, resource_size(mem_res));
1109 1102
1110 platform_set_drvdata(pdev, NULL); 1103 platform_set_drvdata(pdev, NULL);
1111 spi_master_put(master); 1104 spi_master_put(master);
@@ -1118,8 +1111,6 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
1118{ 1111{
1119 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1112 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1120 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1113 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1121 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
1122 struct s3c64xx_spi_csinfo *cs;
1123 unsigned long flags; 1114 unsigned long flags;
1124 1115
1125 spin_lock_irqsave(&sdd->lock, flags); 1116 spin_lock_irqsave(&sdd->lock, flags);
@@ -1130,9 +1121,7 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
1130 msleep(10); 1121 msleep(10);
1131 1122
1132 /* Disable the clock */ 1123 /* Disable the clock */
1133 if (sci->src_clk != sdd->clk) 1124 clk_disable(sdd->src_clk);
1134 clk_disable(sci->src_clk);
1135
1136 clk_disable(sdd->clk); 1125 clk_disable(sdd->clk);
1137 1126
1138 sdd->cur_speed = 0; /* Output Clock is stopped */ 1127 sdd->cur_speed = 0; /* Output Clock is stopped */
@@ -1144,15 +1133,13 @@ static int s3c64xx_spi_resume(struct platform_device *pdev)
1144{ 1133{
1145 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1134 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1146 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1135 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1147 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 1136 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
1148 unsigned long flags; 1137 unsigned long flags;
1149 1138
1150 sci->cfg_gpio(pdev); 1139 sci->cfg_gpio(pdev);
1151 1140
1152 /* Enable the clock */ 1141 /* Enable the clock */
1153 if (sci->src_clk != sdd->clk) 1142 clk_enable(sdd->src_clk);
1154 clk_enable(sci->src_clk);
1155
1156 clk_enable(sdd->clk); 1143 clk_enable(sdd->clk);
1157 1144
1158 s3c64xx_spi_hwinit(sdd, pdev->id); 1145 s3c64xx_spi_hwinit(sdd, pdev->id);