Merge branch 'spi-5.4' into spi-linus

This commit is contained in:
Mark Brown 2019-11-22 19:56:33 +00:00
commit 8f3ed6d0b0
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
17 changed files with 95 additions and 49 deletions

View file

@ -302,7 +302,6 @@ struct atmel_spi {
bool use_cs_gpios; bool use_cs_gpios;
bool keep_cs; bool keep_cs;
bool cs_active;
u32 fifo_size; u32 fifo_size;
}; };
@ -1376,11 +1375,9 @@ static int atmel_spi_one_transfer(struct spi_master *master,
&msg->transfers)) { &msg->transfers)) {
as->keep_cs = true; as->keep_cs = true;
} else { } else {
as->cs_active = !as->cs_active; cs_deactivate(as, msg->spi);
if (as->cs_active) udelay(10);
cs_activate(as, msg->spi); cs_activate(as, msg->spi);
else
cs_deactivate(as, msg->spi);
} }
} }
@ -1403,7 +1400,6 @@ static int atmel_spi_transfer_one_message(struct spi_master *master,
atmel_spi_lock(as); atmel_spi_lock(as);
cs_activate(as, spi); cs_activate(as, spi);
as->cs_active = true;
as->keep_cs = false; as->keep_cs = false;
msg->status = 0; msg->status = 0;

View file

@ -1248,7 +1248,7 @@ static int bcm2835_spi_setup(struct spi_device *spi)
/* /*
* Retrieve the corresponding GPIO line used for CS. * Retrieve the corresponding GPIO line used for CS.
* The inversion semantics will be handled by the GPIO core * The inversion semantics will be handled by the GPIO core
* code, so we pass GPIOS_OUT_LOW for "unasserted" and * code, so we pass GPIOD_OUT_LOW for "unasserted" and
* the correct flag for inversion semantics. The SPI_CS_HIGH * the correct flag for inversion semantics. The SPI_CS_HIGH
* on spi->mode cannot be checked for polarity in this case * on spi->mode cannot be checked for polarity in this case
* as the flag use_gpio_descriptors enforces SPI_CS_HIGH. * as the flag use_gpio_descriptors enforces SPI_CS_HIGH.

View file

@ -9,6 +9,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
@ -193,6 +194,8 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
goto out; goto out;
} }
pm_runtime_enable(&pdev->dev);
ret = dw_spi_add_host(&pdev->dev, dws); ret = dw_spi_add_host(&pdev->dev, dws);
if (ret) if (ret)
goto out; goto out;
@ -201,6 +204,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
return 0; return 0;
out: out:
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(dwsmmio->pclk); clk_disable_unprepare(dwsmmio->pclk);
out_clk: out_clk:
clk_disable_unprepare(dwsmmio->clk); clk_disable_unprepare(dwsmmio->clk);
@ -212,6 +216,7 @@ static int dw_spi_mmio_remove(struct platform_device *pdev)
struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev); struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
dw_spi_remove_host(&dwsmmio->dws); dw_spi_remove_host(&dwsmmio->dws);
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(dwsmmio->pclk); clk_disable_unprepare(dwsmmio->pclk);
clk_disable_unprepare(dwsmmio->clk); clk_disable_unprepare(dwsmmio->clk);

View file

@ -308,7 +308,8 @@ static int dw_spi_transfer_one(struct spi_controller *master,
cr0 = (transfer->bits_per_word - 1) cr0 = (transfer->bits_per_word - 1)
| (chip->type << SPI_FRF_OFFSET) | (chip->type << SPI_FRF_OFFSET)
| ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) | | ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) |
(((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET)) (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET) |
(((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET))
| (chip->tmode << SPI_TMOD_OFFSET); | (chip->tmode << SPI_TMOD_OFFSET);
/* /*

View file

@ -392,7 +392,8 @@ void fsl_spi_cpm_free(struct mpc8xxx_spi *mspi)
dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE); dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE);
dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE);
cpm_muram_free(cpm_muram_offset(mspi->tx_bd)); cpm_muram_free(cpm_muram_offset(mspi->tx_bd));
cpm_muram_free(cpm_muram_offset(mspi->pram)); if (!(mspi->flags & SPI_CPM1))
cpm_muram_free(cpm_muram_offset(mspi->pram));
fsl_spi_free_dummy_rx(); fsl_spi_free_dummy_rx();
} }
EXPORT_SYMBOL_GPL(fsl_spi_cpm_free); EXPORT_SYMBOL_GPL(fsl_spi_cpm_free);

View file

@ -707,7 +707,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
regmap_read(dspi->regmap, SPI_SR, &spi_sr); regmap_read(dspi->regmap, SPI_SR, &spi_sr);
regmap_write(dspi->regmap, SPI_SR, spi_sr); regmap_write(dspi->regmap, SPI_SR, spi_sr);
if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF))) if (!(spi_sr & SPI_SR_EOQF))
return IRQ_NONE; return IRQ_NONE;
if (dspi_rxtx(dspi) == 0) { if (dspi_rxtx(dspi) == 0) {
@ -1114,6 +1114,9 @@ static int dspi_probe(struct platform_device *pdev)
dspi_init(dspi); dspi_init(dspi);
if (dspi->devtype_data->trans_mode == DSPI_TCFQ_MODE)
goto poll_mode;
dspi->irq = platform_get_irq(pdev, 0); dspi->irq = platform_get_irq(pdev, 0);
if (dspi->irq <= 0) { if (dspi->irq <= 0) {
dev_info(&pdev->dev, dev_info(&pdev->dev,

View file

@ -938,7 +938,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
ret = pm_runtime_get_sync(fsl_lpspi->dev); ret = pm_runtime_get_sync(fsl_lpspi->dev);
if (ret < 0) { if (ret < 0) {
dev_err(fsl_lpspi->dev, "failed to enable clock\n"); dev_err(fsl_lpspi->dev, "failed to enable clock\n");
return ret; goto out_controller_put;
} }
temp = readl(fsl_lpspi->base + IMX7ULP_PARAM); temp = readl(fsl_lpspi->base + IMX7ULP_PARAM);

View file

@ -63,6 +63,11 @@
#define QUADSPI_IPCR 0x08 #define QUADSPI_IPCR 0x08
#define QUADSPI_IPCR_SEQID(x) ((x) << 24) #define QUADSPI_IPCR_SEQID(x) ((x) << 24)
#define QUADSPI_FLSHCR 0x0c
#define QUADSPI_FLSHCR_TCSS_MASK GENMASK(3, 0)
#define QUADSPI_FLSHCR_TCSH_MASK GENMASK(11, 8)
#define QUADSPI_FLSHCR_TDH_MASK GENMASK(17, 16)
#define QUADSPI_BUF3CR 0x1c #define QUADSPI_BUF3CR 0x1c
#define QUADSPI_BUF3CR_ALLMST_MASK BIT(31) #define QUADSPI_BUF3CR_ALLMST_MASK BIT(31)
#define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8) #define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8)
@ -95,6 +100,9 @@
#define QUADSPI_FR 0x160 #define QUADSPI_FR 0x160
#define QUADSPI_FR_TFF_MASK BIT(0) #define QUADSPI_FR_TFF_MASK BIT(0)
#define QUADSPI_RSER 0x164
#define QUADSPI_RSER_TFIE BIT(0)
#define QUADSPI_SPTRCLR 0x16c #define QUADSPI_SPTRCLR 0x16c
#define QUADSPI_SPTRCLR_IPPTRC BIT(8) #define QUADSPI_SPTRCLR_IPPTRC BIT(8)
#define QUADSPI_SPTRCLR_BFPTRC BIT(0) #define QUADSPI_SPTRCLR_BFPTRC BIT(0)
@ -112,9 +120,6 @@
#define QUADSPI_LCKER_LOCK BIT(0) #define QUADSPI_LCKER_LOCK BIT(0)
#define QUADSPI_LCKER_UNLOCK BIT(1) #define QUADSPI_LCKER_UNLOCK BIT(1)
#define QUADSPI_RSER 0x164
#define QUADSPI_RSER_TFIE BIT(0)
#define QUADSPI_LUT_BASE 0x310 #define QUADSPI_LUT_BASE 0x310
#define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4) #define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4)
#define QUADSPI_LUT_REG(idx) \ #define QUADSPI_LUT_REG(idx) \
@ -181,6 +186,12 @@
*/ */
#define QUADSPI_QUIRK_BASE_INTERNAL BIT(4) #define QUADSPI_QUIRK_BASE_INTERNAL BIT(4)
/*
* Controller uses TDH bits in register QUADSPI_FLSHCR.
* They need to be set in accordance with the DDR/SDR mode.
*/
#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5)
struct fsl_qspi_devtype_data { struct fsl_qspi_devtype_data {
unsigned int rxfifo; unsigned int rxfifo;
unsigned int txfifo; unsigned int txfifo;
@ -209,7 +220,8 @@ static const struct fsl_qspi_devtype_data imx7d_data = {
.rxfifo = SZ_128, .rxfifo = SZ_128,
.txfifo = SZ_512, .txfifo = SZ_512,
.ahb_buf_size = SZ_1K, .ahb_buf_size = SZ_1K,
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
QUADSPI_QUIRK_USE_TDH_SETTING,
.little_endian = true, .little_endian = true,
}; };
@ -217,7 +229,8 @@ static const struct fsl_qspi_devtype_data imx6ul_data = {
.rxfifo = SZ_128, .rxfifo = SZ_128,
.txfifo = SZ_512, .txfifo = SZ_512,
.ahb_buf_size = SZ_1K, .ahb_buf_size = SZ_1K,
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
QUADSPI_QUIRK_USE_TDH_SETTING,
.little_endian = true, .little_endian = true,
}; };
@ -275,6 +288,11 @@ static inline int needs_amba_base_offset(struct fsl_qspi *q)
return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL); return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL);
} }
static inline int needs_tdh_setting(struct fsl_qspi *q)
{
return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING;
}
/* /*
* An IC bug makes it necessary to rearrange the 32-bit data. * An IC bug makes it necessary to rearrange the 32-bit data.
* Later chips, such as IMX6SLX, have fixed this bug. * Later chips, such as IMX6SLX, have fixed this bug.
@ -710,6 +728,16 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
base + QUADSPI_MCR); base + QUADSPI_MCR);
/*
* Previous boot stages (BootROM, bootloader) might have used DDR
* mode and did not clear the TDH bits. As we currently use SDR mode
* only, clear the TDH bits if necessary.
*/
if (needs_tdh_setting(q))
qspi_writel(q, qspi_readl(q, base + QUADSPI_FLSHCR) &
~QUADSPI_FLSHCR_TDH_MASK,
base + QUADSPI_FLSHCR);
reg = qspi_readl(q, base + QUADSPI_SMPR); reg = qspi_readl(q, base + QUADSPI_SMPR);
qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
| QUADSPI_SMPR_FSPHS_MASK | QUADSPI_SMPR_FSPHS_MASK

