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/spi_imx.c | |
| 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/spi_imx.c')
| -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); |
