spi: Fixes for v3.17

A few driver specific fixes for v3.17:
 
  - Fix davinci so that GPIO chip selects work with deferred probe of
    GPIOs (which could happen in production depending on kernel config)
    plus one incremental stylistic fix to that.
  - Several fixes for the newly introduced rockchip driver that came up
    in wider testing of the device.
  - A couple of small things in the sirf driver, one bug that would stop
    DMA transfers working and another update to follow the documented
    procedure in the datasheet.
  - Fix some memory leaks with devm_kzalloc() being used outside of the
    device bind path.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJUGMflAAoJECTWi3JdVIfQaJoH/1Zvl0/WrxIaNLIhI0SeyiTc
 Wtma9R5/N5Dx9tWp1X6XSZJbWLP/H9VN2YUd2eeZTAn48rlYLf6wgz6pqa8xmVUd
 y1+pYukRxlOFSIfKWaCpTvgqDQx09VnWPNlm+E/vKVj/ba1jvkxdhRoc9ROwcfuj
 DBtJ/kRcmJrEbMEQD60ZbJEHrqTmhNLWwpnoTLQ+2DRsBKyzo6YCgYlcAlcA0siK
 tu1zGsQr28jl0DjYJTl+TwjSWhzcFichFr2NuxC1k8b8xhLonRYxiR9Uxyb8gJQ4
 mtBvOrcZ0GPdCYFG9Fkr62dphxL5thh5ZrSTpUCh5y/ep8l7iZgiv0/CmyYFOHg=
 =hxe+
 -----END PGP SIGNATURE-----

Merge tag 'spi-v3.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A few driver specific fixes for v3.17:

   - Fix davinci so that GPIO chip selects work with deferred probe of
     GPIOs (which could happen in production depending on kernel config)
     plus one incremental stylistic fix to that.
   - Several fixes for the newly introduced rockchip driver that came up
     in wider testing of the device.
   - A couple of small things in the sirf driver, one bug that would
     stop DMA transfers working and another update to follow the
     documented procedure in the datasheet.
   - Fix some memory leaks with devm_kzalloc() being used outside of the
     device bind path"

* tag 'spi-v3.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: davinci: remove empty function davinci_spi_cleanup
  spi: davinci: request cs_gpio's from probe
  spi/pl022: Fix error message
  spi/rockchip: Mark DMA as optional
  spi/rockchip: Don't warn if SPI is busy but disabled
  spi/rockchip: Fix the wait_for_idle() timeout
  spi: sirf: add fifo reset/start for cmd transfer
  spi: sirf: enable RX_IO_DMA_INT interrupt
  spi: dw: Don't use devm_kzalloc in master->setup callback
  spi: fsl: Don't use devm_kzalloc in master->setup callback
This commit is contained in:
Linus Torvalds 2014-09-18 10:33:46 -07:00
commit 27180f7de7
8 changed files with 68 additions and 28 deletions

View File

@ -16,11 +16,15 @@ Required Properties:
- clocks: Must contain an entry for each entry in clock-names. - clocks: Must contain an entry for each entry in clock-names.
- clock-names: Shall be "spiclk" for the transfer-clock, and "apb_pclk" for - clock-names: Shall be "spiclk" for the transfer-clock, and "apb_pclk" for
the peripheral clock. the peripheral clock.
- #address-cells: should be 1.
- #size-cells: should be 0.
Optional Properties:
- dmas: DMA specifiers for tx and rx dma. See the DMA client binding, - dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt Documentation/devicetree/bindings/dma/dma.txt
- dma-names: DMA request names should include "tx" and "rx" if present. - dma-names: DMA request names should include "tx" and "rx" if present.
- #address-cells: should be 1.
- #size-cells: should be 0.
Example: Example:

View File