View file

@ -371,8 +371,10 @@ static int spi_gpio_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
status = devm_add_action_or_reset(&pdev->dev, spi_gpio_put, master); status = devm_add_action_or_reset(&pdev->dev, spi_gpio_put, master);
if (status) if (status) {
spi_master_put(master);
return status; return status;
}
if (of_id) if (of_id)
status = spi_gpio_probe_dt(pdev, master); status = spi_gpio_probe_dt(pdev, master);

View file

@ -145,8 +145,8 @@
#define LWR_SUSP_CTRL_EN BIT(31) #define LWR_SUSP_CTRL_EN BIT(31)
#define DMAS_CTRL 0x9c #define DMAS_CTRL 0x9c
#define DMAS_CTRL_DIR_READ BIT(31) #define DMAS_CTRL_EN BIT(31)
#define DMAS_CTRL_EN BIT(30) #define DMAS_CTRL_DIR_READ BIT(30)
#define DATA_STROB 0xa0 #define DATA_STROB 0xa0
#define DATA_STROB_EDO_EN BIT(2) #define DATA_STROB_EDO_EN BIT(2)
@ -275,7 +275,7 @@ static void mxic_spi_hw_init(struct mxic_spi *mxic)
writel(0, mxic->regs + HC_EN); writel(0, mxic->regs + HC_EN);
writel(0, mxic->regs + LRD_CFG); writel(0, mxic->regs + LRD_CFG);
writel(0, mxic->regs + LRD_CTRL); writel(0, mxic->regs + LRD_CTRL);
writel(HC_CFG_NIO(1) | HC_CFG_TYPE(0, HC_CFG_TYPE_SPI_NAND) | writel(HC_CFG_NIO(1) | HC_CFG_TYPE(0, HC_CFG_TYPE_SPI_NOR) |
HC_CFG_SLV_ACT(0) | HC_CFG_MAN_CS_EN | HC_CFG_IDLE_SIO_LVL(1), HC_CFG_SLV_ACT(0) | HC_CFG_MAN_CS_EN | HC_CFG_IDLE_SIO_LVL(1),
mxic->regs + HC_CFG); mxic->regs + HC_CFG);
} }

