Commit b88f5577 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi updates from Mark Brown:
 "A fairly quiet release for the SPI subsystem:

   - Move to using IDR for allocating bus numbers

   - Modernisation of the ep93xx driver, removing a lot of open coding
     and using the framework more

   - The tools have been moved to use the standard tools build system
     and an install target added (there will be a fairly trivial
     conflict with tip resulting from the changes in the main tools
     Makefile)

   - A refactoring of the Qualcomm QUP driver which enables new variants
     to be supported

   - Explicit support for the Freescale i.MX53 and i.MX6 SPI, Renesas
     R-Car H3 and Rockchip RV1108 controllers"

* tag 'spi-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (71 commits)
  spi: spi-falcon: drop check of boot select
  spi: imx: fix use of native chip-selects with devicetree
  spi: pl022: constify amba_id
  spi: imx: fix little-endian build
  spi: omap: Allocate bus number from spi framework
  spi: Kernel coding style fixes
  spi: imx: dynamic burst length adjust for PIO mode
  spi: Pick spi bus number from Linux idr or spi alias
  spi: rockchip: configure CTRLR1 according to size and data frame
  spi: altera: Consolidate TX/RX data register access
  spi: altera: Switch to SPI core transfer queue management
  spi: rockchip: add compatible string for rv1108 spi
  spi: qup: fix 64-bit build warning
  spi: qup: hide warning for uninitialized variable
  spi: spi-ep93xx: use the default master transfer queueing mechanism
  spi: spi-ep93xx: remove private data 'current_msg'
  spi: spi-ep93xx: pass the spi_master pointer around
  spi: spi-ep93xx: absorb the interrupt enable/disable helpers
  spi: spi-ep93xx: add spi master prepare_transfer_hardware()
  spi: spi-ep93xx: use 32-bit read/write for all registers
  ...
