diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 19:06:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 19:06:58 -0400 |
commit | 85082fd7cbe3173198aac0eb5e85ab1edcc6352c (patch) | |
tree | edbc09b7945994f78668d218fa02e991c3b3b365 /drivers/spi | |
parent | 666484f0250db2e016948d63b3ef33e202e3b8d0 (diff) | |
parent | 53ffe3b440aa85af6fc4eda09b2d44bcdd312d4d (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (241 commits)
[ARM] 5171/1: ep93xx: fix compilation of modules using clocks
[ARM] 5133/2: at91sam9g20 defconfig file
[ARM] 5130/4: Support for the at91sam9g20
[ARM] 5160/1: IOP3XX: gpio/gpiolib support
[ARM] at91: Fix NAND FLASH timings for at91sam9x evaluation kits.
[ARM] 5084/1: zylonite: Register AC97 device
[ARM] 5085/2: PXA: Move AC97 over to the new central device declaration model
[ARM] 5120/1: pxa: correct platform driver names for PXA25x and PXA27x UDC drivers
[ARM] 5147/1: pxaficp_ir: drop pxa_gpio_mode calls, as pin setting
[ARM] 5145/1: PXA2xx: provide api to control IrDA pins state
[ARM] 5144/1: pxaficp_ir: cleanup includes
[ARM] pxa: remove pxa_set_cken()
[ARM] pxa: allow clk aliases
[ARM] Feroceon: don't disable BPU on boot
[ARM] Orion: LED support for HP mv2120
[ARM] Orion: add RD88F5181L-FXO support
[ARM] Orion: add RD88F5181L-GE support
[ARM] Orion: add Netgear WNR854T support
[ARM] s3c2410_defconfig: update for current build
[ARM] Acer n30: Minor style and indentation fixes.
...
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi_imx.c | 54 |
1 files changed, 36 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); |