@ -397,24 +397,21 @@ static int davinci_spi_setup(struct spi_device *spi)
struct spi_master *master = spi->master; struct spi_master *master = spi->master;
struct device_node *np = spi->dev.of_node; struct device_node *np = spi->dev.of_node;
bool internal_cs = true; bool internal_cs = true;
unsigned long flags = GPIOF_DIR_OUT;
dspi = spi_master_get_devdata(spi->master); dspi = spi_master_get_devdata(spi->master);
pdata = &dspi->pdata; pdata = &dspi->pdata;
flags |= (spi->mode & SPI_CS_HIGH) ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH;
if (!(spi->mode & SPI_NO_CS)) { if (!(spi->mode & SPI_NO_CS)) {
if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) { if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) {
retval = gpio_request_one(spi->cs_gpio, retval = gpio_direction_output(
flags, dev_name(&spi->dev)); spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
internal_cs = false; internal_cs = false;
} else if (pdata->chip_sel && } else if (pdata->chip_sel &&
spi->chip_select < pdata->num_chipselect && spi->chip_select < pdata->num_chipselect &&
pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) { pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) {
spi->cs_gpio = pdata->chip_sel[spi->chip_select]; spi->cs_gpio = pdata->chip_sel[spi->chip_select];
retval = gpio_request_one(spi->cs_gpio, retval = gpio_direction_output(
flags, dev_name(&spi->dev)); spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
internal_cs = false; internal_cs = false;
} }
@ -439,12 +436,6 @@ static int davinci_spi_setup(struct spi_device *spi)
return retval; return retval;
} }
static void davinci_spi_cleanup(struct spi_device *spi)
{
if (spi->cs_gpio >= 0)
gpio_free(spi->cs_gpio);
}
static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
{ {
struct device *sdev = dspi->bitbang.master->dev.parent; struct device *sdev = dspi->bitbang.master->dev.parent;
@ -956,7 +947,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
master->num_chipselect = pdata->num_chipselect; master->num_chipselect = pdata->num_chipselect;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
master->setup = davinci_spi_setup; master->setup = davinci_spi_setup;
master->cleanup = davinci_spi_cleanup;
dspi->bitbang.chipselect = davinci_spi_chipselect; dspi->bitbang.chipselect = davinci_spi_chipselect;
dspi->bitbang.setup_transfer = davinci_spi_setup_transfer; dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;
@ -967,6 +957,27 @@ static int davinci_spi_probe(struct platform_device *pdev)
if (dspi->version == SPI_VERSION_2) if (dspi->version == SPI_VERSION_2)
dspi->bitbang.flags |= SPI_READY; dspi->bitbang.flags |= SPI_READY;
if (pdev->dev.of_node) {
int i;
for (i = 0; i < pdata->num_chipselect; i++) {
int cs_gpio = of_get_named_gpio(pdev->dev.of_node,
"cs-gpios", i);
if (cs_gpio == -EPROBE_DEFER) {
ret = cs_gpio;
goto free_clk;
}
if (gpio_is_valid(cs_gpio)) {
ret = devm_gpio_request(&pdev->dev, cs_gpio,
dev_name(&pdev->dev));
if (ret)
goto free_clk;
}
}
}
r = platform_get_resource(pdev, IORESOURCE_DMA, 0); r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (r) if (r)
dma_rx_chan = r->start; dma_rx_chan = r->start;

View File

@ -547,8 +547,7 @@ static int dw_spi_setup(struct spi_device *spi)
/* Only alloc on first setup */ /* Only alloc on first setup */
chip = spi_get_ctldata(spi); chip = spi_get_ctldata(spi);
if (!chip) { if (!chip) {
chip = devm_kzalloc(&spi->dev, sizeof(struct chip_data), chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
GFP_KERNEL);
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
spi_set_ctldata(spi, chip); spi_set_ctldata(spi, chip);
@ -606,6 +605,14 @@ static int dw_spi_setup(struct spi_device *spi)
return 0; return 0;
} }
static void dw_spi_cleanup(struct spi_device *spi)
{
struct chip_data *chip = spi_get_ctldata(spi);
kfree(chip);
spi_set_ctldata(spi, NULL);
}
/* Restart the controller, disable all interrupts, clean rx fifo */ /* Restart the controller, disable all interrupts, clean rx fifo */
static void spi_hw_init(struct dw_spi *dws) static void spi_hw_init(struct dw_spi *dws)
{ {
@ -661,6 +668,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
master->bus_num = dws->bus_num; master->bus_num = dws->bus_num;
master->num_chipselect = dws->num_cs; master->num_chipselect = dws->num_cs;
master->setup = dw_spi_setup; master->setup = dw_spi_setup;
master->cleanup = dw_spi_cleanup;
master->transfer_one_message = dw_spi_transfer_one_message; master->transfer_one_message = dw_spi_transfer_one_message;
master->max_speed_hz = dws->max_freq; master->max_speed_hz = dws->max_freq;

View File

@ -452,16 +452,16 @@ static int fsl_espi_setup(struct spi_device *spi)
int retval; int retval;
u32 hw_mode; u32 hw_mode;
u32 loop_mode; u32 loop_mode;
struct spi_mpc8xxx_cs *cs = spi->controller_state; struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi);
if (!spi->max_speed_hz) if (!spi->max_speed_hz)
return -EINVAL; return -EINVAL;
if (!cs) { if (!cs) {
cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL); cs = kzalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) if (!cs)
return -ENOMEM; return -ENOMEM;
spi->controller_state = cs; spi_set_ctldata(spi, cs);
} }
mpc8xxx_spi = spi_master_get_devdata(spi->master); mpc8xxx_spi = spi_master_get_devdata(spi->master);
@ -496,6 +496,14 @@ static int fsl_espi_setup(struct spi_device *spi)
return 0; return 0;
} }
static void fsl_espi_cleanup(struct spi_device *spi)
{
struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi);
kfree(cs);
spi_set_ctldata(spi, NULL);
}
void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
{ {
struct fsl_espi_reg *reg_base = mspi->reg_base; struct fsl_espi_reg *reg_base = mspi->reg_base;
@ -605,6 +613,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
master->setup = fsl_espi_setup; master->setup = fsl_espi_setup;
master->cleanup = fsl_espi_cleanup;
mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi->spi_do_one_msg = fsl_espi_do_one_msg; mpc8xxx_spi->spi_do_one_msg = fsl_espi_do_one_msg;

View File

@ -425,16 +425,16 @@ static int fsl_spi_setup(struct spi_device *spi)
struct fsl_spi_reg *reg_base; struct fsl_spi_reg *reg_base;
int retval; int retval;
u32 hw_mode; u32 hw_mode;
struct spi_mpc8xxx_cs *cs = spi->controller_state; struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi);
if (!spi->max_speed_hz) if (!spi->max_speed_hz)
return -EINVAL; return -EINVAL;
if (!cs) { if (!cs) {
cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL); cs = kzalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) if (!cs)
return -ENOMEM; return -ENOMEM;
spi->controller_state = cs; spi_set_ctldata(spi, cs);
} }
mpc8xxx_spi = spi_master_get_devdata(spi->master); mpc8xxx_spi = spi_master_get_devdata(spi->master);
@ -496,9 +496,13 @@ static int fsl_spi_setup(struct spi_device *spi)
static void fsl_spi_cleanup(struct spi_device *spi) static void fsl_spi_cleanup(struct spi_device *spi)
{ {
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi);
if (mpc8xxx_spi->type == TYPE_GRLIB && gpio_is_valid(spi->cs_gpio)) if (mpc8xxx_spi->type == TYPE_GRLIB && gpio_is_valid(spi->cs_gpio))
gpio_free(spi->cs_gpio); gpio_free(spi->cs_gpio);
kfree(cs);
spi_set_ctldata(spi, NULL);
} }
static void fsl_spi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) static void fsl_spi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)

