diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 01:44:51 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 01:44:51 -0400 |
commit | 43d2548bb2ef7e6d753f91468a746784041e522d (patch) | |
tree | 77d13fcd48fd998393abb825ec36e2b732684a73 /drivers/spi | |
parent | 585583d95c5660973bc0cf64add517b040acd8a4 (diff) | |
parent | 85082fd7cbe3173198aac0eb5e85ab1edcc6352c (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.c | 54 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 3 |
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 | ||
858 | static inline u32 spi_speed_hz(u32 data_rate) | 861 | static 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 | ||
863 | static u32 spi_data_rate(u32 speed_hz) | 866 | static 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. */ |
1177 | static int setup(struct spi_device *spi) | 1180 | static 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 | ||
1625 | err_no_pdata: | 1637 | err_no_pdata: |
1638 | clk_disable(drv_data->clk); | ||
1639 | clk_put(drv_data->clk); | ||
1640 | err_no_clk: | ||
1626 | err_no_mem: | 1641 | err_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 | ||