aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-15 01:44:51 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-15 01:44:51 -0400
commit43d2548bb2ef7e6d753f91468a746784041e522d (patch)
tree77d13fcd48fd998393abb825ec36e2b732684a73 /drivers/spi
parent585583d95c5660973bc0cf64add517b040acd8a4 (diff)
parent85082fd7cbe3173198aac0eb5e85ab1edcc6352c (diff)
Merge commit '85082fd7cbe3173198aac0eb5e85ab1edcc6352c' into test-build
Manual fixup of: arch/powerpc/Kconfig
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi_imx.c54
-rw-r--r--drivers/spi/spidev.c3
2 files changed, 39 insertions, 18 deletions
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index c730d05bfeb6..54ac7bea5f8c 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) {
@@ -1526,24 +1538,24 @@ static int __init spi_imx_probe(struct platform_device *pdev)
1526 drv_data->rx_channel = -1; 1538 drv_data->rx_channel = -1;
1527 if (platform_info->enable_dma) { 1539 if (platform_info->enable_dma) {
1528 /* Get rx DMA channel */ 1540 /* Get rx DMA channel */
1529 status = imx_dma_request_by_prio(&drv_data->rx_channel, 1541 drv_data->rx_channel = imx_dma_request_by_prio("spi_imx_rx",
1530 "spi_imx_rx", DMA_PRIO_HIGH); 1542 DMA_PRIO_HIGH);
1531 if (status < 0) { 1543 if (drv_data->rx_channel < 0) {
1532 dev_err(dev, 1544 dev_err(dev,
1533 "probe - problem (%d) requesting rx channel\n", 1545 "probe - problem (%d) requesting rx channel\n",
1534 status); 1546 drv_data->rx_channel);
1535 goto err_no_rxdma; 1547 goto err_no_rxdma;
1536 } else 1548 } else
1537 imx_dma_setup_handlers(drv_data->rx_channel, NULL, 1549 imx_dma_setup_handlers(drv_data->rx_channel, NULL,
1538 dma_err_handler, drv_data); 1550 dma_err_handler, drv_data);
1539 1551
1540 /* Get tx DMA channel */ 1552 /* Get tx DMA channel */
1541 status = imx_dma_request_by_prio(&drv_data->tx_channel, 1553 drv_data->tx_channel = imx_dma_request_by_prio("spi_imx_tx",
1542 "spi_imx_tx", DMA_PRIO_MEDIUM); 1554 DMA_PRIO_MEDIUM);
1543 if (status < 0) { 1555 if (drv_data->tx_channel < 0) {
1544 dev_err(dev, 1556 dev_err(dev,
1545 "probe - problem (%d) requesting tx channel\n", 1557 "probe - problem (%d) requesting tx channel\n",
1546 status); 1558 drv_data->tx_channel);
1547 imx_dma_free(drv_data->rx_channel); 1559 imx_dma_free(drv_data->rx_channel);
1548 goto err_no_txdma; 1560 goto err_no_txdma;
1549 } else 1561 } else
@@ -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);
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index f5b60c70389b..ddbe1a5e970e 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -30,6 +30,7 @@
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/smp_lock.h>
33 34
34#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
35#include <linux/spi/spidev.h> 36#include <linux/spi/spidev.h>
@@ -464,6 +465,7 @@ static int spidev_open(struct inode *inode, struct file *filp)
464 struct spidev_data *spidev; 465 struct spidev_data *spidev;
465 int status = -ENXIO; 466 int status = -ENXIO;
466 467
468 lock_kernel();
467 mutex_lock(&device_list_lock); 469 mutex_lock(&device_list_lock);
468 470
469 list_for_each_entry(spidev, &device_list, device_entry) { 471 list_for_each_entry(spidev, &device_list, device_entry) {
@@ -489,6 +491,7 @@ static int spidev_open(struct inode *inode, struct file *filp)
489 pr_debug("spidev: nothing for minor %d\n", iminor(inode)); 491 pr_debug("spidev: nothing for minor %d\n", iminor(inode));
490 492
491 mutex_unlock(&device_list_lock); 493 mutex_unlock(&device_list_lock);
494 unlock_kernel();
492 return status; 495 return status;
493} 496}
494 497