Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…/git/broonie/spi into spi-5.6
  • Loading branch information
Mark Brown committed Dec 25, 2019
2 parents 0d9c754 + 9cd34ef commit 790514e
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 26 deletions.
27 changes: 27 additions & 0 deletions drivers/gpio/gpiolib-of.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@
#include "gpiolib.h"
#include "gpiolib-of.h"

/**
* of_gpio_spi_cs_get_count() - special GPIO counting for SPI
* Some elder GPIO controllers need special quirks. Currently we handle
* the Freescale GPIO controller with bindings that doesn't use the
* established "cs-gpios" for chip selects but instead rely on
* "gpios" for the chip select lines. If we detect this, we redirect
* the counting of "cs-gpios" to count "gpios" transparent to the
* driver.
*/
static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id)
{
struct device_node *np = dev->of_node;

if (!IS_ENABLED(CONFIG_SPI_MASTER))
return 0;
if (!con_id || strcmp(con_id, "cs"))
return 0;
if (!of_device_is_compatible(np, "fsl,spi") &&
!of_device_is_compatible(np, "aeroflexgaisler,spictrl"))
return 0;
return of_gpio_named_count(np, "gpios");
}

/*
* This is used by external users of of_gpio_count() from <linux/of_gpio.h>
*
Expand All @@ -35,6 +58,10 @@ int of_gpio_get_count(struct device *dev, const char *con_id)
char propname[32];
unsigned int i;

ret = of_gpio_spi_cs_get_count(dev, con_id);
if (ret > 0)
return ret;

for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
if (con_id)
snprintf(propname, sizeof(propname), "%s-%s",
Expand Down
6 changes: 3 additions & 3 deletions drivers/spi/spi-cadence.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,16 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi)
/**
* cdns_spi_chipselect - Select or deselect the chip select line
* @spi: Pointer to the spi_device structure
* @enable: Select (1) or deselect (0) the chip select line
* @is_high: Select(0) or deselect (1) the chip select line
*/
static void cdns_spi_chipselect(struct spi_device *spi, bool enable)
static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
{
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
u32 ctrl_reg;

ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);

if (!enable) {
if (is_high) {
/* Deselect the slave */
ctrl_reg |= CDNS_SPI_CR_SSCTRL;
} else {
Expand Down
2 changes: 2 additions & 0 deletions drivers/spi/spi-cavium-thunderx.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,

error:
clk_disable_unprepare(p->clk);
pci_release_regions(pdev);
spi_master_put(master);
return ret;
}
Expand All @@ -96,6 +97,7 @@ static void thunderx_spi_remove(struct pci_dev *pdev)
return;

clk_disable_unprepare(p->clk);
pci_release_regions(pdev);
/* Put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/spi/spi-dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable)
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
struct chip_data *chip = spi_get_ctldata(spi);

/* Chip select logic is inverted from spi_set_cs() */
if (chip && chip->cs_control)
chip->cs_control(enable);
chip->cs_control(!enable);

if (enable)
if (!enable)
dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select));
else if (dws->cs_override)
dw_writel(dws, DW_SPI_SER, 0);
Expand Down
22 changes: 16 additions & 6 deletions drivers/spi/spi-fsl-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
master->setup = fsl_spi_setup;
master->cleanup = fsl_spi_cleanup;
master->transfer_one_message = fsl_spi_do_one_msg;
master->use_gpio_descriptors = true;

mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi->max_bits_per_word = 32;
Expand Down Expand Up @@ -727,17 +728,27 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
}
}
#endif

pdata->cs_control = fsl_spi_cs_control;
/*
* Handle the case where we have one hardwired (always selected)
* device on the first "chipselect". Else we let the core code
* handle any GPIOs or native chip selects and assign the
* appropriate callback for dealing with the CS lines. This isn't
* supported on the GRLIB variant.
*/
ret = gpiod_count(dev, "cs");
if (ret <= 0)
pdata->max_chipselect = 1;
else
pdata->cs_control = fsl_spi_cs_control;
}

ret = of_address_to_resource(np, 0, &mem);
if (ret)
goto err;

