Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'spi-fix-v3.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc

Pull spi fixes from Mark Brown:
"A bunch of small driver fixes plus a fix for error handling in the
core - nothing too exciting overall."

* tag 'spi-fix-v3.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc:
spi/mpc512x-psc: optionally keep PSC SS asserted across xfer segmensts
spi: Unlock a spinlock before calling into the controller driver.
spi/s3c64xx: modified error interrupt handling and init
spi/bcm63xx: don't disable non enabled clocks in probe error path
spi/bcm63xx: Remove unused variable
spi: slink-tegra20: move runtime pm calls to transfer_one_message

+42 -44
+1 -2
drivers/spi/spi-bcm63xx.c
··· 152 152 static int bcm63xx_spi_setup(struct spi_device *spi) 153 153 { 154 154 struct bcm63xx_spi *bs; 155 - int ret; 156 155 157 156 bs = spi_master_get_devdata(spi->master); 158 157 ··· 489 490 default: 490 491 dev_err(dev, "unsupported MSG_CTL width: %d\n", 491 492 bs->msg_ctl_width); 492 - goto out_clk_disable; 493 + goto out_err; 493 494 } 494 495 495 496 /* Initialize hardware */
+1 -1
drivers/spi/spi-mpc512x-psc.c
··· 164 164 165 165 for (i = count; i > 0; i--) { 166 166 data = tx_buf ? *tx_buf++ : 0; 167 - if (len == EOFBYTE) 167 + if (len == EOFBYTE && t->cs_change) 168 168 setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); 169 169 out_8(&fifo->txdata_8, data); 170 170 len--;
+25 -16
drivers/spi/spi-s3c64xx.c
··· 994 994 { 995 995 struct s3c64xx_spi_driver_data *sdd = data; 996 996 struct spi_master *spi = sdd->master; 997 - unsigned int val; 997 + unsigned int val, clr = 0; 998 998 999 - val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); 999 + val = readl(sdd->regs + S3C64XX_SPI_STATUS); 1000 1000 1001 - val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | 1002 - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | 1003 - S3C64XX_SPI_PND_TX_OVERRUN_CLR | 1004 - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; 1005 - 1006 - writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); 1007 - 1008 - if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) 1001 + if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { 1002 + clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; 1009 1003 dev_err(&spi->dev, "RX overrun\n"); 1010 - if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) 1004 + } 1005 + if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { 1006 + clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; 1011 1007 dev_err(&spi->dev, "RX underrun\n"); 1012 - if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) 1008 + } 1009 + if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { 1010 + clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; 1013 1011 dev_err(&spi->dev, "TX overrun\n"); 1014 - if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) 1012 + } 1013 + if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { 1014 + clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; 1015 1015 dev_err(&spi->dev, "TX underrun\n"); 1016 + } 1017 + 1018 + /* Clear the pending irq by setting and then clearing it */ 1019 + writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); 1020 + writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); 1016 1021 1017 1022 return IRQ_HANDLED; 1018 1023 } ··· 1041 1036 writel(0, regs + S3C64XX_SPI_MODE_CFG); 1042 1037 writel(0, regs + S3C64XX_SPI_PACKET_CNT); 1043 1038 1044 - /* Clear any irq pending bits */ 1045 - writel(readl(regs + S3C64XX_SPI_PENDING_CLR), 1046 - regs + S3C64XX_SPI_PENDING_CLR); 1039 + /* Clear any irq pending bits, should set and clear the bits */ 1040 + val = S3C64XX_SPI_PND_RX_OVERRUN_CLR | 1041 + S3C64XX_SPI_PND_RX_UNDERRUN_CLR | 1042 + S3C64XX_SPI_PND_TX_OVERRUN_CLR | 1043 + S3C64XX_SPI_PND_TX_UNDERRUN_CLR; 1044 + writel(val, regs + S3C64XX_SPI_PENDING_CLR); 1045 + writel(0, regs + S3C64XX_SPI_PENDING_CLR); 1047 1046 1048 1047 writel(0, regs + S3C64XX_SPI_SWAP_CFG); 1049 1048
+8 -17
drivers/spi/spi-tegra20-slink.c
··· 858 858 return 0; 859 859 } 860 860 861 - static int tegra_slink_prepare_transfer(struct spi_master *master) 862 - { 863 - struct tegra_slink_data *tspi = spi_master_get_devdata(master); 864 - 865 - return pm_runtime_get_sync(tspi->dev); 866 - } 867 - 868 - static int tegra_slink_unprepare_transfer(struct spi_master *master) 869 - { 870 - struct tegra_slink_data *tspi = spi_master_get_devdata(master); 871 - 872 - pm_runtime_put(tspi->dev); 873 - return 0; 874 - } 875 - 876 861 static int tegra_slink_transfer_one_message(struct spi_master *master, 877 862 struct spi_message *msg) 878 863 { ··· 870 885 871 886 msg->status = 0; 872 887 msg->actual_length = 0; 888 + ret = pm_runtime_get_sync(tspi->dev); 889 + if (ret < 0) { 890 + dev_err(tspi->dev, "runtime get failed: %d\n", ret); 891 + goto done; 892 + } 893 + 873 894 single_xfer = list_is_singular(&msg->transfers); 874 895 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 875 896 INIT_COMPLETION(tspi->xfer_completion); ··· 912 921 exit: 913 922 tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); 914 923 tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); 924 + pm_runtime_put(tspi->dev); 925 + done: 915 926 msg->status = ret; 916 927 spi_finalize_current_message(master); 917 928 return ret; ··· 1141 1148 /* the spi->mode bits understood by this driver: */ 1142 1149 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 1143 1150 master->setup = tegra_slink_setup; 1144 - master->prepare_transfer_hardware = tegra_slink_prepare_transfer; 1145 1151 master->transfer_one_message = tegra_slink_transfer_one_message; 1146 - master->unprepare_transfer_hardware = tegra_slink_unprepare_transfer; 1147 1152 master->num_chipselect = MAX_CHIP_SELECT; 1148 1153 master->bus_num = -1; 1149 1154
+7 -8
drivers/spi/spi.c
··· 543 543 /* Lock queue and check for queue work */ 544 544 spin_lock_irqsave(&master->queue_lock, flags); 545 545 if (list_empty(&master->queue) || !master->running) { 546 - if (master->busy && master->unprepare_transfer_hardware) { 547 - ret = master->unprepare_transfer_hardware(master); 548 - if (ret) { 549 - spin_unlock_irqrestore(&master->queue_lock, flags); 550 - dev_err(&master->dev, 551 - "failed to unprepare transfer hardware\n"); 552 - return; 553 - } 546 + if (!master->busy) { 547 + spin_unlock_irqrestore(&master->queue_lock, flags); 548 + return; 554 549 } 555 550 master->busy = false; 556 551 spin_unlock_irqrestore(&master->queue_lock, flags); 552 + if (master->unprepare_transfer_hardware && 553 + master->unprepare_transfer_hardware(master)) 554 + dev_err(&master->dev, 555 + "failed to unprepare transfer hardware\n"); 557 556 return; 558 557 } 559 558