View File

@ -2136,7 +2136,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
cs_gpio); cs_gpio);
else if (gpio_direction_output(cs_gpio, 1)) else if (gpio_direction_output(cs_gpio, 1))
dev_err(&adev->dev, dev_err(&adev->dev,
"could set gpio %d as output\n", "could not set gpio %d as output\n",
cs_gpio); cs_gpio);
} }
} }

View File

@ -220,7 +220,7 @@ static inline void wait_for_idle(struct rockchip_spi *rs)
do { do {
if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)) if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
return; return;
} while (time_before(jiffies, timeout)); } while (!time_after(jiffies, timeout));
dev_warn(rs->dev, "spi controller is in busy state!\n"); dev_warn(rs->dev, "spi controller is in busy state!\n");
} }
@ -529,7 +529,8 @@ static int rockchip_spi_transfer_one(
int ret = 0; int ret = 0;
struct rockchip_spi *rs = spi_master_get_devdata(master); struct rockchip_spi *rs = spi_master_get_devdata(master);
WARN_ON((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)); WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));
if (!xfer->tx_buf && !xfer->rx_buf) { if (!xfer->tx_buf && !xfer->rx_buf) {
dev_err(rs->dev, "No buffer for transfer\n"); dev_err(rs->dev, "No buffer for transfer\n");

View File

@ -312,6 +312,8 @@ static int spi_sirfsoc_cmd_transfer(struct spi_device *spi,
u32 cmd; u32 cmd;
sspi = spi_master_get_devdata(spi->master); sspi = spi_master_get_devdata(spi->master);
writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
memcpy(&cmd, sspi->tx, t->len); memcpy(&cmd, sspi->tx, t->len);
if (sspi->word_width == 1 && !(spi->mode & SPI_LSB_FIRST)) if (sspi->word_width == 1 && !(spi->mode & SPI_LSB_FIRST))
cmd = cpu_to_be32(cmd) >> cmd = cpu_to_be32(cmd) >>
@ -438,7 +440,8 @@ static void spi_sirfsoc_pio_transfer(struct spi_device *spi,
sspi->tx_word(sspi); sspi->tx_word(sspi);
writel(SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN | writel(SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN |
SIRFSOC_SPI_TX_UFLOW_INT_EN | SIRFSOC_SPI_TX_UFLOW_INT_EN |
SIRFSOC_SPI_RX_OFLOW_INT_EN, SIRFSOC_SPI_RX_OFLOW_INT_EN |
SIRFSOC_SPI_RX_IO_DMA_INT_EN,
sspi->base + SIRFSOC_SPI_INT_EN); sspi->base + SIRFSOC_SPI_INT_EN);
writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN, writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN,
sspi->base + SIRFSOC_SPI_TX_RX_EN); sspi->base + SIRFSOC_SPI_TX_RX_EN);