Commit d2f68a05 authored by Mark Brown's avatar Mark Brown

Merge tag 'spi-fix-v4.10-rc4' into spi-linus

spi: Fixes for v4.10

The usual small smattering of driver specific fixes.  A few bits that
stand out here:

 - The R-Car patches adding fallbacks are just adding new compatible
   strings to the driver so that device trees are written in a more
   robustly future proof fashion, this isn't strictly a fix but it's
   just new IDs and it's better to get it into mainline sooner to
   improve the ABI.
 - The DesignWare "switch to new API part 2" patch is actually a
   misleadingly titled fix for a bit that got missed in the original
   conversion.

# gpg: Signature made Thu 19 Jan 2017 14:54:15 GMT
# gpg:                using RSA key ADE668AA675718B59FE29FEA24D68B725D5487D0
# gpg:                issuer "broonie@kernel.org"
# gpg: key 0D9EACE2CD7BEEBC: no public key for trusted key - skipped
# gpg: key 0D9EACE2CD7BEEBC marked as ultimately trusted
# gpg: key CCB0A420AF88CD16: no public key for trusted key - skipped
# gpg: key CCB0A420AF88CD16 marked as ultimately trusted
# gpg: key 162614E316005C11: no public key for trusted key - skipped
# gpg: key 162614E316005C11 marked as ultimately trusted
# gpg: key A730C53A5621E907: no public key for trusted key - skipped
# gpg: key A730C53A5621E907 marked as ultimately trusted
# gpg: key 276568D75C6153AD: no public key for trusted key - skipped
# gpg: key 276568D75C6153AD marked as ultimately trusted
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>" [ultimate]
# gpg:                 aka "Mark Brown <broonie@debian.org>" [ultimate]
# gpg:                 aka "Mark Brown <broonie@kernel.org>" [ultimate]
# gpg:                 aka "Mark Brown <broonie@tardis.ed.ac.uk>" [ultimate]
# gpg:                 aka "Mark Brown <broonie@linaro.org>" [ultimate]
# gpg:                 aka "Mark Brown <Mark.Brown@linaro.org>" [ultimate]
parents 69973b83 52cc720c
Renesas MSIOF spi controller
Required properties:
- compatible : "renesas,msiof-<soctype>" for SoCs,
"renesas,sh-msiof" for SuperH, or
"renesas,sh-mobile-msiof" for SH Mobile series.
Examples with soctypes are:
"renesas,msiof-r8a7790" (R-Car H2)
- compatible : "renesas,msiof-r8a7790" (R-Car H2)
"renesas,msiof-r8a7791" (R-Car M2-W)
"renesas,msiof-r8a7792" (R-Car V2H)
"renesas,msiof-r8a7793" (R-Car M2-N)
"renesas,msiof-r8a7794" (R-Car E2)
"renesas,msiof-r8a7796" (R-Car M3-W)
"renesas,msiof-sh73a0" (SH-Mobile AG5)
"renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
"renesas,rcar-gen2-msiof" (generic R-Car Gen2 compatible device)
"renesas,rcar-gen3-msiof" (generic R-Car Gen3 compatible device)
"renesas,sh-msiof" (deprecated)
When compatible with the generic version, nodes
must list the SoC-specific version corresponding
to the platform first followed by the generic
version.
- reg : A list of offsets and lengths of the register sets for
the device.
If only one register set is present, it is to be used
......@@ -60,7 +67,8 @@ Documentation/devicetree/bindings/pinctrl/renesas,*.
Example:
msiof0: spi@e6e20000 {
compatible = "renesas,msiof-r8a7791";
compatible = "renesas,msiof-r8a7791",
"renesas,rcar-gen2-msiof";
reg = <0 0xe6e20000 0 0x0064>;
interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
......
* Marvell Armada 3700 SPI Controller
Required Properties:
- compatible: should be "marvell,armada-3700-spi"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: The interrupt number. The interrupt specifier format depends on
the interrupt controller and of its driver.
- clocks: Must contain the clock source, usually from the North Bridge clocks.
- num-cs: The number of chip selects that is supported by this SPI Controller
- #address-cells: should be 1.
- #size-cells: should be 0.
Example:
spi0: spi@10600 {
compatible = "marvell,armada-3700-spi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10600 0x5d>;
clocks = <&nb_perih_clk 7>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
num-cs = <4>;
};
* Freescale Low Power SPI (LPSPI) for i.MX
Required properties:
- compatible :
- "fsl,imx7ulp-spi" for LPSPI compatible with the one integrated on i.MX7ULP soc
- reg : address and length of the lpspi master registers
- interrupt-parent : core interrupt controller
- interrupts : lpspi interrupt
- clocks : lpspi clock specifier
Examples:
lpspi2: lpspi@40290000 {
compatible = "fsl,imx7ulp-spi";
reg = <0x40290000 0x10000>;
interrupt-parent = <&intc>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7ULP_CLK_LPSPI2>;
};
Allwinner A31 SPI controller
Allwinner A31/H3 SPI controller
Required properties:
- compatible: Should be "allwinner,sun6i-a31-spi".
- compatible: Should be "allwinner,sun6i-a31-spi" or "allwinner,sun8i-h3-spi".
- reg: Should contain register location and length.
- interrupts: Should contain interrupt.
- clocks: phandle to the clocks feeding the SPI controller. Two are
......@@ -12,6 +12,11 @@ Required properties:
- resets: phandle to the reset controller asserting this device in
reset
Optional properties:
- dmas: DMA specifiers for rx and tx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
- dma-names: DMA request names should include "rx" and "tx" if present.
Example:
spi1: spi@01c69000 {
......@@ -22,3 +27,19 @@ spi1: spi@01c69000 {
clock-names = "ahb", "mod";
resets = <&ahb1_rst 21>;
};
spi0: spi@01c68000 {
compatible = "allwinner,sun8i-h3-spi";
reg = <0x01c68000 0x1000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
clock-names = "ahb", "mod";
dmas = <&dma 23>, <&dma 23>;
dma-names = "rx", "tx";
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
resets = <&ccu RST_BUS_SPI0>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
......@@ -67,6 +67,13 @@ config SPI_ATH79
This enables support for the SPI controller present on the
Atheros AR71XX/AR724X/AR913X SoCs.
config SPI_ARMADA_3700
tristate "Marvell Armada 3700 SPI Controller"
depends on (ARCH_MVEBU && OF) || COMPILE_TEST
help
This enables support for the SPI controller present on the
Marvell Armada 3700 SoCs.
config SPI_ATMEL
tristate "Atmel SPI Controller"
depends on HAS_DMA
......@@ -264,6 +271,12 @@ config SPI_FALCON
has only been tested with m25p80 type chips. The hardware has no
support for other types of SPI peripherals.
config SPI_FSL_LPSPI
tristate "Freescale i.MX LPSPI controller"
depends on ARCH_MXC || COMPILE_TEST
help
This enables Freescale i.MX LPSPI controllers in master mode.
config SPI_GPIO
tristate "GPIO-based bitbanging SPI Master"
depends on GPIOLIB || COMPILE_TEST
......@@ -365,6 +378,7 @@ config SPI_FSL_SPI
config SPI_FSL_DSPI
tristate "Freescale DSPI controller"
select REGMAP_MMIO
depends on HAS_DMA
depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
help
This enables support for the Freescale DSPI controller in master
......@@ -373,7 +387,6 @@ config SPI_FSL_DSPI
config SPI_FSL_ESPI
tristate "Freescale eSPI controller"
depends on FSL_SOC
select SPI_FSL_LIB
help
This enables using the Freescale eSPI controllers in master mode.
From MPC8536, 85xx platform uses the controller, and all P10xx,
......@@ -451,7 +464,8 @@ config SPI_ORION
tristate "Orion SPI master"
depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST
help
This enables using the SPI master controller on the Orion chips.
This enables using the SPI master controller on the Orion
and MVEBU chips.
config SPI_PIC32
tristate "Microchip PIC32 series SPI"
......@@ -553,7 +567,7 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI"
depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
depends on (PLAT_SAMSUNG || ARCH_EXYNOS || COMPILE_TEST)
help
SPI driver for Samsung S3C64XX and newer SoCs.
......
......@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o
obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
......@@ -43,6 +44,7 @@ obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o
obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o
obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o
obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o
obj-$(CONFIG_SPI_FSL_LPSPI) += spi-fsl-lpspi.o
obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
......
This diff is collapsed.
......@@ -304,6 +304,7 @@ static const struct of_device_id ath79_spi_of_match[] = {
{ .compatible = "qca,ar7100-spi", },
{ },
};
MODULE_DEVICE_TABLE(of, ath79_spi_of_match);
static struct platform_driver ath79_spi_driver = {
.probe = ath79_spi_probe,
......
This diff is collapsed.
......@@ -494,7 +494,8 @@ static int spi_engine_probe(struct platform_device *pdev)
SPI_ENGINE_VERSION_MAJOR(version),
SPI_ENGINE_VERSION_MINOR(version),
SPI_ENGINE_VERSION_PATCH(version));
return -ENODEV;
ret = -ENODEV;
goto err_put_master;
}
spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
......@@ -574,6 +575,7 @@ static const struct of_device_id spi_engine_match_table[] = {
{ .compatible = "adi,axi-spi-engine-1.00.a" },
{ },
};
MODULE_DEVICE_TABLE(of, spi_engine_match_table);
static struct platform_driver spi_engine_driver = {
.probe = spi_engine_probe,
......
......@@ -646,7 +646,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
buf = t->rx_buf;
t->rx_dma = dma_map_single(&spi->dev, buf,
t->len, DMA_FROM_DEVICE);
if (!t->rx_dma) {
if (dma_mapping_error(&spi->dev, !t->rx_dma)) {
ret = -EFAULT;
goto err_rx_map;
}
......@@ -660,7 +660,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
buf = (void *)t->tx_buf;
t->tx_dma = dma_map_single(&spi->dev, buf,
t->len, DMA_TO_DEVICE);
if (!t->tx_dma) {
if (dma_mapping_error(&spi->dev, t->tx_dma)) {
ret = -EFAULT;
goto err_tx_map;
}
......
......@@ -274,11 +274,11 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer)
static void mid_spi_dma_stop(struct dw_spi *dws)
{
if (test_bit(TX_BUSY, &dws->dma_chan_busy)) {
dmaengine_terminate_all(dws->txchan);
dmaengine_terminate_sync(dws->txchan);
clear_bit(TX_BUSY, &dws->dma_chan_busy);
}
if (test_bit(RX_BUSY, &dws->dma_chan_busy)) {
dmaengine_terminate_all(dws->rxchan);
dmaengine_terminate_sync(dws->rxchan);
clear_bit(RX_BUSY, &dws->dma_chan_busy);
}
}
......
......@@ -107,7 +107,10 @@ static const struct file_operations dw_spi_regs_ops = {
static int dw_spi_debugfs_init(struct dw_spi *dws)
{
dws->debugfs = debugfs_create_dir("dw_spi", NULL);
char name[128];
snprintf(name, 128, "dw_spi-%s", dev_name(&dws->master->dev));
dws->debugfs = debugfs_create_dir(name, NULL);
if (!dws->debugfs)
return -ENOMEM;
......@@ -502,6 +505,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
master->handle_err = dw_spi_handle_err;
master->max_speed_hz = dws->max_freq;
master->dev.of_node = dev->of_node;
master->flags = SPI_MASTER_GPIO_SS;
/* Basic HW init */
spi_hw_init(dev, dws);
......
This diff is collapsed.
This diff is collapsed.
......@@ -28,10 +28,6 @@ struct mpc8xxx_spi {
/* rx & tx bufs from the spi_transfer */
const void *tx;
void *rx;
#if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
int len;
u8 *local_buf;
#endif
int subblock;
struct spi_pram __iomem *pram;
......
This diff is collapsed.
......@@ -173,15 +173,16 @@ static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
/* MX21, MX27 */
static unsigned int spi_imx_clkdiv_1(unsigned int fin,
unsigned int fspi, unsigned int max)
unsigned int fspi, unsigned int max, unsigned int *fres)
{
int i;
for (i = 2; i < max; i++)
if (fspi * mxc_clkdivs[i] >= fin)
return i;
break;
return max;
*fres = fin / mxc_clkdivs[i];
return i;
}
/* MX1, MX31, MX35, MX51 CSPI */
......@@ -442,6 +443,7 @@ static void mx51_ecspi_reset(struct spi_imx_data *spi_imx)
#define MX31_CSPICTRL_ENABLE (1 << 0)
#define MX31_CSPICTRL_MASTER (1 << 1)
#define MX31_CSPICTRL_XCH (1 << 2)
#define MX31_CSPICTRL_SMC (1 << 3)
#define MX31_CSPICTRL_POL (1 << 4)
#define MX31_CSPICTRL_PHA (1 << 5)
#define MX31_CSPICTRL_SSCTL (1 << 6)
......@@ -452,6 +454,10 @@ static void mx51_ecspi_reset(struct spi_imx_data *spi_imx)
#define MX35_CSPICTRL_CS_SHIFT 12
#define MX31_CSPICTRL_DR_SHIFT 16
#define MX31_CSPI_DMAREG 0x10
#define MX31_DMAREG_RH_DEN (1<<4)
#define MX31_DMAREG_TH_DEN (1<<1)
#define MX31_CSPISTATUS 0x14
#define MX31_STATUS_RR (1 << 3)
......@@ -511,6 +517,9 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config)
(is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT :
MX31_CSPICTRL_CS_SHIFT);
if (spi_imx->usedma)
reg |= MX31_CSPICTRL_SMC;
writel(reg, spi_imx->base + MXC_CSPICTRL);
reg = readl(spi_imx->base + MX31_CSPI_TESTREG);
......@@ -520,6 +529,13 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config)
reg &= ~MX31_TEST_LBC;
writel(reg, spi_imx->base + MX31_CSPI_TESTREG);
if (spi_imx->usedma) {
/* configure DMA requests when RXFIFO is half full and
when TXFIFO is half empty */
writel(MX31_DMAREG_RH_DEN | MX31_DMAREG_TH_DEN,
spi_imx->base + MX31_CSPI_DMAREG);
}
return 0;
}
......@@ -574,9 +590,12 @@ static int mx21_config(struct spi_device *spi, struct spi_imx_config *config)
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER;
unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18;
unsigned int clk;
reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max, &clk)
<< MX21_CSPICTRL_DR_SHIFT;
spi_imx->spi_bus_clk = clk;
reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max) <<
MX21_CSPICTRL_DR_SHIFT;
reg |= config->bpw - 1;
if (spi->mode & SPI_CPHA)
......@@ -1244,10 +1263,10 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per);
/*
* Only validated on i.mx6 now, can remove the constrain if validated on
* other chips.
* Only validated on i.mx35 and i.mx6 now, can remove the constraint
* if validated on other chips.
*/
if (is_imx51_ecspi(spi_imx)) {
if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) {
ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master);
if (ret == -EPROBE_DEFER)
goto out_clk_put;
......
......@@ -214,6 +214,7 @@ static const struct of_device_id jcore_spi_of_match[] = {
{ .compatible = "jcore,spi2" },
{},
};
MODULE_DEVICE_TABLE(of, jcore_spi_of_match);
static struct platform_driver jcore_spi_driver = {
.probe = jcore_spi_probe,
......
......@@ -1386,20 +1386,13 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
regs_offset = pdata->regs_offset;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
status = -ENODEV;
goto free_master;
}
r->start += regs_offset;
r->end += regs_offset;
mcspi->phys = r->start;
mcspi->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(mcspi->base)) {
status = PTR_ERR(mcspi->base);
goto free_master;
}
mcspi->phys = r->start + regs_offset;
mcspi->base += regs_offset;
mcspi->dev = &pdev->dev;
......
......@@ -138,37 +138,62 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
tclk_hz = clk_get_rate(orion_spi->clk);
if (devdata->typ == ARMADA_SPI) {
unsigned int clk, spr, sppr, sppr2, err;
unsigned int best_spr, best_sppr, best_err;
best_err = speed;
best_spr = 0;
best_sppr = 0;
/* Iterate over the valid range looking for best fit */
for (sppr = 0; sppr < 8; sppr++) {
sppr2 = 0x1 << sppr;
spr = tclk_hz / sppr2;
spr = DIV_ROUND_UP(spr, speed);
if ((spr == 0) || (spr > 15))
continue;
clk = tclk_hz / (spr * sppr2);
err = speed - clk;
if (err < best_err) {
best_spr = spr;
best_sppr = sppr;
best_err = err;
}
}
/*
* Given the core_clk (tclk_hz) and the target rate (speed) we
* determine the best values for SPR (in [0 .. 15]) and SPPR (in
* [0..7]) such that
*
* core_clk / (SPR * 2 ** SPPR)
*
* is as big as possible but not bigger than speed.
*/
if ((best_sppr == 0) && (best_spr == 0))
return -EINVAL;
/* best integer divider: */
unsigned divider = DIV_ROUND_UP(tclk_hz, speed);
unsigned spr, sppr;
if (divider < 16) {
/* This is the easy case, divider is less than 16 */
spr = divider;
sppr = 0;
} else {
unsigned two_pow_sppr;
/*
* Find the highest bit set in divider. This and the
* three next bits define SPR (apart from rounding).
* SPPR is then the number of zero bits that must be
* appended:
*/
sppr = fls(divider) - 4;
/*
* As SPR only has 4 bits, we have to round divider up
* to the next multiple of 2 ** sppr.
*/
two_pow_sppr = 1 << sppr;
divider = (divider + two_pow_sppr - 1) & -two_pow_sppr;
/*
* recalculate sppr as rounding up divider might have
* increased it enough to change the position of the
* highest set bit. In this case the bit that now
* doesn't make it into SPR is 0, so there is no need to
* round again.
*/
sppr = fls(divider) - 4;
spr = divider >> sppr;
/*
* Now do range checking. SPR is constructed to have a
* width of 4 bits, so this is fine for sure. So we
* still need to check for sppr to fit into 3 bits:
*/
if (sppr > 7)
return -EINVAL;
}
prescale = ((best_sppr & 0x6) << 5) |
((best_sppr & 0x1) << 4) | best_spr;
prescale = ((sppr & 0x6) << 5) | ((sppr & 0x1) << 4) | spr;
} else {
/*
* the supported rates are: 4,6,8...30
......
......@@ -1690,6 +1690,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
pxa2xx_spi_write(drv_data, SSCR1, tmp);
tmp = SSCR0_SCR(2) | SSCR0_Motorola | SSCR0_DataSize(8);
pxa2xx_spi_write(drv_data, SSCR0, tmp);
break;
default:
tmp = SSCR1_RxTresh(RX_THRESH_DFLT) |
SSCR1_TxTresh(TX_THRESH_DFLT);
......
......@@ -109,7 +109,6 @@ static inline void pxa2xx_spi_write(const struct driver_data *drv_data,
#define DONE_STATE ((void *)2)
#define ERROR_STATE ((void *)-1)
#define IS_DMA_ALIGNED(x) IS_ALIGNED((unsigned long)(x), DMA_ALIGNMENT)
#define DMA_ALIGNMENT 8
static inline int pxa25x_ssp_comp(struct driver_data *drv_data)
......
......@@ -413,7 +413,7 @@ static unsigned int qspi_set_send_trigger(struct rspi_data *rspi,
return n;
}
static void qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len)
static int qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len)
{
unsigned int n;
......@@ -428,6 +428,7 @@ static void qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len)
qspi_update(rspi, SPBFCR_RXTRG_MASK,
SPBFCR_RXTRG_1B, QSPI_SPBFCR);
}
return n;
}
#define set_config_register(spi, n) spi->ops->set_config_register(spi, n)
......@@ -785,6 +786,9 @@ static int qspi_transfer_out_in(struct rspi_data *rspi,
static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
{
const u8 *tx = xfer->tx_buf;
unsigned int n = xfer->len;
unsigned int i, len;
int ret;
if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
......@@ -793,9 +797,23 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
return ret;
}
ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len);
if (ret < 0)
return ret;
while (n > 0) {
len = qspi_set_send_trigger(rspi, n);
if (len == QSPI_BUFFER_SIZE) {
ret = rspi_wait_for_tx_empty(rspi);
if (ret < 0) {
dev_err(&rspi->master->dev, "transmit timeout\n");
return ret;
}
for (i = 0; i < len; i++)
rspi_write_data(rspi, *tx++);
} else {
ret = rspi_pio_transfer(rspi, tx, NULL, n);
if (ret < 0)
return ret;
}
n -= len;
}
/* Wait for the last transmission */
rspi_wait_for_tx_empty(rspi);
......@@ -805,13 +823,37 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
{
u8 *rx = xfer->rx_buf;
unsigned int n = xfer->len;
unsigned int i, len;
int ret;
if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
if (ret != -EAGAIN)
return ret;
}
return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len);
while (n > 0) {
len = qspi_set_receive_trigger(rspi, n);
if (len == QSPI_BUFFER_SIZE) {
ret = rspi_wait_for_rx_full(rspi);
if (ret < 0) {
dev_err(&rspi->master->dev, "receive timeout\n");
return ret;
}
for (i = 0; i < len; i++)
*rx++ = rspi_read_data(rspi);
} else {
ret = rspi_pio_transfer(rspi, NULL, rx, n);
if (ret < 0)
return ret;
*rx++ = ret;
}
n -= len;
}
return 0;
}
static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
......
......@@ -973,13 +973,16 @@ static const struct sh_msiof_chipdata r8a779x_data = {
};
static const struct of_device_id sh_msiof_match[] = {
{ .compatible = "renesas,sh-msiof", .data = &sh_data },
{ .compatible = "renesas,sh-mobile-msiof", .data = &sh_data },
{ .compatible = "renesas,msiof-r8a7790", .data = &r8a779x_data },
{ .compatible = "renesas,msiof-r8a7791", .data = &r8a779x_data },
{ .compatible = "renesas,msiof-r8a7792", .data = &r8a779x_data },
{ .compatible = "renesas,msiof-r8a7793", .data = &r8a779x_data },
{ .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data },
{ .compatible = "renesas,rcar-gen2-msiof", .data = &r8a779x_data },
{ .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data },
{ .compatible = "renesas,rcar-gen3-msiof", .data = &r8a779x_data },
{ .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */
{},
};
MODULE_DEVICE_TABLE(of, sh_msiof_match);
......
......@@ -46,6 +46,8 @@
#define SUN4I_CTL_TP BIT(18)
#define SUN4I_INT_CTL_REG 0x0c
#define SUN4I_INT_CTL_RF_F34 BIT(4)
#define SUN4I_INT_CTL_TF_E34 BIT(12)
#define SUN4I_INT_CTL_TC BIT(16)
#define SUN4I_INT_STA_REG 0x10
......@@ -61,11 +63,14 @@
#define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
#define SUN4I_CLK_CTL_DRS BIT(12)
#define SUN4I_MAX_XFER_SIZE 0xffffff
#define SUN4I_BURST_CNT_REG 0x20
#define SUN4I_BURST_CNT(cnt) ((cnt) & 0xffffff)
#define SUN4I_BURST_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE)
#define SUN4I_XMIT_CNT_REG 0x24
#define SUN4I_XMIT_CNT(cnt) ((cnt) & 0xffffff)
#define SUN4I_XMIT_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE)
#define SUN4I_FIFO_STA_REG 0x28
#define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f
......@@ -96,6 +101,31 @@ static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value)
writel(value, sspi->base_addr + reg);
}
static inline u32 sun4i_spi_get_tx_fifo_count(struct sun4i_spi *sspi)
{
u32 reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG);
reg >>= SUN4I_FIFO_STA_TF_CNT_BITS;
return reg & SUN4I_FIFO_STA_TF_CNT_MASK;
}
static inline void sun4i_spi_enable_interrupt(struct sun4i_spi *sspi, u32 mask)
{
u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG);
reg |= mask;
sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg);
}
static inline void sun4i_spi_disable_interrupt(struct sun4i_spi *sspi, u32 mask)
{
u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG);
reg &= ~mask;
sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg);
}
static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
{
u32 reg, cnt;
......@@ -118,10 +148,13 @@ static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
{
u32 cnt;
u8 byte;
if (len > sspi->len)
len = sspi->len;
/* See how much data we can fit */
cnt = SUN4I_FIFO_DEPTH - sun4i_spi_get_tx_fifo_count(sspi);
len = min3(len, (int)cnt, sspi->len);
while (len--) {
byte = sspi->tx_buf ? *sspi->tx_buf++ : 0;
......@@ -184,10 +217,10 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
u32 reg;
/* We don't support transfer larger than the FIFO */
if (tfr->len > SUN4I_FIFO_DEPTH)
if (tfr->len > SUN4I_MAX_XFER_SIZE)
return -EMSGSIZE;
if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH)
if (tfr->tx_buf && tfr->len >= SUN4I_MAX_XFER_SIZE)
return -EMSGSIZE;
reinit_completion(&sspi->done);
......@@ -286,7 +319,11 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
/* Enable the interrupts */
sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TC |
SUN4I_INT_CTL_RF_F34);
/* Only enable Tx FIFO interrupt if we really need it */
if (tx_len > SUN4I_FIFO_DEPTH)
sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TF_E34);
/* Start the transfer */
reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
......@@ -306,7 +343,6 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
goto out;
}
sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
out:
sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
......@@ -322,10 +358,33 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id)
/* Transfer complete */
if (status & SUN4I_INT_CTL_TC) {
sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC);
sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
complete(&sspi->done);
return IRQ_HANDLED;
}
/* Receive FIFO 3/4 full */
if (status & SUN4I_INT_CTL_RF_F34) {
sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
/* Only clear the interrupt _after_ draining the FIFO */
sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_RF_F34);
return IRQ_HANDLED;
}
/* Transmit FIFO 3/4 empty */
if (status & SUN4I_INT_CTL_TF_E34) {
sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
if (!sspi->len)
/* nothing left to transmit */
sun4i_spi_disable_interrupt(sspi, SUN4I_INT_CTL_TF_E34);
/* Only clear the interrupt _after_ re-seeding the FIFO */
sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TF_E34);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
......
......@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
......@@ -24,6 +25,7 @@
#include <linux/spi/spi.h>
#define SUN6I_FIFO_DEPTH 128
#define SUN8I_FIFO_DEPTH 64
#define SUN6I_GBL_CTL_REG 0x04
#define SUN6I_GBL_CTL_BUS_ENABLE BIT(0)
......@@ -90,6 +92,7 @@ struct sun6i_spi {
const u8 *tx_buf;
u8 *rx_buf;
int len;
unsigned long fifo_depth;
};
static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg)
......@@ -155,7 +158,9 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
static size_t sun6i_spi_max_transfer_size(struct spi_device *spi)
{
return SUN6I_FIFO_DEPTH - 1;
struct sun6i_spi *sspi = spi_master_get_devdata(spi->master);
return sspi->fifo_depth - 1;
}
static int sun6i_spi_transfer_one(struct spi_master *master,
......@@ -170,7 +175,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
u32 reg;
/* We don't support transfer larger than the FIFO */
if (tfr->len > SUN6I_FIFO_DEPTH)
if (tfr->len > sspi->fifo_depth)
return -EINVAL;
reinit_completion(&sspi->done);
......@@ -265,7 +270,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
SUN6I_BURST_CTL_CNT_STC(tx_len));
/* Fill the TX FIFO */
sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH);
sun6i_spi_fill_fifo(sspi, sspi->fifo_depth);
/* Enable the interrupts */
sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
......@@ -288,7 +293,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
goto out;
}
sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH);
sun6i_spi_drain_fifo(sspi, sspi->fifo_depth);
out:
sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
......@@ -398,6 +403,8 @@ static int sun6i_spi_probe(struct platform_device *pdev)
}
sspi->master = master;
sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev);
master->max_speed_hz = 100 * 1000 * 1000;
master->min_speed_hz = 3 * 1000;
master->set_cs = sun6i_spi_set_cs;
......@@ -470,7 +477,8 @@ static int sun6i_spi_remove(struct platform_device *pdev)
}
static const struct of_device_id sun6i_spi_match[] = {
{ .compatible = "allwinner,sun6i-a31-spi", },
{ .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH },
{ .compatible = "allwinner,sun8i-h3-spi", .data = (void *)SUN8I_FIFO_DEPTH },
{}
};
MODULE_DEVICE_TABLE(of, sun6i_spi_match);
......
......@@ -411,6 +411,7 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst,
tx->callback = ti_qspi_dma_callback;
tx->callback_param = qspi;
cookie = tx->tx_submit(tx);
reinit_completion(&qspi->transfer_complete);
ret = dma_submit_error(cookie);
if (ret) {
......
......@@ -1268,11 +1268,8 @@ static void pch_spi_free_resources(struct pch_spi_board_data *board_dat,
static int pch_spi_get_resources(struct pch_spi_board_data *board_dat,
struct pch_spi_data *data)
{
int retval = 0;
dev_dbg(&board_dat->pdev->dev, "%s ENTRY\n", __func__);
/* reset PCH SPI h/w */
pch_spi_reset(data->master);
dev_dbg(&board_dat->pdev->dev,
......@@ -1280,15 +1277,7 @@ static int pch_spi_get_resources(struct pch_spi_board_data *board_dat,
dev_dbg(&board_dat->pdev->dev, "%s data->irq_reg_sts=true\n", __func__);
if (retval != 0) {
dev_err(&board_dat->pdev->dev,
"%s FAIL:invoking pch_spi_free_resources\n", __func__);
pch_spi_free_resources(board_dat, data);
}
dev_dbg(&board_dat->pdev->dev, "%s Return=%d\n", __func__, retval);
return retval;
return 0;
}
static void pch_free_dma_buf(struct pch_spi_board_data *board_dat,
......
......@@ -451,6 +451,7 @@ static const struct of_device_id xlp_spi_dt_id[] = {
{ .compatible = "netlogic,xlp832-spi" },
{ },
};
MODULE_DEVICE_TABLE(of, xlp_spi_dt_id);
static struct platform_driver xlp_spi_driver = {
.probe = xlp_spi_probe,
......
......@@ -697,10 +697,15 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
if (spi->mode & SPI_CS_HIGH)
enable = !enable;
if (gpio_is_valid(spi->cs_gpio))
if (gpio_is_valid(spi->cs_gpio)) {
gpio_set_value(spi->cs_gpio, !enable);
else if (spi->master->set_cs)
/* Some SPI masters need both GPIO CS & slave_select */
if ((spi->master->flags & SPI_MASTER_GPIO_SS) &&
spi->master->set_cs)
spi->master->set_cs(spi, !enable);
} else if (spi->master->set_cs) {
spi->master->set_cs(spi, !enable);
}
}
#ifdef CONFIG_HAS_DMA
......@@ -720,6 +725,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
int desc_len;
int sgs;
struct page *vm_page;
struct scatterlist *sg;
void *sg_buf;
size_t min;
int i, ret;
......@@ -738,6 +744,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
if (ret != 0)
return ret;
sg = &sgt->sgl[0];
for (i = 0; i < sgs; i++) {
if (vmalloced_buf || kmap_buf) {
......@@ -751,16 +758,17 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
sg_free_table(sgt);
return -ENOMEM;
}
sg_set_page(&sgt->sgl[i], vm_page,
sg_set_page(sg, vm_page,
min, offset_in_page(buf));
} else {
min = min_t(size_t, len, desc_len);
sg_buf = buf;
sg_set_buf(&sgt->sgl[i], sg_buf, min);
sg_set_buf(sg, sg_buf, min);
}
buf += min;
len -= min;
sg = sg_next(sg);
}
ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
......@@ -1034,8 +1042,14 @@ static int spi_transfer_one_message(struct spi_master *master,
if (msg->status != -EINPROGRESS)
goto out;
if (xfer->delay_usecs)
udelay(xfer->delay_usecs);
if (xfer->delay_usecs) {
u16 us = xfer->delay_usecs;
if (us <= 10)
udelay(us);
else
usleep_range(us, us + DIV_ROUND_UP(us, 10));
}
if (xfer->cs_change) {
if (list_is_last(&xfer->transfer_list,
......
......@@ -696,6 +696,7 @@ static struct class *spidev_class;
static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "rohm,dh2228fv" },
{ .compatible = "lineartechnology,ltc2488" },
{ .compatible = "ge,achc" },
{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);
......
......@@ -442,6 +442,7 @@ struct spi_master {
#define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */
#define SPI_MASTER_MUST_RX BIT(3) /* requires rx */
#define SPI_MASTER_MUST_TX BIT(4) /* requires tx */
#define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */
/*
* on some hardware transfer / message size may be constrained
......
......@@ -315,7 +315,7 @@ static void transfer_file(int fd, char *filename)
pabort("can't stat input file");
tx_fd = open(filename, O_RDONLY);
if (fd < 0)
if (tx_fd < 0)
pabort("can't open input file");
tx = malloc(sb.st_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment