aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi_s3c64xx.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 6d03d8f2de6d..3acf38119e96 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -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,6 +158,7 @@
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;
@@ -389,7 +391,6 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
389 391
390static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 392static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
391{ 393{
392 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
393 void __iomem *regs = sdd->regs; 394 void __iomem *regs = sdd->regs;
394 u32 val; 395 u32 val;
395 396
@@ -435,7 +436,7 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
435 /* Configure Clock */ 436 /* Configure Clock */
436 val = readl(regs + S3C64XX_SPI_CLK_CFG); 437 val = readl(regs + S3C64XX_SPI_CLK_CFG);
437 val &= ~S3C64XX_SPI_PSR_MASK; 438 val &= ~S3C64XX_SPI_PSR_MASK;
438 val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1) 439 val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1)
439 & S3C64XX_SPI_PSR_MASK); 440 & S3C64XX_SPI_PSR_MASK);
440 writel(val, regs + S3C64XX_SPI_CLK_CFG); 441 writel(val, regs + S3C64XX_SPI_CLK_CFG);
441 442
@@ -831,17 +832,17 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
831 } 832 }
832 833
833 /* Check if we can provide the requested rate */ 834 /* Check if we can provide the requested rate */
834 speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */ 835 speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1); /* Max possible */
835 836
836 if (spi->max_speed_hz > speed) 837 if (spi->max_speed_hz > speed)
837 spi->max_speed_hz = speed; 838 spi->max_speed_hz = speed;
838 839
839 psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1; 840 psr = clk_get_rate(sdd->src_clk) / 2 / spi->max_speed_hz - 1;
840 psr &= S3C64XX_SPI_PSR_MASK; 841 psr &= S3C64XX_SPI_PSR_MASK;
841 if (psr == S3C64XX_SPI_PSR_MASK) 842 if (psr == S3C64XX_SPI_PSR_MASK)
842 psr--; 843 psr--;
843 844
844 speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); 845 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
845 if (spi->max_speed_hz < speed) { 846 if (spi->max_speed_hz < speed) {
846 if (psr+1 < S3C64XX_SPI_PSR_MASK) { 847 if (psr+1 < S3C64XX_SPI_PSR_MASK) {
847 psr++; 848 psr++;
@@ -851,7 +852,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
851 } 852 }
852 } 853 }
853 854
854 speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); 855 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
855 if (spi->max_speed_hz >= speed) 856 if (spi->max_speed_hz >= speed)
856 spi->max_speed_hz = speed; 857 spi->max_speed_hz = speed;
857 else 858 else
@@ -1000,15 +1001,15 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1000 goto err4; 1001 goto err4;
1001 } 1002 }
1002 1003
1003 sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name); 1004 sdd->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
1004 if (IS_ERR(sci->src_clk)) { 1005 if (IS_ERR(sdd->src_clk)) {
1005 dev_err(&pdev->dev, 1006 dev_err(&pdev->dev,
1006 "Unable to acquire clock '%s'\n", sci->src_clk_name); 1007 "Unable to acquire clock '%s'\n", sci->src_clk_name);
1007 ret = PTR_ERR(sci->src_clk); 1008 ret = PTR_ERR(sdd->src_clk);
1008 goto err5; 1009 goto err5;
1009 } 1010 }
1010 1011
1011 if (clk_enable(sci->src_clk)) { 1012 if (clk_enable(sdd->src_clk)) {
1012 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", 1013 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n",
1013 sci->src_clk_name); 1014 sci->src_clk_name);
1014 ret = -EBUSY; 1015 ret = -EBUSY;
@@ -1050,9 +1051,9 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1050err8: 1051err8:
1051 destroy_workqueue(sdd->workqueue); 1052 destroy_workqueue(sdd->workqueue);
1052err7: 1053err7:
1053 clk_disable(sci->src_clk); 1054 clk_disable(sdd->src_clk);
1054err6: 1055err6:
1055 clk_put(sci->src_clk); 1056 clk_put(sdd->src_clk);
1056err5: 1057err5:
1057 clk_disable(sdd->clk); 1058 clk_disable(sdd->clk);
1058err4: 1059err4:
@@ -1073,7 +1074,6 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1073{ 1074{
1074 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1075 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1075 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1076 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1076 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
1077 struct resource *mem_res; 1077 struct resource *mem_res;
1078 unsigned long flags; 1078 unsigned long flags;
1079 1079
@@ -1088,8 +1088,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1088 1088
1089 destroy_workqueue(sdd->workqueue); 1089 destroy_workqueue(sdd->workqueue);
1090 1090
1091 clk_disable(sci->src_clk); 1091 clk_disable(sdd->src_clk);
1092 clk_put(sci->src_clk); 1092 clk_put(sdd->src_clk);
1093 1093
1094 clk_disable(sdd->clk); 1094 clk_disable(sdd->clk);
1095 clk_put(sdd->clk); 1095 clk_put(sdd->clk);
@@ -1110,8 +1110,6 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
1110{ 1110{
1111 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1111 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1112 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1112 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1113 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
1114 struct s3c64xx_spi_csinfo *cs;
1115 unsigned long flags; 1113 unsigned long flags;
1116 1114
1117 spin_lock_irqsave(&sdd->lock, flags); 1115 spin_lock_irqsave(&sdd->lock, flags);
@@ -1122,7 +1120,7 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
1122 msleep(10); 1120 msleep(10);
1123 1121
1124 /* Disable the clock */ 1122 /* Disable the clock */
1125 clk_disable(sci->src_clk); 1123 clk_disable(sdd->src_clk);
1126 clk_disable(sdd->clk); 1124 clk_disable(sdd->clk);
1127 1125
1128 sdd->cur_speed = 0; /* Output Clock is stopped */ 1126 sdd->cur_speed = 0; /* Output Clock is stopped */
@@ -1140,7 +1138,7 @@ static int s3c64xx_spi_resume(struct platform_device *pdev)
1140 sci->cfg_gpio(pdev); 1138 sci->cfg_gpio(pdev);
1141 1139
1142 /* Enable the clock */ 1140 /* Enable the clock */
1143 clk_enable(sci->src_clk); 1141 clk_enable(sdd->src_clk);
1144 clk_enable(sdd->clk); 1142 clk_enable(sdd->clk);
1145 1143
1146 s3c64xx_spi_hwinit(sdd, pdev->id); 1144 s3c64xx_spi_hwinit(sdd, pdev->id);