View file

@ -772,9 +772,6 @@ static int orion_spi_probe(struct platform_device *pdev)
if (status < 0) if (status < 0)
goto out_rel_pm; goto out_rel_pm;
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
status = spi_register_master(master); status = spi_register_master(master);
if (status < 0) if (status < 0)

View file

@ -1457,6 +1457,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
{ PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP },
/* CML-H */
{ PCI_VDEVICE(INTEL, 0x06aa), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x06ab), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x06fb), LPSS_CNL_SSP },
/* TGL-LP */ /* TGL-LP */
{ PCI_VDEVICE(INTEL, 0xa0aa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa0aa), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa0ab), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa0ab), LPSS_CNL_SSP },
@ -1545,17 +1549,15 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
if (!pdata) if (!pdata)
return NULL; return NULL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return NULL;
ssp = &pdata->ssp; ssp = &pdata->ssp;
ssp->phys_base = res->start; res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res); ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ssp->mmio_base)) if (IS_ERR(ssp->mmio_base))
return NULL; return NULL;
ssp->phys_base = res->start;
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
if (pcidev_id) { if (pcidev_id) {
pdata->tx_param = pdev->dev.parent; pdata->tx_param = pdev->dev.parent;
@ -1602,6 +1604,11 @@ static int pxa2xx_spi_fw_translate_cs(struct spi_controller *controller,
return cs; return cs;
} }
static size_t pxa2xx_spi_max_dma_transfer_size(struct spi_device *spi)
{
return MAX_DMA_LEN;
}
static int pxa2xx_spi_probe(struct platform_device *pdev) static int pxa2xx_spi_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
@ -1707,6 +1714,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
} else { } else {
controller->can_dma = pxa2xx_spi_can_dma; controller->can_dma = pxa2xx_spi_can_dma;
controller->max_dma_len = MAX_DMA_LEN; controller->max_dma_len = MAX_DMA_LEN;
controller->max_transfer_size =
pxa2xx_spi_max_dma_transfer_size;
} }
} }

