aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2008-07-05 04:02:46 -0400
committerRobert Schwebel <r.schwebel@pengutronix.de>2008-07-05 04:02:46 -0400
commit38a41fdf94c449c165213e4665c3f8a0d30f8aba (patch)
treecde7f6c0da8c9877736a6b66f245e163fa21c2f7 /drivers/spi
parentdbff4e9ea2e83fda89143389bfb229cb29425a32 (diff)
IMX: introduce clock API
This patch introduces the clock API for i.MX and converts all in-Kernel drivers to use it. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi_imx.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index c730d05bfeb6..bd0729b6b6ed 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -29,6 +29,7 @@
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/clk.h>
32 33
33#include <asm/io.h> 34#include <asm/io.h>
34#include <asm/irq.h> 35#include <asm/irq.h>
@@ -250,6 +251,8 @@ struct driver_data {
250 int tx_dma_needs_unmap; 251 int tx_dma_needs_unmap;
251 size_t tx_map_len; 252 size_t tx_map_len;
252 u32 dummy_dma_buf ____cacheline_aligned; 253 u32 dummy_dma_buf ____cacheline_aligned;
254
255 struct clk *clk;
253}; 256};
254 257
255/* Runtime state */ 258/* Runtime state */
@@ -855,15 +858,15 @@ static irqreturn_t spi_int(int irq, void *dev_id)
855 return drv_data->transfer_handler(drv_data); 858 return drv_data->transfer_handler(drv_data);
856} 859}
857 860
858static inline u32 spi_speed_hz(u32 data_rate) 861static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate)
859{ 862{
860 return imx_get_perclk2() / (4 << ((data_rate) >> 13)); 863 return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13));
861} 864}
862 865
863static u32 spi_data_rate(u32 speed_hz) 866static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz)
864{ 867{
865 u32 div; 868 u32 div;
866 u32 quantized_hz = imx_get_perclk2() >> 2; 869 u32 quantized_hz = clk_get_rate(drv_data->clk) >> 2;
867 870
868 for (div = SPI_PERCLK2_DIV_MIN; 871 for (div = SPI_PERCLK2_DIV_MIN;
869 div <= SPI_PERCLK2_DIV_MAX; 872 div <= SPI_PERCLK2_DIV_MAX;
@@ -947,7 +950,7 @@ static void pump_transfers(unsigned long data)
947 tmp = transfer->speed_hz; 950 tmp = transfer->speed_hz;
948 if (tmp == 0) 951 if (tmp == 0)
949 tmp = chip->max_speed_hz; 952 tmp = chip->max_speed_hz;
950 tmp = spi_data_rate(tmp); 953 tmp = spi_data_rate(drv_data, tmp);
951 u32_EDIT(control, SPI_CONTROL_DATARATE, tmp); 954 u32_EDIT(control, SPI_CONTROL_DATARATE, tmp);
952 955
953 writel(control, regs + SPI_CONTROL); 956 writel(control, regs + SPI_CONTROL);
@@ -1109,7 +1112,7 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
1109 msg->actual_length = 0; 1112 msg->actual_length = 0;
1110 1113
1111 /* Per transfer setup check */ 1114 /* Per transfer setup check */
1112 min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN); 1115 min_speed_hz = spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN);
1113 max_speed_hz = spi->max_speed_hz; 1116 max_speed_hz = spi->max_speed_hz;
1114 list_for_each_entry(trans, &msg->transfers, transfer_list) { 1117 list_for_each_entry(trans, &msg->transfers, transfer_list) {
1115 tmp = trans->bits_per_word; 1118 tmp = trans->bits_per_word;
@@ -1176,6 +1179,7 @@ msg_rejected:
1176 applied and notified to the calling driver. */ 1179 applied and notified to the calling driver. */
1177static int setup(struct spi_device *spi) 1180static int setup(struct spi_device *spi)
1178{ 1181{
1182 struct driver_data *drv_data = spi_master_get_devdata(spi->master);
1179 struct spi_imx_chip *chip_info; 1183 struct spi_imx_chip *chip_info;
1180 struct chip_data *chip; 1184 struct chip_data *chip;
1181 int first_setup = 0; 1185 int first_setup = 0;
@@ -1304,14 +1308,14 @@ static int setup(struct spi_device *spi)
1304 chip->n_bytes = (tmp <= 8) ? 1 : 2; 1308 chip->n_bytes = (tmp <= 8) ? 1 : 2;
1305 1309
1306 /* SPI datarate */ 1310 /* SPI datarate */
1307 tmp = spi_data_rate(spi->max_speed_hz); 1311 tmp = spi_data_rate(drv_data, spi->max_speed_hz);
1308 if (tmp == SPI_CONTROL_DATARATE_BAD) { 1312 if (tmp == SPI_CONTROL_DATARATE_BAD) {
1309 status = -EINVAL; 1313 status = -EINVAL;
1310 dev_err(&spi->dev, 1314 dev_err(&spi->dev,
1311 "setup - " 1315 "setup - "
1312 "HW min speed (%d Hz) exceeds required " 1316 "HW min speed (%d Hz) exceeds required "
1313 "max speed (%d Hz)\n", 1317 "max speed (%d Hz)\n",
1314 spi_speed_hz(SPI_CONTROL_DATARATE_MIN), 1318 spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN),
1315 spi->max_speed_hz); 1319 spi->max_speed_hz);
1316 if (first_setup) 1320 if (first_setup)
1317 goto err_first_setup; 1321 goto err_first_setup;
@@ -1321,7 +1325,7 @@ static int setup(struct spi_device *spi)
1321 } else { 1325 } else {
1322 u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp); 1326 u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp);
1323 /* Actual rounded max_speed_hz */ 1327 /* Actual rounded max_speed_hz */
1324 tmp = spi_speed_hz(tmp); 1328 tmp = spi_speed_hz(drv_data, tmp);
1325 spi->max_speed_hz = tmp; 1329 spi->max_speed_hz = tmp;
1326 chip->max_speed_hz = tmp; 1330 chip->max_speed_hz = tmp;
1327 } 1331 }
@@ -1352,7 +1356,7 @@ static int setup(struct spi_device *spi)
1352 chip->period & SPI_PERIOD_WAIT, 1356 chip->period & SPI_PERIOD_WAIT,
1353 spi->mode, 1357 spi->mode,
1354 spi->bits_per_word, 1358 spi->bits_per_word,
1355 spi_speed_hz(SPI_CONTROL_DATARATE_MIN), 1359 spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN),
1356 spi->max_speed_hz); 1360 spi->max_speed_hz);
1357 return status; 1361 return status;
1358 1362
@@ -1465,6 +1469,14 @@ static int __init spi_imx_probe(struct platform_device *pdev)
1465 goto err_no_pdata; 1469 goto err_no_pdata;
1466 } 1470 }
1467 1471
1472 drv_data->clk = clk_get(&pdev->dev, "perclk2");
1473 if (IS_ERR(drv_data->clk)) {
1474 dev_err(&pdev->dev, "probe - cannot get get\n");
1475 status = PTR_ERR(drv_data->clk);
1476 goto err_no_clk;
1477 }
1478 clk_enable(drv_data->clk);
1479
1468 /* Allocate master with space for drv_data */ 1480 /* Allocate master with space for drv_data */
1469 master = spi_alloc_master(dev, sizeof(struct driver_data)); 1481 master = spi_alloc_master(dev, sizeof(struct driver_data));
1470 if (!master) { 1482 if (!master) {
@@ -1623,6 +1635,9 @@ err_no_iores:
1623 spi_master_put(master); 1635 spi_master_put(master);
1624 1636
1625err_no_pdata: 1637err_no_pdata:
1638 clk_disable(drv_data->clk);
1639 clk_put(drv_data->clk);
1640err_no_clk:
1626err_no_mem: 1641err_no_mem:
1627 return status; 1642 return status;
1628} 1643}
@@ -1662,6 +1677,9 @@ static int __exit spi_imx_remove(struct platform_device *pdev)
1662 if (irq >= 0) 1677 if (irq >= 0)
1663 free_irq(irq, drv_data); 1678 free_irq(irq, drv_data);
1664 1679
1680 clk_disable(drv_data->clk);
1681 clk_put(drv_data->clk);
1682
1665 /* Release map resources */ 1683 /* Release map resources */
1666 iounmap(drv_data->regs); 1684 iounmap(drv_data->regs);
1667 release_resource(drv_data->ioarea); 1685 release_resource(drv_data->ioarea);