irq = irq_of_parse_and_map(np, 0);
if (!irq) {
ret = -EINVAL;
irq = platform_get_irq(ofdev, 0);
if (irq < 0) {
ret = irq;
goto err;
}

Expand All @@ -750,7 +761,6 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
return 0;

err:
irq_dispose_mapping(irq);
return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi-nxp-fspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ static bool nxp_fspi_supports_op(struct spi_mem *mem,
op->data.nbytes > f->devtype_data->txfifo)
return false;

return true;
return spi_mem_default_supports_op(mem, op);
}

/* Instead of busy looping invoke readl_poll_timeout functionality. */
Expand Down
4 changes: 4 additions & 0 deletions drivers/spi/spi-pxa2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
{ PCI_VDEVICE(INTEL, 0x4b2a), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x4b2b), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x4b37), LPSS_BXT_SSP },
/* JSL */
{ PCI_VDEVICE(INTEL, 0x4daa), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x4dfb), LPSS_CNL_SSP },
/* APL */
{ PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP },
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi-sprd.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ static int sprd_spi_init_hw(struct sprd_spi *ss, struct spi_transfer *t)
if (d->unit != SPI_DELAY_UNIT_SCK)
return -EINVAL;

val = readl_relaxed(ss->base + SPRD_SPI_CTL7);
val = readl_relaxed(ss->base + SPRD_SPI_CTL0);
val &= ~(SPRD_SPI_SCK_REV | SPRD_SPI_NG_TX | SPRD_SPI_NG_RX);
/* Set default chip selection, clock phase and clock polarity */
val |= ss->hw_mode & SPI_CPHA ? SPRD_SPI_NG_RX : SPRD_SPI_NG_TX;
Expand Down
6 changes: 5 additions & 1 deletion drivers/spi/spi-ti-qspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct ti_qspi {
u32 dc;

bool mmap_enabled;
int current_cs;
};

#define QSPI_PID (0x0)
Expand Down Expand Up @@ -485,6 +486,7 @@ static void ti_qspi_enable_memory_map(struct spi_device *spi)
MEM_CS_EN(spi->chip_select));
}
qspi->mmap_enabled = true;
qspi->current_cs = spi->chip_select;
}

static void ti_qspi_disable_memory_map(struct spi_device *spi)
Expand All @@ -496,6 +498,7 @@ static void ti_qspi_disable_memory_map(struct spi_device *spi)
regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg,
MEM_CS_MASK, 0);
qspi->mmap_enabled = false;
qspi->current_cs = -1;
}

static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode,
Expand Down Expand Up @@ -541,7 +544,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,

mutex_lock(&qspi->list_lock);

if (!qspi->mmap_enabled)
if (!qspi->mmap_enabled || qspi->current_cs != mem->spi->chip_select)
ti_qspi_enable_memory_map(mem->spi);
ti_qspi_setup_mmap_read(mem->spi, op->cmd.opcode, op->data.buswidth,
op->addr.nbytes, op->dummy.nbytes);
Expand Down Expand Up @@ -797,6 +800,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
}
}
qspi->mmap_enabled = false;
qspi->current_cs = -1;

ret = devm_spi_register_master(&pdev->dev, master);
if (!ret)
Expand Down
31 changes: 19 additions & 12 deletions drivers/spi/spi-uniphier.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,25 +290,32 @@ static void uniphier_spi_recv(struct uniphier_spi_priv *priv)
}
}

static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv)
static void uniphier_spi_set_fifo_threshold(struct uniphier_spi_priv *priv,
unsigned int threshold)
{
unsigned int fifo_threshold, fill_bytes;
u32 val;

fifo_threshold = DIV_ROUND_UP(priv->rx_bytes,
bytes_per_word(priv->bits_per_word));
fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH);

fill_bytes = fifo_threshold - (priv->rx_bytes - priv->tx_bytes);

/* set fifo threshold */
val = readl(priv->base + SSI_FC);
val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK);
val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold);
val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold);
val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold);
val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold);
writel(val, priv->base + SSI_FC);
}

static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv)
{
unsigned int fifo_threshold, fill_words;
unsigned int bpw = bytes_per_word(priv->bits_per_word);

fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, bpw);
fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH);

uniphier_spi_set_fifo_threshold(priv, fifo_threshold);

fill_words = fifo_threshold -
DIV_ROUND_UP(priv->rx_bytes - priv->tx_bytes, bpw);

while (fill_bytes--)
while (fill_words--)
uniphier_spi_send(priv);
}

Expand Down

0 comments on commit 790514e

Please sign in to comment.