View file

@ -1257,9 +1257,9 @@ static int rspi_probe(struct platform_device *pdev)
ctlr->flags = ops->flags; ctlr->flags = ops->flags;
ctlr->dev.of_node = pdev->dev.of_node; ctlr->dev.of_node = pdev->dev.of_node;
ret = platform_get_irq_byname(pdev, "rx"); ret = platform_get_irq_byname_optional(pdev, "rx");
if (ret < 0) { if (ret < 0) {
ret = platform_get_irq_byname(pdev, "mux"); ret = platform_get_irq_byname_optional(pdev, "mux");
if (ret < 0) if (ret < 0)
ret = platform_get_irq(pdev, 0); ret = platform_get_irq(pdev, 0);
if (ret >= 0) if (ret >= 0)
@ -1270,10 +1270,6 @@ static int rspi_probe(struct platform_device *pdev)
if (ret >= 0) if (ret >= 0)
rspi->tx_irq = ret; rspi->tx_irq = ret;
} }
if (ret < 0) {
dev_err(&pdev->dev, "platform_get_irq error\n");
goto error2;
}
if (rspi->rx_irq == rspi->tx_irq) { if (rspi->rx_irq == rspi->tx_irq) {
/* Single multiplexed interrupt */ /* Single multiplexed interrupt */

View file

@ -357,14 +357,14 @@ static int sifive_spi_probe(struct platform_device *pdev)
if (!cs_bits) { if (!cs_bits) {
dev_err(&pdev->dev, "Could not auto probe CS lines\n"); dev_err(&pdev->dev, "Could not auto probe CS lines\n");
ret = -EINVAL; ret = -EINVAL;
goto put_master; goto disable_clk;
} }
num_cs = ilog2(cs_bits) + 1; num_cs = ilog2(cs_bits) + 1;
if (num_cs > SIFIVE_SPI_MAX_CS) { if (num_cs > SIFIVE_SPI_MAX_CS) {
dev_err(&pdev->dev, "Invalid number of spi slaves\n"); dev_err(&pdev->dev, "Invalid number of spi slaves\n");
ret = -EINVAL; ret = -EINVAL;
goto put_master; goto disable_clk;
} }
/* Define our master */ /* Define our master */
@ -393,7 +393,7 @@ static int sifive_spi_probe(struct platform_device *pdev)
dev_name(&pdev->dev), spi); dev_name(&pdev->dev), spi);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to bind to interrupt\n"); dev_err(&pdev->dev, "Unable to bind to interrupt\n");
goto put_master; goto disable_clk;
} }
dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n", dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
@ -402,11 +402,13 @@ static int sifive_spi_probe(struct platform_device *pdev)
ret = devm_spi_register_master(&pdev->dev, master); ret = devm_spi_register_master(&pdev->dev, master);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "spi_register_master failed\n"); dev_err(&pdev->dev, "spi_register_master failed\n");
goto put_master; goto disable_clk;
} }
return 0; return 0;
disable_clk:
clk_disable_unprepare(spi->clk);
put_master: put_master:
spi_master_put(master); spi_master_put(master);
@ -420,6 +422,7 @@ static int sifive_spi_remove(struct platform_device *pdev)
/* Disable all the interrupts just in case */ /* Disable all the interrupts just in case */
sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
clk_disable_unprepare(spi->clk);
return 0; return 0;
} }

