mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
spi: Fixes for v6.8
A smallish collection of fixes for SPI, all driver specific, plus one device ID addition for a new Intel part. The ppc4xx isn't routinely covered by most of the automated testing so there were some errors that were missed in some of the recent API conversions, otherwise there's nothing super remarkable here. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmXOE6IACgkQJNaLcl1U h9Bbogf+OxmKFCtZW5QKple5TxYv4FAjdWERMDG1CAWBDU67Unkf7fUopHSPYw5a P/F6Y8sbSaQpmhdBVL9vjMugrO8hKEpAVN9EWLnhZJ8Z3Zm4XYhRhMizabgPdIeg kFwONgv+dKkJPu+e5Cecoi2tVq1cy5bht7ob8cQ3PMuCgu7PGl0N8RXjdCVU1AoR lYWR+W62nkJHQWhZhSRvlpdBok86KLo8cBjCH7mn+ngXSBPjpcchriky7XTvfm85 fl5nHrG+3TNMc/pr2MDY6onjH0zifTdBXnPv0HM77KU/jO45najJ+ZdoCquL9QQT vgg1bbfBFJilOFKvwmNJSGwZFnBtkQ== =pkCk -----END PGP SIGNATURE----- Merge tag 'spi-fix-v6.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi Pull spi fixes from Mark Brown: "A smallish collection of fixes for SPI, all driver specific, plus one device ID addition for a new Intel part. The ppc4xx isn't routinely covered by most of the automated testing so there were some errors that were missed in some of the recent API conversions, otherwise there's nothing super remarkable here" * tag 'spi-fix-v6.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi-mxs: Fix chipselect glitch spi: intel-pci: Add support for Lunar Lake-M SPI serial flash spi: omap2-mcspi: Revert FIFO support without DMA spi: ppc4xx: Drop write-only variable spi: ppc4xx: Fix fallout from rename in struct spi_bitbang spi: ppc4xx: Fix fallout from include cleanup spi: spi-ppc4xx: include missing platform_device.h spi: imx: fix the burst length at DMA mode and CPU mode
This commit is contained in:
commit
a00cf1988a
@ -2,6 +2,7 @@
|
||||
// Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
// Copyright (C) 2008 Juergen Beisert
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
@ -660,15 +661,15 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
else {
|
||||
if (spi_imx->usedma) {
|
||||
ctrl |= (spi_imx->bits_per_word *
|
||||
spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
|
||||
ctrl |= (spi_imx->bits_per_word - 1)
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
} else {
|
||||
if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST)
|
||||
ctrl |= (MX51_ECSPI_CTRL_MAX_BURST - 1)
|
||||
ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1)
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
else
|
||||
ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
|
||||
ctrl |= spi_imx->count / DIV_ROUND_UP(spi_imx->bits_per_word,
|
||||
BITS_PER_BYTE) * spi_imx->bits_per_word
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/mxs-spi.h>
|
||||
#include <trace/events/spi.h>
|
||||
#include <linux/dma/mxs-dma.h>
|
||||
|
||||
#define DRIVER_NAME "mxs-spi"
|
||||
|
||||
@ -252,7 +253,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
|
||||
desc = dmaengine_prep_slave_sg(ssp->dmach,
|
||||
&dma_xfer[sg_count].sg, 1,
|
||||
(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END);
|
||||
|
||||
if (!desc) {
|
||||
dev_err(ssp->dev,
|
||||
|
@ -53,8 +53,6 @@
|
||||
|
||||
/* per-register bitmasks: */
|
||||
#define OMAP2_MCSPI_IRQSTATUS_EOW BIT(17)
|
||||
#define OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY BIT(0)
|
||||
#define OMAP2_MCSPI_IRQSTATUS_RX0_FULL BIT(2)
|
||||
|
||||
#define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0)
|
||||
#define OMAP2_MCSPI_MODULCTRL_MS BIT(2)
|
||||
@ -293,7 +291,7 @@ static void omap2_mcspi_set_mode(struct spi_controller *ctlr)
|
||||
}
|
||||
|
||||
static void omap2_mcspi_set_fifo(const struct spi_device *spi,
|
||||
struct spi_transfer *t, int enable, int dma_enabled)
|
||||
struct spi_transfer *t, int enable)
|
||||
{
|
||||
struct spi_controller *ctlr = spi->controller;
|
||||
struct omap2_mcspi_cs *cs = spi->controller_state;
|
||||
@ -314,28 +312,20 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
|
||||
max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH / 2;
|
||||
else
|
||||
max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH;
|
||||
if (dma_enabled)
|
||||
wcnt = t->len / bytes_per_word;
|
||||
else
|
||||
wcnt = 0;
|
||||
|
||||
wcnt = t->len / bytes_per_word;
|
||||
if (wcnt > OMAP2_MCSPI_MAX_FIFOWCNT)
|
||||
goto disable_fifo;
|
||||
|
||||
xferlevel = wcnt << 16;
|
||||
if (t->rx_buf != NULL) {
|
||||
chconf |= OMAP2_MCSPI_CHCONF_FFER;
|
||||
if (dma_enabled)
|
||||
xferlevel |= (bytes_per_word - 1) << 8;
|
||||
else
|
||||
xferlevel |= (max_fifo_depth - 1) << 8;
|
||||
xferlevel |= (bytes_per_word - 1) << 8;
|
||||
}
|
||||
|
||||
if (t->tx_buf != NULL) {
|
||||
chconf |= OMAP2_MCSPI_CHCONF_FFET;
|
||||
if (dma_enabled)
|
||||
xferlevel |= bytes_per_word - 1;
|
||||
else
|
||||
xferlevel |= (max_fifo_depth - 1);
|
||||
xferlevel |= bytes_per_word - 1;
|
||||
}
|
||||
|
||||
mcspi_write_reg(ctlr, OMAP2_MCSPI_XFERLEVEL, xferlevel);
|
||||
@ -892,113 +882,6 @@ out:
|
||||
return count - c;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
omap2_mcspi_txrx_piofifo(struct spi_device *spi, struct spi_transfer *xfer)
|
||||
{
|
||||
struct omap2_mcspi_cs *cs = spi->controller_state;
|
||||
struct omap2_mcspi *mcspi;
|
||||
unsigned int count, c;
|
||||
unsigned int iter, cwc;
|
||||
int last_request;
|
||||
void __iomem *base = cs->base;
|
||||
void __iomem *tx_reg;
|
||||
void __iomem *rx_reg;
|
||||
void __iomem *chstat_reg;
|
||||
void __iomem *irqstat_reg;
|
||||
int word_len, bytes_per_word;
|
||||
u8 *rx;
|
||||
const u8 *tx;
|
||||
|
||||
mcspi = spi_controller_get_devdata(spi->controller);
|
||||
count = xfer->len;
|
||||
c = count;
|
||||
word_len = cs->word_len;
|
||||
bytes_per_word = mcspi_bytes_per_word(word_len);
|
||||
|
||||
/*
|
||||
* We store the pre-calculated register addresses on stack to speed
|
||||
* up the transfer loop.
|
||||
*/
|
||||
tx_reg = base + OMAP2_MCSPI_TX0;
|
||||
rx_reg = base + OMAP2_MCSPI_RX0;
|
||||
chstat_reg = base + OMAP2_MCSPI_CHSTAT0;
|
||||
irqstat_reg = base + OMAP2_MCSPI_IRQSTATUS;
|
||||
|
||||
if (c < (word_len >> 3))
|
||||
return 0;
|
||||
|
||||
rx = xfer->rx_buf;
|
||||
tx = xfer->tx_buf;
|
||||
|
||||
do {
|
||||
/* calculate number of words in current iteration */
|
||||
cwc = min((unsigned int)mcspi->fifo_depth / bytes_per_word,
|
||||
c / bytes_per_word);
|
||||
last_request = cwc != (mcspi->fifo_depth / bytes_per_word);
|
||||
if (tx) {
|
||||
if (mcspi_wait_for_reg_bit(irqstat_reg,
|
||||
OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY) < 0) {
|
||||
dev_err(&spi->dev, "TX Empty timed out\n");
|
||||
goto out;
|
||||
}
|
||||
writel_relaxed(OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY, irqstat_reg);
|
||||
|
||||
for (iter = 0; iter < cwc; iter++, tx += bytes_per_word) {
|
||||
if (bytes_per_word == 1)
|
||||
writel_relaxed(*tx, tx_reg);
|
||||
else if (bytes_per_word == 2)
|
||||
writel_relaxed(*((u16 *)tx), tx_reg);
|
||||
else if (bytes_per_word == 4)
|
||||
writel_relaxed(*((u32 *)tx), tx_reg);
|
||||
}
|
||||
}
|
||||
|
||||
if (rx) {
|
||||
if (!last_request &&
|
||||
mcspi_wait_for_reg_bit(irqstat_reg,
|
||||
OMAP2_MCSPI_IRQSTATUS_RX0_FULL) < 0) {
|
||||
dev_err(&spi->dev, "RX_FULL timed out\n");
|
||||
goto out;
|
||||
}
|
||||
writel_relaxed(OMAP2_MCSPI_IRQSTATUS_RX0_FULL, irqstat_reg);
|
||||
|
||||
for (iter = 0; iter < cwc; iter++, rx += bytes_per_word) {
|
||||
if (last_request &&
|
||||
mcspi_wait_for_reg_bit(chstat_reg,
|
||||
OMAP2_MCSPI_CHSTAT_RXS) < 0) {
|
||||
dev_err(&spi->dev, "RXS timed out\n");
|
||||
goto out;
|
||||
}
|
||||
if (bytes_per_word == 1)
|
||||
*rx = readl_relaxed(rx_reg);
|
||||
else if (bytes_per_word == 2)
|
||||
*((u16 *)rx) = readl_relaxed(rx_reg);
|
||||
else if (bytes_per_word == 4)
|
||||
*((u32 *)rx) = readl_relaxed(rx_reg);
|
||||
}
|
||||
}
|
||||
|
||||
if (last_request) {
|
||||
if (mcspi_wait_for_reg_bit(chstat_reg,
|
||||
OMAP2_MCSPI_CHSTAT_EOT) < 0) {
|
||||
dev_err(&spi->dev, "EOT timed out\n");
|
||||
goto out;
|
||||
}
|
||||
if (mcspi_wait_for_reg_bit(chstat_reg,
|
||||
OMAP2_MCSPI_CHSTAT_TXFFE) < 0) {
|
||||
dev_err(&spi->dev, "TXFFE timed out\n");
|
||||
goto out;
|
||||
}
|
||||
omap2_mcspi_set_enable(spi, 0);
|
||||
}
|
||||
c -= cwc * bytes_per_word;
|
||||
} while (c >= bytes_per_word);
|
||||
|
||||
out:
|
||||
omap2_mcspi_set_enable(spi, 1);
|
||||
return count - c;
|
||||
}
|
||||
|
||||
static u32 omap2_mcspi_calc_divisor(u32 speed_hz, u32 ref_clk_hz)
|
||||
{
|
||||
u32 div;
|
||||
@ -1323,9 +1206,7 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr,
|
||||
if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) &&
|
||||
ctlr->cur_msg_mapped &&
|
||||
ctlr->can_dma(ctlr, spi, t))
|
||||
omap2_mcspi_set_fifo(spi, t, 1, 1);
|
||||
else if (t->len > OMAP2_MCSPI_MAX_FIFODEPTH)
|
||||
omap2_mcspi_set_fifo(spi, t, 1, 0);
|
||||
omap2_mcspi_set_fifo(spi, t, 1);
|
||||
|
||||
omap2_mcspi_set_enable(spi, 1);
|
||||
|
||||
@ -1338,8 +1219,6 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr,
|
||||
ctlr->cur_msg_mapped &&
|
||||
ctlr->can_dma(ctlr, spi, t))
|
||||
count = omap2_mcspi_txrx_dma(spi, t);
|
||||
else if (mcspi->fifo_depth > 0)
|
||||
count = omap2_mcspi_txrx_piofifo(spi, t);
|
||||
else
|
||||
count = omap2_mcspi_txrx_pio(spi, t);
|
||||
|
||||
@ -1352,7 +1231,7 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr,
|
||||
omap2_mcspi_set_enable(spi, 0);
|
||||
|
||||
if (mcspi->fifo_depth > 0)
|
||||
omap2_mcspi_set_fifo(spi, t, 0, 0);
|
||||
omap2_mcspi_set_fifo(spi, t, 0);
|
||||
|
||||
out:
|
||||
/* Restore defaults if they were overriden */
|
||||
@ -1375,7 +1254,7 @@ out:
|
||||
omap2_mcspi_set_cs(spi, !(spi->mode & SPI_CS_HIGH));
|
||||
|
||||
if (mcspi->fifo_depth > 0 && t)
|
||||
omap2_mcspi_set_fifo(spi, t, 0, 0);
|
||||
omap2_mcspi_set_fifo(spi, t, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -25,11 +25,13 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
@ -166,10 +168,8 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)
|
||||
int scr;
|
||||
u8 cdm = 0;
|
||||
u32 speed;
|
||||
u8 bits_per_word;
|
||||
|
||||
/* Start with the generic configuration for this device. */
|
||||
bits_per_word = spi->bits_per_word;
|
||||
speed = spi->max_speed_hz;
|
||||
|
||||
/*
|
||||
@ -177,9 +177,6 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)
|
||||
* the transfer to overwrite the generic configuration with zeros.
|
||||
*/
|
||||
if (t) {
|
||||
if (t->bits_per_word)
|
||||
bits_per_word = t->bits_per_word;
|
||||
|
||||
if (t->speed_hz)
|
||||
speed = min(t->speed_hz, spi->max_speed_hz);
|
||||
}
|
||||
@ -362,22 +359,22 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
|
||||
|
||||
/* Setup the state for the bitbang driver */
|
||||
bbp = &hw->bitbang;
|
||||
bbp->master = hw->host;
|
||||
bbp->ctlr = hw->host;
|
||||
bbp->setup_transfer = spi_ppc4xx_setupxfer;
|
||||
bbp->txrx_bufs = spi_ppc4xx_txrx;
|
||||
bbp->use_dma = 0;
|
||||
bbp->master->setup = spi_ppc4xx_setup;
|
||||
bbp->master->cleanup = spi_ppc4xx_cleanup;
|
||||
bbp->master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
bbp->master->use_gpio_descriptors = true;
|
||||
bbp->ctlr->setup = spi_ppc4xx_setup;
|
||||
bbp->ctlr->cleanup = spi_ppc4xx_cleanup;
|
||||
bbp->ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
bbp->ctlr->use_gpio_descriptors = true;
|
||||
/*
|
||||
* The SPI core will count the number of GPIO descriptors to figure
|
||||
* out the number of chip selects available on the platform.
|
||||
*/
|
||||
bbp->master->num_chipselect = 0;
|
||||
bbp->ctlr->num_chipselect = 0;
|
||||
|
||||
/* the spi->mode bits understood by this driver: */
|
||||
bbp->master->mode_bits =
|
||||
bbp->ctlr->mode_bits =
|
||||
SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST;
|
||||
|
||||
/* Get the clock for the OPB */
|
||||
|
Loading…
Reference in New Issue
Block a user