parents 16a832a2 ecb478bf
......@@ -9,6 +9,7 @@ Required properties:
- "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31
- "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35
- "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51
- "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc
- reg : Offset and length of the register set for the device
- interrupts : Should contain CSPI/eCSPI interrupt
- cs-gpios : Specifies the gpio pins to be used for chipselects.
......
......@@ -6,6 +6,7 @@ Required properties:
"renesas,msiof-r8a7792" (R-Car V2H)
"renesas,msiof-r8a7793" (R-Car M2-N)
"renesas,msiof-r8a7794" (R-Car E2)
"renesas,msiof-r8a7795" (R-Car H3)
"renesas,msiof-r8a7796" (R-Car M3-W)
"renesas,msiof-sh73a0" (SH-Mobile AG5)
"renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
......
......@@ -6,6 +6,7 @@ and display controllers using the SPI communication interface.
Required Properties:
- compatible: should be one of the following.
"rockchip,rv1108-spi" for rv1108 SoCs.
"rockchip,rk3036-spi" for rk3036 SoCS.
"rockchip,rk3066-spi" for rk3066 SoCs.
"rockchip,rk3188-spi" for rk3188 SoCs.
......
......@@ -55,7 +55,6 @@ comment "SPI Master Controller Drivers"
config SPI_ALTERA
tristate "Altera SPI Controller"
select SPI_BITBANG
help
This is the driver for the Altera SPI Controller.
......@@ -518,8 +517,8 @@ config SPI_PPC4xx
config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on (ARCH_PXA || PCI || ACPI)
select PXA_SSP if ARCH_PXA
depends on (ARCH_PXA || ARCH_MMP || PCI || ACPI)
select PXA_SSP if ARCH_PXA || ARCH_MMP
help
This enables using a PXA2xx or Sodaville SSP port as a SPI master
controller. The driver can be configured to use any SSP port and
......
......@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/io.h>
#include <linux/of.h>
......@@ -45,10 +44,6 @@
#define ALTERA_SPI_CONTROL_SSO_MSK 0x400
struct altera_spi {
/* bitbang has to be first */
struct spi_bitbang bitbang;
struct completion done;
void __iomem *base;
int irq;
int len;
......@@ -66,59 +61,64 @@ static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
return spi_master_get_devdata(sdev->master);
}
static void altera_spi_chipsel(struct spi_device *spi, int value)
static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
{
struct altera_spi *hw = altera_spi_to_hw(spi);
if (spi->mode & SPI_CS_HIGH) {
switch (value) {
case BITBANG_CS_INACTIVE:
writel(1 << spi->chip_select,
hw->base + ALTERA_SPI_SLAVE_SEL);
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
break;
case BITBANG_CS_ACTIVE:
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
break;
}
if (is_high) {
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
} else {
switch (value) {
case BITBANG_CS_INACTIVE:
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
break;
writel(BIT(spi->chip_select), hw->base + ALTERA_SPI_SLAVE_SEL);
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
}
}
static void altera_spi_tx_word(struct altera_spi *hw)
{
unsigned int txd = 0;
case BITBANG_CS_ACTIVE:
writel(1 << spi->chip_select,
hw->base + ALTERA_SPI_SLAVE_SEL);
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
if (hw->tx) {
switch (hw->bytes_per_word) {
case 1:
txd = hw->tx[hw->count];
break;
case 2:
txd = (hw->tx[hw->count * 2]
| (hw->tx[hw->count * 2 + 1] << 8));
break;
}
}
writel(txd, hw->base + ALTERA_SPI_TXDATA);
}
static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
static void altera_spi_rx_word(struct altera_spi *hw)
{
if (hw->tx) {
unsigned int rxd;
rxd = readl(hw->base + ALTERA_SPI_RXDATA);
if (hw->rx) {
switch (hw->bytes_per_word) {
case 1:
return hw->tx[count];
hw->rx[hw->count] = rxd;
break;
case 2:
return (hw->tx[count * 2]
| (hw->tx[count * 2 + 1] << 8));
hw->rx[hw->count * 2] = rxd;
hw->rx[hw->count * 2 + 1] = rxd >> 8;
break;
}
}
return 0;
hw->count++;
}
static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
static int altera_spi_txrx(struct spi_master *master,
struct spi_device *spi, struct spi_transfer *t)
{
struct altera_spi *hw = altera_spi_to_hw(spi);
struct altera_spi *hw = spi_master_get_devdata(master);
hw->tx = t->tx_buf;
hw->rx = t->rx_buf;
......@@ -132,67 +132,39 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
/* send the first byte */
writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);
wait_for_completion(&hw->done);
/* disable receive interrupt */
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
altera_spi_tx_word(hw);
} else {
while (hw->count < hw->len) {
unsigned int rxd;
writel(hw_txbyte(hw, hw->count),
hw->base + ALTERA_SPI_TXDATA);
altera_spi_tx_word(hw);
while (!(readl(hw->base + ALTERA_SPI_STATUS) &
ALTERA_SPI_STATUS_RRDY_MSK))
cpu_relax();
rxd = readl(hw->base + ALTERA_SPI_RXDATA);
if (hw->rx) {
switch (hw->bytes_per_word) {
case 1:
hw->rx[hw->count] = rxd;
break;
case 2:
hw->rx[hw->count * 2] = rxd;
hw->rx[hw->count * 2 + 1] = rxd >> 8;
break;
}
}
hw->count++;
altera_spi_rx_word(hw);
}
spi_finalize_current_transfer(master);
}
return hw->count * hw->bytes_per_word;
return t->len;
}
static irqreturn_t altera_spi_irq(int irq, void *dev)
{
struct altera_spi *hw = dev;
unsigned int rxd;
struct spi_master *master = dev;
struct altera_spi *hw = spi_master_get_devdata(master);
rxd = readl(hw->base + ALTERA_SPI_RXDATA);
if (hw->rx) {
switch (hw->bytes_per_word) {
case 1:
hw->rx[hw->count] = rxd;
break;
case 2:
hw->rx[hw->count * 2] = rxd;
hw->rx[hw->count * 2 + 1] = rxd >> 8;
break;
}
}
altera_spi_rx_word(hw);
hw->count++;
if (hw->count < hw->len) {
altera_spi_tx_word(hw);
} else {
/* disable receive interrupt */
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
if (hw->count < hw->len)
writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA);
else
complete(&hw->done);
spi_finalize_current_transfer(master);
}
return IRQ_HANDLED;
}
......@@ -214,14 +186,10 @@ static int altera_spi_probe(struct platform_device *pdev)
master->mode_bits = SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
master->dev.of_node = pdev->dev.of_node;
master->transfer_one = altera_spi_txrx;
master->set_cs = altera_spi_set_cs;
hw = spi_master_get_devdata(master);
platform_set_drvdata(pdev, hw);
/* setup the state for the bitbang driver */
hw->bitbang.master = master;
hw->bitbang.chipselect = altera_spi_chipsel;
hw->bitbang.txrx_bufs = altera_spi_txrx;
/* find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......@@ -239,15 +207,13 @@ static int altera_spi_probe(struct platform_device *pdev)
/* irq is optional */
hw->irq = platform_get_irq(pdev, 0);
if (hw->irq >= 0) {
init_completion(&hw->done);
err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
pdev->name, hw);
pdev->name, master);
if (err)
goto exit;
}
/* register our spi controller */
err = spi_bitbang_start(&hw->bitbang);
err = devm_spi_register_master(&pdev->dev, master);
if (err)
goto exit;
dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);
......@@ -258,16 +224,6 @@ static int altera_spi_probe(struct platform_device *pdev)
return err;
}
static int altera_spi_remove(struct platform_device *dev)
{
struct altera_spi *hw = platform_get_drvdata(dev);
struct spi_master *master = hw->bitbang.master;
spi_bitbang_stop(&hw->bitbang);
spi_master_put(master);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id altera_spi_match[] = {
{ .compatible = "ALTR,spi-1.0", },
......@@ -279,7 +235,6 @@ MODULE_DEVICE_TABLE(of, altera_spi_match);
static struct platform_driver altera_spi_driver = {
.probe = altera_spi_probe,
.remove = altera_spi_remove,
.driver = {
.name = DRV_NAME,
.pm = NULL,
......
......@@ -39,15 +39,15 @@ struct ath79_spi {
u32 reg_ctrl;
void __iomem *base;
struct clk *clk;
unsigned rrw_delay;
unsigned int rrw_delay;
};
static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned int reg)
{
return ioread32(sp->base + reg);
}
static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned int reg, u32 val)
{
iowrite32(val, sp->base + reg);
}
......@@ -57,7 +57,7 @@ static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi)
return spi_master_get_devdata(spi->master);
}
static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned nsecs)
static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned int nsecs)
{
if (nsecs > sp->rrw_delay)
ndelay(nsecs - sp->rrw_delay);
......@@ -148,9 +148,8 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
static void ath79_spi_cleanup_cs(struct spi_device *spi)
{
if (gpio_is_valid(spi->cs_gpio)) {
if (gpio_is_valid(spi->cs_gpio))
gpio_free(spi->cs_gpio);
}
}
static int ath79_spi_setup(struct spi_device *spi)
......@@ -176,7 +175,7 @@ static void ath79_spi_cleanup(struct spi_device *spi)
spi_bitbang_cleanup(spi);
}
static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs,
u32 word, u8 bits)
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
......
......@@ -25,7 +25,6 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mtd/spi-nor.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
......@@ -349,76 +348,60 @@ static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte,
bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode);
}
static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, int width,
int addrlen, int hp)
static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi,
struct spi_flash_read_message *msg,
int hp)
{
int bpc = 0, bpp = 0;
u8 command = SPINOR_OP_READ_FAST;
int flex_mode = 1, rv = 0;
bool spans_4byte = false;
u8 command = msg->read_opcode;
int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
int addrlen = msg->addr_width;
int addr_nbits = msg->addr_nbits ? msg->addr_nbits : SPI_NBITS_SINGLE;
int flex_mode = 1;
dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n",
width, addrlen, hp);
if (addrlen == BSPI_ADDRLEN_4BYTES) {
if (addrlen == BSPI_ADDRLEN_4BYTES)
bpp = BSPI_BPP_ADDR_SELECT_MASK;
spans_4byte = true;
}
bpp |= 8;
bpp |= msg->dummy_bytes * (8/addr_nbits);
switch (width) {
case SPI_NBITS_SINGLE:
if (addrlen == BSPI_ADDRLEN_3BYTES)
/* default mode, does not need flex_cmd */
flex_mode = 0;
else
command = SPINOR_OP_READ_FAST_4B;
break;
case SPI_NBITS_DUAL:
bpc = 0x00000001;
if (hp) {
bpc |= 0x00010100; /* address and mode are 2-bit */
bpp = BSPI_BPP_MODE_SELECT_MASK;
command = OPCODE_DIOR;
if (spans_4byte)
command = OPCODE_DIOR_4B;
} else {
command = SPINOR_OP_READ_1_1_2;
if (spans_4byte)
command = SPINOR_OP_READ_1_1_2_4B;
}
break;
case SPI_NBITS_QUAD:
bpc = 0x00000002;
if (hp) {
bpc |= 0x00020200; /* address and mode are 4-bit */
bpp = 4; /* dummy cycles */
bpp |= BSPI_BPP_ADDR_SELECT_MASK;
command = OPCODE_QIOR;
if (spans_4byte)
command = OPCODE_QIOR_4B;
} else {
command = SPINOR_OP_READ_1_1_4;
if (spans_4byte)
command = SPINOR_OP_READ_1_1_4_4B;
bpp |= BSPI_BPP_MODE_SELECT_MASK;
}
break;
default:
rv = -EINVAL;
break;
return -EINVAL;
}
if (rv == 0)
bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc,
flex_mode);
bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc, flex_mode);
return rv;
return 0;
}
static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width,
int addrlen, int hp)
static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi,
struct spi_flash_read_message *msg,
int hp)
{
int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
int addrlen = msg->addr_width;
u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n",
......@@ -430,7 +413,6 @@ static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width,
data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD |
BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL);
break;
case SPI_NBITS_QUAD:
/* clear dual mode and set quad mode */
data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
......@@ -455,15 +437,17 @@ static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width,
/* set the override mode */
data |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data);
bcm_qspi_bspi_set_xfer_params(qspi, SPINOR_OP_READ_FAST, 0, 0, 0);
bcm_qspi_bspi_set_xfer_params(qspi, msg->read_opcode, 0, 0, 0);
return 0;
}
static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi,
int width, int addrlen, int hp)
struct spi_flash_read_message *msg, int hp)
{
int error = 0;
int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
int addrlen = msg->addr_width;
/* default mode */
qspi->xfer_mode.flex_mode = true;
......@@ -475,23 +459,13 @@ static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi,
mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
if (val & mask || qspi->s3_strap_override_ctrl & mask) {
qspi->xfer_mode.flex_mode = false;
bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE,
0);
if ((val | qspi->s3_strap_override_ctrl) &
BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL)
width = SPI_NBITS_DUAL;
else if ((val | qspi->s3_strap_override_ctrl) &
BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD)
width = SPI_NBITS_QUAD;
error = bcm_qspi_bspi_set_override(qspi, width, addrlen,
hp);
bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0);
error = bcm_qspi_bspi_set_override(qspi, msg, hp);
}
}
if (qspi->xfer_mode.flex_mode)
error = bcm_qspi_bspi_set_flex_mode(qspi, width, addrlen, hp);
error = bcm_qspi_bspi_set_flex_mode(qspi, msg, hp);
if (error) {
dev_warn(&qspi->pdev->dev,
......@@ -981,7 +955,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi,
struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
int ret = 0;
bool mspi_read = false;
u32 io_width, addrlen, addr, len;
u32 addr, len;
u_char *buf;
buf = msg->buf;
......@@ -1010,9 +984,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi,
if (mspi_read)
return bcm_qspi_mspi_flash_read(spi, msg);
io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
addrlen = msg->addr_width;
ret = bcm_qspi_bspi_set_mode(qspi, io_width, addrlen, -1);
ret = bcm_qspi_bspi_set_mode(qspi, msg, -1);
if (!ret)
ret = bcm_qspi_bspi_flash_read(spi, msg);
......@@ -1422,6 +1394,11 @@ static int __maybe_unused bcm_qspi_suspend(struct device *dev)
{
struct bcm_qspi *qspi = dev_get_drvdata(dev);
/* store the override strap value */
if (!bcm_qspi_bspi_ver_three(qspi))
qspi->s3_strap_override_ctrl =
bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
spi_master_suspend(qspi->master);
clk_disable(qspi->clk);
bcm_qspi_hw_uninit(qspi);
......
......@@ -108,7 +108,7 @@ struct bcm63xx_hsspi {
u8 cs_polarity;
};
static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned cs,
static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned int cs,
bool active)
{
u32 reg;
......@@ -127,7 +127,7 @@ static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned cs,
static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs,
struct spi_device *spi, int hz)
{
unsigned profile = spi->chip_select;
unsigned int profile = spi->chip_select;
u32 reg;
reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz));
......@@ -154,7 +154,7 @@ static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs,
static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
unsigned chip_select = spi->chip_select;
unsigned int chip_select = spi->chip_select;
u16 opcode = 0;
int pending = t->len;
int step_size = HSSPI_BUFFER_LEN;
......@@ -338,8 +338,8 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq\n");
return -ENXIO;
dev_err(dev, "no irq: %d\n", irq);
return irq;
}
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......
......@@ -530,8 +530,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq\n");
return -ENXIO;
dev_err(dev, "no irq: %d\n", irq);
return irq;
}
clk = devm_clk_get(dev, "spi");
......
......@@ -576,10 +576,10 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto clk_dis_apb;
}
pm_runtime_enable(&pdev->dev);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
if (ret < 0)
......@@ -704,7 +704,9 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
struct cdns_spi *xspi = spi_master_get_devdata(master);
cdns_spi_init_hw(xspi);
return spi_master_resume(master);
}
......
This diff is collapsed.
......@@ -395,11 +395,6 @@ static int falcon_sflash_probe(struct platform_device *pdev)
struct spi_master *master;
int ret;
if (ltq_boot_select() != BS_SPI) {
dev_err(&pdev->dev, "invalid bootstrap options\n");
return -ENODEV;
}
master = spi_alloc_master(&pdev->dev, sizeof(*priv));
if (!master)
return -ENOMEM;
......
This diff is collapsed.
......@@ -32,39 +32,50 @@
#include "spi-test.h"
/* flag to only simulate transfers */
int simulate_only;
static int simulate_only;
module_param(simulate_only, int, 0);
MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message");
/* dump spi messages */
int dump_messages;
static int dump_messages;
module_param(dump_messages, int, 0);
MODULE_PARM_DESC(dump_messages,
"=1 dump the basic spi_message_structure, " \
"=2 dump the spi_message_structure including data, " \
"=3 dump the spi_message structure before and after execution");
/* the device is jumpered for loopback - enabling some rx_buf tests */
int loopback;
static int loopback;
module_param(loopback, int, 0);
MODULE_PARM_DESC(loopback,
"if set enable loopback mode, where the rx_buf " \
"is checked to match tx_buf after the spi_message " \
"is executed");
static int loop_req;
module_param(loop_req, int, 0);
MODULE_PARM_DESC(loop_req,
"if set controller will be asked to enable test loop mode. " \
"If controller supported it, MISO and MOSI will be connected");
static int no_cs;
module_param(no_cs, int, 0);
MODULE_PARM_DESC(no_cs,
"if set Chip Select (CS) will not be used");
/* run only a specific test */
int run_only_test = -1;
static int run_only_test = -1;
module_param(run_only_test, int, 0);
MODULE_PARM_DESC(run_only_test,
"only run the test with this number (0-based !)");
/* use vmalloc'ed buffers */
int use_vmalloc;
static int use_vmalloc;
module_param(use_vmalloc, int, 0644);
MODULE_PARM_DESC(use_vmalloc,
"use vmalloc'ed buffers instead of kmalloc'ed");
/* check rx ranges */
int check_ranges = 1;
static int check_ranges = 1;
module_param(check_ranges, int, 0644);
MODULE_PARM_DESC(check_ranges,
"checks rx_buffer pattern are valid");
......@@ -313,6 +324,17 @@ static int spi_loopback_test_probe(struct spi_device *spi)
{
int ret;
if (loop_req || no_cs) {
spi->mode |= loop_req ? SPI_LOOP : 0;
spi->mode |= no_cs ? SPI_NO_CS : 0;
ret = spi_setup(spi);
if (ret) {
dev_err(&spi->dev, "SPI setup with SPI_LOOP or SPI_NO_CS failed (%d)\n",
ret);
return ret;
}
}
dev_info(&spi->dev, "Executing spi-loopback-tests\n");
ret = spi_test_run_tests(spi, spi_tests);
......
......@@ -1338,7 +1338,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
struct resource *r;
int status = 0, i;
u32 regs_offset = 0;
static int bus_num = 1;
struct device_node *node = pdev->dev.of_node;
const struct of_device_id *match;
......@@ -1374,14 +1373,11 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
of_property_read_u32(node, "ti,spi-num-cs", &num_cs);
master->num_chipselect = num_cs;
master->bus_num = bus_num++;
if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL))
mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
} else {
pdata = dev_get_platdata(&pdev->dev);
master->num_chipselect = pdata->num_cs;
if (pdev->id != -1)
master->bus_num = pdev->id;
mcspi->pin_dir = pdata->pin_dir;
}
regs_offset = pdata->regs_offset;
......
......@@ -669,8 +669,8 @@ static int orion_spi_probe(struct platform_device *pdev)
status = of_property_read_u32(np, "reg", &cs);
if (status) {
dev_err(&pdev->dev,
"%s has no valid 'reg' property (%d)\n",
np->full_name, status);
"%pOF has no valid 'reg' property (%d)\n",
np, status);
status = 0;
continue;
}
......
......@@ -52,14 +52,14 @@ struct pic32_spi_regs {
/* Bit fields of SPI Control Register */
#define CTRL_RX_INT_SHIFT 0 /* Rx interrupt generation */
#define RX_FIFO_EMTPY 0
#define RX_FIFO_EMPTY 0
#define RX_FIFO_NOT_EMPTY 1 /* not empty */
#define RX_FIFO_HALF_FULL 2 /* full by half or more */
#define RX_FIFO_FULL 3 /* completely full */
#define CTRL_TX_INT_SHIFT 2 /* TX interrupt generation */
#define TX_FIFO_ALL_EMPTY 0 /* completely empty */
#define TX_FIFO_EMTPY 1 /* empty */
#define TX_FIFO_EMPTY 1 /* empty */
#define TX_FIFO_HALF_EMPTY 2 /* empty by half or more */
#define TX_FIFO_NOT_FULL 3 /* atleast one empty */
......
......@@ -2429,7 +2429,7 @@ static struct vendor_data vendor_lsi = {
.internal_cs_ctrl = true,
};
static struct amba_id pl022_ids[] = {
static const struct amba_id pl022_ids[] = {
{
/*
* ARM PL022 variant, this has a 16bit wide
......
......@@ -402,8 +402,8 @@ static void cs_assert(struct driver_data *drv_data)
return;
}
if (gpio_is_valid(chip->gpio_cs)) {
gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted);
if (chip->gpiod_cs) {
gpiod_set_value(chip->gpiod_cs, chip->gpio_cs_inverted);
return;
}
......@@ -424,8 +424,8 @@ static void cs_deassert(struct driver_data *drv_data)
return;
}
if (gpio_is_valid(chip->gpio_cs)) {
gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted);
if (chip->gpiod_cs) {
gpiod_set_value(chip->gpiod_cs, !chip->gpio_cs_inverted);
return;
}
......@@ -1213,17 +1213,16 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip,
struct pxa2xx_spi_chip *chip_info)
{
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
struct gpio_desc *gpiod;
int err = 0;
if (chip == NULL)
return 0;
if (drv_data->cs_gpiods) {
struct gpio_desc *gpiod;
gpiod = drv_data->cs_gpiods[spi->chip_select];
if (gpiod) {
chip->gpio_cs = desc_to_gpio(gpiod);
chip->gpiod_cs = gpiod;
chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
gpiod_set_value(gpiod, chip->gpio_cs_inverted);
}
......@@ -1237,8 +1236,10 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip,
/* NOTE: setup() can be called multiple times, possibly with
* different chip_info, release previously requested GPIO
*/
if (gpio_is_valid(chip->gpio_cs))
gpio_free(chip->gpio_cs);
if (chip->gpiod_cs) {
gpio_free(desc_to_gpio(chip->gpiod_cs));
chip->gpiod_cs = NULL;
}
/* If (*cs_control) is provided, ignore GPIO chip select */
if (chip_info->cs_control) {
......@@ -1254,11 +1255,11 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip,
return err;
}
chip->gpio_cs = chip_info->gpio_cs;
gpiod = gpio_to_desc(chip_info->gpio_cs);
chip->gpiod_cs = gpiod;
chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
err = gpio_direction_output(chip->gpio_cs,
!chip->gpio_cs_inverted);
err = gpiod_direction_output(gpiod, !chip->gpio_cs_inverted);
}
return err;
......@@ -1317,8 +1318,7 @@ static int setup(struct spi_device *spi)
}
chip->frm = spi->chip_select;
} else
chip->gpio_cs = -1;
}
chip->enable_dma = drv_data->master_info->enable_dma;
chip->timeout = TIMOUT_DFLT;
}
......@@ -1416,8 +1416,8 @@ static void cleanup(struct spi_device *spi)
return;
if (drv_data->ssp_type != CE4100_SSP && !drv_data->cs_gpiods &&
gpio_is_valid(chip->gpio_cs))
gpio_free(chip->gpio_cs);
chip->gpiod_cs)
gpio_free(desc_to_gpio(chip->gpiod_cs));
kfree(chip);
}
......@@ -1769,8 +1769,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
for (i = 0; i < master->num_chipselect; i++) {
struct gpio_desc *gpiod;
gpiod = devm_gpiod_get_index(dev, "cs", i,
GPIOD_OUT_HIGH);
gpiod = devm_gpiod_get_index(dev, "cs", i, GPIOD_ASIS);
if (IS_ERR(gpiod)) {
/* Means use native chip select */
if (PTR_ERR(gpiod) == -ENOENT)
......
......@@ -83,7 +83,7 @@ struct chip_data {
u16 lpss_tx_threshold;
u8 enable_dma;
union {
int gpio_cs;
struct gpio_desc *gpiod_cs;
unsigned int frm;
};
int gpio_cs_inverted;
......
This diff is collapsed.
......@@ -568,7 +568,13 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
if (rs->n_bytes == 1)
writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
else if (rs->n_bytes == 2)
writel_relaxed((rs->len / 2) - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
else
writel_relaxed((rs->len * 2) - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_TXFTLR);
writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
......@@ -666,7 +672,7 @@ static bool rockchip_spi_can_dma(struct spi_master *master,
static int rockchip_spi_probe(struct platform_device *pdev)
{
int ret = 0;
int ret;
struct rockchip_spi *rs;
struct spi_master *master;
struct resource *mem;
......@@ -703,13 +709,13 @@ static int rockchip_spi_probe(struct platform_device *pdev)
}
ret = clk_prepare_enable(rs->apb_pclk);
if (ret) {
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable apb_pclk\n");
goto err_put_master;
}
ret = clk_prepare_enable(rs->spiclk);
if (ret) {
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable spi_clk\n");
goto err_disable_apbclk;
}
......@@ -786,7 +792,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
}
ret = devm_spi_register_master(&pdev->dev, master);
if (ret) {
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register master\n");
goto err_free_dma_rx;
}
......@@ -816,11 +822,15 @@ static int rockchip_spi_remove(struct platform_device *pdev)
struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
struct rockchip_spi *rs = spi_master_get_devdata(master);
pm_runtime_disable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(rs->spiclk);
clk_disable_unprepare(rs->apb_pclk);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
if (rs->dma_tx.ch)
dma_release_channel(rs->dma_tx.ch);
if (rs->dma_rx.ch)
......@@ -834,43 +844,34 @@ static int rockchip_spi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int rockchip_spi_suspend(struct device *dev)
{
int ret = 0;
int ret;
struct spi_master *master = dev_get_drvdata(dev);
struct rockchip_spi *rs = spi_master_get_devdata(master);
ret = spi_master_suspend(rs->master);
if (ret)
if (ret < 0)
return ret;
if (!pm_runtime_suspended(dev)) {
clk_disable_unprepare(rs->spiclk);
clk_disable_unprepare(rs->apb_pclk);
}
ret = pm_runtime_force_suspend(dev);
if (ret < 0)
return ret;
pinctrl_pm_select_sleep_state(dev);
return ret;
return 0;
}
static int rockchip_spi_resume(struct device *dev)
{
int ret = 0;
int ret;
struct spi_master *master = dev_get_drvdata(dev);
struct rockchip_spi *rs = spi_master_get_devdata(master);
pinctrl_pm_select_default_state(dev);
if (!pm_runtime_suspended(dev)) {
ret = clk_prepare_enable(rs->apb_pclk);
if (ret < 0)
return ret;
ret = clk_prepare_enable(rs->spiclk);
if (ret < 0) {
clk_disable_unprepare(rs->apb_pclk);
return ret;
}
}
ret = pm_runtime_force_resume(dev);
if (ret < 0)
return ret;
ret = spi_master_resume(rs->master);
if (ret < 0) {
......@@ -878,7 +879,7 @@ static int rockchip_spi_resume(struct device *dev)
clk_disable_unprepare(rs->apb_pclk);
}
return ret;
return 0;
}
#endif /* CONFIG_PM_SLEEP */
......@@ -901,14 +902,14 @@ static int rockchip_spi_runtime_resume(struct device *dev)
struct rockchip_spi *rs = spi_master_get_devdata(master);
ret = clk_prepare_enable(rs->apb_pclk);
if (ret)
if (ret < 0)
return ret;
ret = clk_prepare_enable(rs->spiclk);
if (ret)
if (ret < 0)
clk_disable_unprepare(rs->apb_pclk);
return ret;
return 0;
}
#endif /* CONFIG_PM */
......@@ -919,6 +920,7 @@ static const struct dev_pm_ops rockchip_spi_pm = {
};
static const struct of_device_id rockchip_spi_dt_match[] = {
{ .compatible = "rockchip,rv1108-spi", },
{ .compatible = "rockchip,rk3036-spi", },
{ .compatible = "rockchip,rk3066-spi", },
{ .compatible = "rockchip,rk3188-spi", },
......
......@@ -38,6 +38,7 @@ struct sh_msiof_chipdata {
u16 tx_fifo_size;
u16 rx_fifo_size;
u16 master_flags;
u16 min_div;
};
struct sh_msiof_spi_priv {
......@@ -49,6 +50,7 @@ struct sh_msiof_spi_priv {
struct completion done;
unsigned int tx_fifo_size;
unsigned int rx_fifo_size;
unsigned int min_div;
void *tx_dma_page;
void *rx_dma_page;
dma_addr_t tx_dma_addr;
......@@ -261,6 +263,8 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
if (!WARN_ON(!spi_hz || !parent_rate))
div = DIV_ROUND_UP(parent_rate, spi_hz);
div = max_t(unsigned long, div, p->min_div);
for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) {
brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div);
/* SCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */
......@@ -998,24 +1002,33 @@ static const struct sh_msiof_chipdata sh_data = {
.tx_fifo_size = 64,
.rx_fifo_size = 64,
.master_flags = 0,
.min_div = 1,
};
static const struct sh_msiof_chipdata rcar_gen2_data = {
.tx_fifo_size = 64,
.rx_fifo_size = 64,
.master_flags = SPI_MASTER_MUST_TX,
.min_div = 1,
};
static const struct sh_msiof_chipdata r8a779x_data = {
static const struct sh_msiof_chipdata rcar_gen3_data = {
.tx_fifo_size = 64,
.rx_fifo_size = 64,
.master_flags = SPI_MASTER_MUST_TX,
.min_div = 2,
};
static const struct of_device_id sh_msiof_match[] = {
{ .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,msiof-r8a7790", .data = &rcar_gen2_data },
{ .compatible = "renesas,msiof-r8a7791", .data = &rcar_gen2_data },
{ .compatible = "renesas,msiof-r8a7792", .data = &rcar_gen2_data },
{ .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data },
{ .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data },
{ .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data },
{ .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data },
{ .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data },
{ .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */
{},
};
......@@ -1230,6 +1243,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, p);
p->master = master;
p->info = info;
p->min_div = chipdata->min_div;
init_completion(&p->done);
......
......@@ -446,8 +446,8 @@ static int spi_sh_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "platform_get_irq error\n");
return -ENODEV;
dev_err(&pdev->dev, "platform_get_irq error: %d\n", irq);
return irq;
}
master = spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data));
......
......@@ -1132,7 +1132,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
goto err_master_put;
}
spi->rst = devm_reset_control_get(&pdev->dev, NULL);
spi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (!IS_ERR(spi->rst)) {
reset_control_assert(spi->rst);
udelay(2);
......
......@@ -502,7 +502,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
init_completion(&sspi->done);
sspi->rstc = devm_reset_control_get(&pdev->dev, NULL);
sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(sspi->rstc)) {
dev_err(&pdev->dev, "Couldn't get reset controller\n");
ret = PTR_ERR(sspi->rstc);
......
......@@ -1083,7 +1083,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
goto exit_free_irq;
}
tspi->rst = devm_reset_control_get(&pdev->dev, "spi");
tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst);
......
......@@ -485,7 +485,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
goto exit_free_irq;
}
tsd->rst = devm_reset_control_get(&pdev->dev, "spi");
tsd->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
if (IS_ERR(tsd->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tsd->rst);
......
......@@ -1081,7 +1081,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
goto exit_free_irq;
}
tspi->rst = devm_reset_control_get(&pdev->dev, "spi");
tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst);
......
......@@ -393,8 +393,8 @@ static int xlp_spi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no IRQ resource found\n");
return -EINVAL;
dev_err(&pdev->dev, "no IRQ resource found: %d\n", irq);
return irq;
}
err = devm_request_irq(&pdev->dev, irq, xlp_spi_interrupt, 0,
pdev->name, xspi);
......
......@@ -40,9 +40,13 @@
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <linux/highmem.h>
#include <linux/idr.h>
#define CREATE_TRACE_POINTS
#include <trace/events/spi.h>
#define SPI_DYN_FIRST_BUS_NUM 0
static DEFINE_IDR(spi_master_idr);
static void spidev_release(struct device *dev)
{
......@@ -321,8 +325,7 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
if (rc != -ENODEV)
return rc;
add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);
return 0;
return add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);
}
struct bus_type spi_bus_type = {
......@@ -421,6 +424,7 @@ static LIST_HEAD(spi_controller_list);
/*
* Used to protect add/del opertion for board_info list and
* spi_controller list, and their matching process
* also used to protect object of type struct idr
*/
static DEFINE_MUTEX(board_lock);
......@@ -1533,15 +1537,15 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
int rc;
/* Mode (clock phase/polarity/etc.) */
if (of_find_property(nc, "spi-cpha", NULL))
if (of_property_read_bool(nc, "spi-cpha"))
spi->mode |= SPI_CPHA;
if (of_find_property(nc, "spi-cpol", NULL))
if (of_property_read_bool(nc, "spi-cpol"))
spi->mode |= SPI_CPOL;
if (of_find_property(nc, "spi-cs-high", NULL))
if (of_property_read_bool(nc, "spi-cs-high"))
spi->mode |= SPI_CS_HIGH;
if (of_find_property(nc, "spi-3wire", NULL))
if (of_property_read_bool(nc, "spi-3wire"))
spi->mode |= SPI_3WIRE;
if (of_find_property(nc, "spi-lsb-first", NULL))
if (of_property_read_bool(nc, "spi-lsb-first"))
spi->mode |= SPI_LSB_FIRST;
/* Device DUAL/QUAD mode */
......@@ -1583,8 +1587,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
if (spi_controller_is_slave(ctlr)) {
if (strcmp(nc->name, "slave")) {
dev_err(&ctlr->dev, "%s is not called 'slave'\n",
nc->full_name);
dev_err(&ctlr->dev, "%pOF is not called 'slave'\n",
nc);
return -EINVAL;
}
return 0;
......@@ -1593,8 +1597,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
/* Device address */
rc = of_property_read_u32(nc, "reg", &value);
if (rc) {
dev_err(&ctlr->dev, "%s has no valid 'reg' property (%d)\n",
nc->full_name, rc);
dev_err(&ctlr->dev, "%pOF has no valid 'reg' property (%d)\n",
nc, rc);
return rc;
}
spi->chip_select = value;
......@@ -1603,8 +1607,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
rc = of_property_read_u32(nc, "spi-max-frequency", &value);
if (rc) {
dev_err(&ctlr->dev,
"%s has no valid 'spi-max-frequency' property (%d)\n",
nc->full_name, rc);
"%pOF has no valid 'spi-max-frequency' property (%d)\n", nc, rc);
return rc;
}
spi->max_speed_hz = value;
......@@ -1621,8 +1624,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc)
/* Alloc an spi_device */
spi = spi_alloc_device(ctlr);
if (!spi) {
dev_err(&ctlr->dev, "spi_device alloc error for %s\n",
nc->full_name);
dev_err(&ctlr->dev, "spi_device alloc error for %pOF\n", nc);
rc = -ENOMEM;
goto err_out;
}
......@@ -1631,8 +1633,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc)
rc = of_modalias_node(nc, spi->modalias,
sizeof(spi->modalias));
if (rc < 0) {
dev_err(&ctlr->dev, "cannot find modalias for %s\n",
nc->full_name);
dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc);
goto err_out;
}
......@@ -1647,8 +1648,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc)
/* Register the new device */
rc = spi_add_device(spi);
if (rc) {
dev_err(&ctlr->dev, "spi_device register error %s\n",
nc->full_name);
dev_err(&ctlr->dev, "spi_device register error %pOF\n", nc);
goto err_of_node_put;
}
......@@ -1682,8 +1682,7 @@ static void of_register_spi_devices(struct spi_controller *ctlr)
spi = of_register_spi_device(ctlr, nc);
if (IS_ERR(spi)) {
dev_warn(&ctlr->dev,
"Failed to create SPI device for %s\n",
nc->full_name);
"Failed to create SPI device for %pOF\n", nc);
of_node_clear_flag(nc, OF_POPULATED);
}
}
......@@ -2052,11 +2051,10 @@ static int of_spi_register_master(struct spi_controller *ctlr)
*/
int spi_register_controller(struct spi_controller *ctlr)
{
static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
struct device *dev = ctlr->dev.parent;
struct boardinfo *bi;
int status = -ENODEV;
int dynamic = 0;
int id;
if (!dev)
return -ENODEV;
......@@ -2072,19 +2070,28 @@ int spi_register_controller(struct spi_controller *ctlr)
*/
if (ctlr->num_chipselect == 0)
return -EINVAL;
if ((ctlr->bus_num < 0) && ctlr->dev.of_node)
ctlr->bus_num = of_alias_get_id(ctlr->dev.of_node, "spi");
/* convention: dynamically assigned bus IDs count down from the max */
/* allocate dynamic bus number using Linux idr */
if ((ctlr->bus_num < 0) && ctlr->dev.of_node) {
id = of_alias_get_id(ctlr->dev.of_node, "spi");
if (id >= 0) {
ctlr->bus_num = id;
mutex_lock(&board_lock);
id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num,
ctlr->bus_num + 1, GFP_KERNEL);
mutex_unlock(&board_lock);
if (WARN(id < 0, "couldn't get idr"))
return id == -ENOSPC ? -EBUSY : id;
}
}
if (ctlr->bus_num < 0) {
/* FIXME switch to an IDR based scheme, something like
* I2C now uses, so we can't run out of "dynamic" IDs
*/
ctlr->bus_num = atomic_dec_return(&dyn_bus_id);
dynamic = 1;
mutex_lock(&board_lock);
id = idr_alloc(&spi_master_idr, ctlr, SPI_DYN_FIRST_BUS_NUM, 0,
GFP_KERNEL);
mutex_unlock(&board_lock);
if (WARN(id < 0, "couldn't get idr"))
return id;
ctlr->bus_num = id;
}
INIT_LIST_HEAD(&ctlr->queue);
spin_lock_init(&ctlr->queue_lock);
spin_lock_init(&ctlr->bus_lock_spinlock);
......@@ -2100,11 +2107,16 @@ int spi_register_controller(struct spi_controller *ctlr)
*/
dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num);
status = device_add(&ctlr->dev);
if (status < 0)
if (status < 0) {
/* free bus id */
mutex_lock(&board_lock);
idr_remove(&spi_master_idr, ctlr->bus_num);
mutex_unlock(&board_lock);
goto done;
dev_dbg(dev, "registered %s %s%s\n",
}
dev_dbg(dev, "registered %s %s\n",
spi_controller_is_slave(ctlr) ? "slave" : "master",
dev_name(&ctlr->dev), dynamic ? " (dynamic)" : "");
dev_name(&ctlr->dev));
/* If we're using a queued driver, start the queue */
if (ctlr->transfer)
......@@ -2113,6 +2125,10 @@ int spi_register_controller(struct spi_controller *ctlr)
status = spi_controller_initialize_queue(ctlr);
if (status) {
device_del(&ctlr->dev);
/* free bus id */
mutex_lock(&board_lock);
idr_remove(&spi_master_idr, ctlr->bus_num);
mutex_unlock(&board_lock);
goto done;
}
}
......@@ -2191,19 +2207,33 @@ static int __unregister(struct device *dev, void *null)
*/
void spi_unregister_controller(struct spi_controller *ctlr)
{
struct spi_controller *found;
int dummy;
/* First make sure that this controller was ever added */
mutex_lock(&board_lock);
found = idr_find(&spi_master_idr, ctlr->bus_num);
mutex_unlock(&board_lock);
if (found != ctlr) {
dev_dbg(&ctlr->dev,
"attempting to delete unregistered controller [%s]\n",
dev_name(&ctlr->dev));
return;
}
if (ctlr->queued) {
if (spi_destroy_queue(ctlr))
dev_err(&ctlr->dev, "queue remove failed\n");
}
mutex_lock(&board_lock);
list_del(&ctlr->list);
mutex_unlock(&board_lock);
dummy = device_for_each_child(&ctlr->dev, NULL, __unregister);
device_unregister(&ctlr->dev);
/* free bus id */
mutex_lock(&board_lock);
idr_remove(&spi_master_idr, ctlr->bus_num);
mutex_unlock(&board_lock);
}
EXPORT_SYMBOL_GPL(spi_unregister_controller);
......@@ -3311,8 +3341,8 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action,
put_device(&ctlr->dev);
if (IS_ERR(spi)) {
pr_err("%s: failed to create for '%s'\n",
__func__, rd->dn->full_name);
pr_err("%s: failed to create for '%pOF'\n",
__func__, rd->dn);
of_node_clear_flag(rd->dn, OF_POPULATED);
return notifier_from_errno(PTR_ERR(spi));
}
......
......@@ -90,7 +90,7 @@ kvm_stat: FORCE
$(call descend,kvm/$@)
all: acpi cgroup cpupower gpio hv firewire liblockdep \
perf selftests turbostat usb \
perf selftests spi turbostat usb \
virtio vm net x86_energy_perf_policy \
tmon freefall iio objtool kvm_stat
......@@ -100,7 +100,7 @@ acpi_install:
cpupower_install:
$(call descend,power/$(@:_install=),install)
cgroup_install firewire_install gpio_install hv_install iio_install perf_install usb_install virtio_install vm_install net_install objtool_install:
cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install net_install objtool_install:
$(call descend,$(@:_install=),install)
liblockdep_install:
......
spidev_test-y += spidev_test.o
spidev_fdx-y += spidev_fdx.o
include ../scripts/Makefile.include
bindir ?= /usr/bin
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
# Do not use make's built-in rules
# (this improves performance and avoids hard-to-debug behaviour);
MAKEFLAGS += -r
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
ALL_TARGETS := spidev_test spidev_fdx
ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
all: $(ALL_PROGRAMS)
export srctree OUTPUT CC LD CFLAGS
include $(srctree)/tools/build/Makefile.include
all: spidev_test spidev_fdx
#
# We need the following to be outside of kernel tree
#
$(OUTPUT)include/linux/spi/spidev.h: ../../include/uapi/linux/spi/spidev.h
mkdir -p $(OUTPUT)include/linux/spi 2>&1 || true
ln -sf $(CURDIR)/../../include/uapi/linux/spi/spidev.h $@
prepare: $(OUTPUT)include/linux/spi/spidev.h
#
# spidev_test
#
SPIDEV_TEST_IN := $(OUTPUT)spidev_test-in.o
$(SPIDEV_TEST_IN): prepare FORCE
$(Q)$(MAKE) $(build)=spidev_test
$(OUTPUT)spidev_test: $(SPIDEV_TEST_IN)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
#
# spidev_fdx
#
SPIDEV_FDX_IN := $(OUTPUT)spidev_fdx-in.o
$(SPIDEV_FDX_IN): prepare FORCE
$(Q)$(MAKE) $(build)=spidev_fdx
$(OUTPUT)spidev_fdx: $(SPIDEV_FDX_IN)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
clean:
$(RM) spidev_test spidev_fdx
rm -f $(ALL_PROGRAMS)
rm -f $(OUTPUT)include/linux/spi/spidev.h
find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
install: $(ALL_PROGRAMS)
install -d -m 755 $(DESTDIR)$(bindir); \
for program in $(ALL_PROGRAMS); do \
install $$program $(DESTDIR)$(bindir); \
done
FORCE:
.PHONY: all install clean FORCE prepare
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