Commit 6142811a3395188bac6fa4f5c4223471b1ac98a8
Exists in
master
and in
7 other branches
Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6
* 'next-spi' of git://git.secretlab.ca/git/linux-2.6: spi/pl022: move probe call to subsys_initcall() powerpc/5200: mpc52xx_uart.c: Add of_node_put to avoid memory leak spi/pl022: fix APB pclk power regression on U300 spi/spi_s3c64xx: Warn if PIO transfers time out spi/s3c64xx: Fix incorrect reuse of 'val' local variable. spi/s3c64xx: Fix compilation warning spi/dw_spi: clean the cs_control code spi/dw_spi: Allow interrupt sharing spi/spi_s3c64xx: Increase dead reckoning time in wait_for_xfer() spi/spi_s3c64xx: Move to subsys_initcall() spi: free children in spi_unregister_master, not siblings gpiolib: Add 'struct gpio_chip' forward declaration for !GPIOLIB case of: Fix missing includes - ll_temac spi/spi_s3c64xx: Staticise non-exported functions spi/spi_s3c64xx: Make probe more robust against missing board config
Showing 9 changed files Side-by-side Diff
drivers/net/ll_temac_main.c
drivers/net/ll_temac_mdio.c
drivers/serial/mpc52xx_uart.c
drivers/spi/amba-pl022.c
... | ... | @@ -503,8 +503,9 @@ |
503 | 503 | msg->state = NULL; |
504 | 504 | if (msg->complete) |
505 | 505 | msg->complete(msg->context); |
506 | - /* This message is completed, so let's turn off the clock! */ | |
506 | + /* This message is completed, so let's turn off the clocks! */ | |
507 | 507 | clk_disable(pl022->clk); |
508 | + amba_pclk_disable(pl022->adev); | |
508 | 509 | } |
509 | 510 | |
510 | 511 | /** |
511 | 512 | |
... | ... | @@ -1139,9 +1140,10 @@ |
1139 | 1140 | /* Setup the SPI using the per chip configuration */ |
1140 | 1141 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
1141 | 1142 | /* |
1142 | - * We enable the clock here, then the clock will be disabled when | |
1143 | + * We enable the clocks here, then the clocks will be disabled when | |
1143 | 1144 | * giveback() is called in each method (poll/interrupt/DMA) |
1144 | 1145 | */ |
1146 | + amba_pclk_enable(pl022->adev); | |
1145 | 1147 | clk_enable(pl022->clk); |
1146 | 1148 | restore_state(pl022); |
1147 | 1149 | flush(pl022); |
1148 | 1150 | |
... | ... | @@ -1786,11 +1788,9 @@ |
1786 | 1788 | } |
1787 | 1789 | |
1788 | 1790 | /* Disable SSP */ |
1789 | - clk_enable(pl022->clk); | |
1790 | 1791 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), |
1791 | 1792 | SSP_CR1(pl022->virtbase)); |
1792 | 1793 | load_ssp_default_config(pl022); |
1793 | - clk_disable(pl022->clk); | |
1794 | 1794 | |
1795 | 1795 | status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", |
1796 | 1796 | pl022); |
... | ... | @@ -1818,6 +1818,8 @@ |
1818 | 1818 | goto err_spi_register; |
1819 | 1819 | } |
1820 | 1820 | dev_dbg(dev, "probe succeded\n"); |
1821 | + /* Disable the silicon block pclk and clock it when needed */ | |
1822 | + amba_pclk_disable(adev); | |
1821 | 1823 | return 0; |
1822 | 1824 | |
1823 | 1825 | err_spi_register: |
1824 | 1826 | |
... | ... | @@ -1879,9 +1881,9 @@ |
1879 | 1881 | return status; |
1880 | 1882 | } |
1881 | 1883 | |
1882 | - clk_enable(pl022->clk); | |
1884 | + amba_pclk_enable(adev); | |
1883 | 1885 | load_ssp_default_config(pl022); |
1884 | - clk_disable(pl022->clk); | |
1886 | + amba_pclk_disable(adev); | |
1885 | 1887 | dev_dbg(&adev->dev, "suspended\n"); |
1886 | 1888 | return 0; |
1887 | 1889 | } |
... | ... | @@ -1981,7 +1983,7 @@ |
1981 | 1983 | return amba_driver_register(&pl022_driver); |
1982 | 1984 | } |
1983 | 1985 | |
1984 | -module_init(pl022_init); | |
1986 | +subsys_initcall(pl022_init); | |
1985 | 1987 | |
1986 | 1988 | static void __exit pl022_exit(void) |
1987 | 1989 | { |
drivers/spi/dw_spi.c
... | ... | @@ -181,10 +181,6 @@ |
181 | 181 | wait_till_not_busy(dws); |
182 | 182 | } |
183 | 183 | |
184 | -static void null_cs_control(u32 command) | |
185 | -{ | |
186 | -} | |
187 | - | |
188 | 184 | static int null_writer(struct dw_spi *dws) |
189 | 185 | { |
190 | 186 | u8 n_bytes = dws->n_bytes; |
... | ... | @@ -322,7 +318,7 @@ |
322 | 318 | struct spi_transfer, |
323 | 319 | transfer_list); |
324 | 320 | |
325 | - if (!last_transfer->cs_change) | |
321 | + if (!last_transfer->cs_change && dws->cs_control) | |
326 | 322 | dws->cs_control(MRST_SPI_DEASSERT); |
327 | 323 | |
328 | 324 | msg->state = NULL; |
329 | 325 | |
... | ... | @@ -396,7 +392,12 @@ |
396 | 392 | static irqreturn_t dw_spi_irq(int irq, void *dev_id) |
397 | 393 | { |
398 | 394 | struct dw_spi *dws = dev_id; |
395 | + u16 irq_status, irq_mask = 0x3f; | |
399 | 396 | |
397 | + irq_status = dw_readw(dws, isr) & irq_mask; | |
398 | + if (!irq_status) | |
399 | + return IRQ_NONE; | |
400 | + | |
400 | 401 | if (!dws->cur_msg) { |
401 | 402 | spi_mask_intr(dws, SPI_INT_TXEI); |
402 | 403 | /* Never fail */ |
403 | 404 | |
404 | 405 | |
405 | 406 | |
... | ... | @@ -544,13 +545,13 @@ |
544 | 545 | */ |
545 | 546 | if (dws->cs_control) { |
546 | 547 | if (dws->rx && dws->tx) |
547 | - chip->tmode = 0x00; | |
548 | + chip->tmode = SPI_TMOD_TR; | |
548 | 549 | else if (dws->rx) |
549 | - chip->tmode = 0x02; | |
550 | + chip->tmode = SPI_TMOD_RO; | |
550 | 551 | else |
551 | - chip->tmode = 0x01; | |
552 | + chip->tmode = SPI_TMOD_TO; | |
552 | 553 | |
553 | - cr0 &= ~(0x3 << SPI_MODE_OFFSET); | |
554 | + cr0 &= ~SPI_TMOD_MASK; | |
554 | 555 | cr0 |= (chip->tmode << SPI_TMOD_OFFSET); |
555 | 556 | } |
556 | 557 | |
... | ... | @@ -699,9 +700,6 @@ |
699 | 700 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); |
700 | 701 | if (!chip) |
701 | 702 | return -ENOMEM; |
702 | - | |
703 | - chip->cs_control = null_cs_control; | |
704 | - chip->enable_dma = 0; | |
705 | 703 | } |
706 | 704 | |
707 | 705 | /* |
... | ... | @@ -883,7 +881,7 @@ |
883 | 881 | dws->dma_inited = 0; |
884 | 882 | dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); |
885 | 883 | |
886 | - ret = request_irq(dws->irq, dw_spi_irq, 0, | |
884 | + ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, | |
887 | 885 | "dw_spi", dws); |
888 | 886 | if (ret < 0) { |
889 | 887 | dev_err(&master->dev, "can not get IRQ\n"); |
drivers/spi/spi.c
... | ... | @@ -554,11 +554,9 @@ |
554 | 554 | EXPORT_SYMBOL_GPL(spi_register_master); |
555 | 555 | |
556 | 556 | |
557 | -static int __unregister(struct device *dev, void *master_dev) | |
557 | +static int __unregister(struct device *dev, void *null) | |
558 | 558 | { |
559 | - /* note: before about 2.6.14-rc1 this would corrupt memory: */ | |
560 | - if (dev != master_dev) | |
561 | - spi_unregister_device(to_spi_device(dev)); | |
559 | + spi_unregister_device(to_spi_device(dev)); | |
562 | 560 | return 0; |
563 | 561 | } |
564 | 562 | |
... | ... | @@ -576,8 +574,7 @@ |
576 | 574 | { |
577 | 575 | int dummy; |
578 | 576 | |
579 | - dummy = device_for_each_child(master->dev.parent, &master->dev, | |
580 | - __unregister); | |
577 | + dummy = device_for_each_child(&master->dev, NULL, __unregister); | |
581 | 578 | device_unregister(&master->dev); |
582 | 579 | } |
583 | 580 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
drivers/spi/spi_s3c64xx.c
... | ... | @@ -200,6 +200,9 @@ |
200 | 200 | val = readl(regs + S3C64XX_SPI_STATUS); |
201 | 201 | } while (TX_FIFO_LVL(val, sci) && loops--); |
202 | 202 | |
203 | + if (loops == 0) | |
204 | + dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); | |
205 | + | |
203 | 206 | /* Flush RxFIFO*/ |
204 | 207 | loops = msecs_to_loops(1); |
205 | 208 | do { |
... | ... | @@ -210,6 +213,9 @@ |
210 | 213 | break; |
211 | 214 | } while (loops--); |
212 | 215 | |
216 | + if (loops == 0) | |
217 | + dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); | |
218 | + | |
213 | 219 | val = readl(regs + S3C64XX_SPI_CH_CFG); |
214 | 220 | val &= ~S3C64XX_SPI_CH_SW_RST; |
215 | 221 | writel(val, regs + S3C64XX_SPI_CH_CFG); |
216 | 222 | |
217 | 223 | |
... | ... | @@ -320,16 +326,17 @@ |
320 | 326 | |
321 | 327 | /* millisecs to xfer 'len' bytes @ 'cur_speed' */ |
322 | 328 | ms = xfer->len * 8 * 1000 / sdd->cur_speed; |
323 | - ms += 5; /* some tolerance */ | |
329 | + ms += 10; /* some tolerance */ | |
324 | 330 | |
325 | 331 | if (dma_mode) { |
326 | 332 | val = msecs_to_jiffies(ms) + 10; |
327 | 333 | val = wait_for_completion_timeout(&sdd->xfer_completion, val); |
328 | 334 | } else { |
335 | + u32 status; | |
329 | 336 | val = msecs_to_loops(ms); |
330 | 337 | do { |
331 | - val = readl(regs + S3C64XX_SPI_STATUS); | |
332 | - } while (RX_FIFO_LVL(val, sci) < xfer->len && --val); | |
338 | + status = readl(regs + S3C64XX_SPI_STATUS); | |
339 | + } while (RX_FIFO_LVL(status, sci) < xfer->len && --val); | |
333 | 340 | } |
334 | 341 | |
335 | 342 | if (!val) |
... | ... | @@ -447,8 +454,8 @@ |
447 | 454 | writel(val, regs + S3C64XX_SPI_CLK_CFG); |
448 | 455 | } |
449 | 456 | |
450 | -void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, | |
451 | - int size, enum s3c2410_dma_buffresult res) | |
457 | +static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, | |
458 | + int size, enum s3c2410_dma_buffresult res) | |
452 | 459 | { |
453 | 460 | struct s3c64xx_spi_driver_data *sdd = buf_id; |
454 | 461 | unsigned long flags; |
... | ... | @@ -467,8 +474,8 @@ |
467 | 474 | spin_unlock_irqrestore(&sdd->lock, flags); |
468 | 475 | } |
469 | 476 | |
470 | -void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, | |
471 | - int size, enum s3c2410_dma_buffresult res) | |
477 | +static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, | |
478 | + int size, enum s3c2410_dma_buffresult res) | |
472 | 479 | { |
473 | 480 | struct s3c64xx_spi_driver_data *sdd = buf_id; |
474 | 481 | unsigned long flags; |
... | ... | @@ -508,8 +515,9 @@ |
508 | 515 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
509 | 516 | |
510 | 517 | if (xfer->tx_buf != NULL) { |
511 | - xfer->tx_dma = dma_map_single(dev, xfer->tx_buf, | |
512 | - xfer->len, DMA_TO_DEVICE); | |
518 | + xfer->tx_dma = dma_map_single(dev, | |
519 | + (void *)xfer->tx_buf, xfer->len, | |
520 | + DMA_TO_DEVICE); | |
513 | 521 | if (dma_mapping_error(dev, xfer->tx_dma)) { |
514 | 522 | dev_err(dev, "dma_map_single Tx failed\n"); |
515 | 523 | xfer->tx_dma = XFER_DMAADDR_INVALID; |
... | ... | @@ -919,6 +927,13 @@ |
919 | 927 | return -ENODEV; |
920 | 928 | } |
921 | 929 | |
930 | + sci = pdev->dev.platform_data; | |
931 | + if (!sci->src_clk_name) { | |
932 | + dev_err(&pdev->dev, | |
933 | + "Board init must call s3c64xx_spi_set_info()\n"); | |
934 | + return -EINVAL; | |
935 | + } | |
936 | + | |
922 | 937 | /* Check for availability of necessary resource */ |
923 | 938 | |
924 | 939 | dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
... | ... | @@ -946,8 +961,6 @@ |
946 | 961 | return -ENOMEM; |
947 | 962 | } |
948 | 963 | |
949 | - sci = pdev->dev.platform_data; | |
950 | - | |
951 | 964 | platform_set_drvdata(pdev, master); |
952 | 965 | |
953 | 966 | sdd = spi_master_get_devdata(master); |
... | ... | @@ -1170,7 +1183,7 @@ |
1170 | 1183 | { |
1171 | 1184 | return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); |
1172 | 1185 | } |
1173 | -module_init(s3c64xx_spi_init); | |
1186 | +subsys_initcall(s3c64xx_spi_init); | |
1174 | 1187 | |
1175 | 1188 | static void __exit s3c64xx_spi_exit(void) |
1176 | 1189 | { |
include/linux/gpio.h
include/linux/spi/dw_spi.h
... | ... | @@ -14,7 +14,9 @@ |
14 | 14 | #define SPI_MODE_OFFSET 6 |
15 | 15 | #define SPI_SCPH_OFFSET 6 |
16 | 16 | #define SPI_SCOL_OFFSET 7 |
17 | + | |
17 | 18 | #define SPI_TMOD_OFFSET 8 |
19 | +#define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET) | |
18 | 20 | #define SPI_TMOD_TR 0x0 /* xmit & recv */ |
19 | 21 | #define SPI_TMOD_TO 0x1 /* xmit only */ |
20 | 22 | #define SPI_TMOD_RO 0x2 /* recv only */ |