View file

@ -528,7 +528,6 @@ static void stm32_qspi_release(struct stm32_qspi *qspi)
stm32_qspi_dma_free(qspi); stm32_qspi_dma_free(qspi);
mutex_destroy(&qspi->lock); mutex_destroy(&qspi->lock);
clk_disable_unprepare(qspi->clk); clk_disable_unprepare(qspi->clk);
spi_master_put(qspi->ctrl);
} }
static int stm32_qspi_probe(struct platform_device *pdev) static int stm32_qspi_probe(struct platform_device *pdev)
@ -626,6 +625,8 @@ static int stm32_qspi_probe(struct platform_device *pdev)
err: err:
stm32_qspi_release(qspi); stm32_qspi_release(qspi);
spi_master_put(qspi->ctrl);
return ret; return ret;
} }

View file

@ -1711,15 +1711,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
spi->mode |= SPI_3WIRE; spi->mode |= SPI_3WIRE;
if (of_property_read_bool(nc, "spi-lsb-first")) if (of_property_read_bool(nc, "spi-lsb-first"))
spi->mode |= SPI_LSB_FIRST; spi->mode |= SPI_LSB_FIRST;
if (of_property_read_bool(nc, "spi-cs-high"))
/*
* For descriptors associated with the device, polarity inversion is
* handled in the gpiolib, so all chip selects are "active high" in
* the logical sense, the gpiolib will invert the line if need be.
*/
if (ctlr->use_gpio_descriptors)
spi->mode |= SPI_CS_HIGH;
else if (of_property_read_bool(nc, "spi-cs-high"))
spi->mode |= SPI_CS_HIGH; spi->mode |= SPI_CS_HIGH;
/* Device DUAL/QUAD mode */ /* Device DUAL/QUAD mode */
@ -1783,6 +1775,15 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
} }
spi->chip_select = value; spi->chip_select = value;
/*
* For descriptors associated with the device, polarity inversion is
* handled in the gpiolib, so all gpio chip selects are "active high"
* in the logical sense, the gpiolib will invert the line if need be.
*/
if ((ctlr->use_gpio_descriptors) && ctlr->cs_gpiods &&
ctlr->cs_gpiods[spi->chip_select])
spi->mode |= SPI_CS_HIGH;
/* Device speed */ /* Device speed */
rc = of_property_read_u32(nc, "spi-max-frequency", &value); rc = of_property_read_u32(nc, "spi-max-frequency", &value);
if (rc) { if (rc) {

View file

@ -627,6 +627,9 @@ static int spidev_release(struct inode *inode, struct file *filp)
if (dofree) if (dofree)
kfree(spidev); kfree(spidev);
} }
#ifdef CONFIG_SPI_SLAVE
spi_slave_abort(spidev->spi);
#endif
mutex_unlock(&device_list_lock); mutex_unlock(&device_list_lock);
return 0; return 0;