Commit 24b414d5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull spi fixes from Mark Brown:
 "A few driver specific fixes, the biggest one being a fix for the newly
  added Qualcomm SPI controller driver to make it not use its internal
  chip select due to hardware bugs, replacing it with GPIOs"

* tag 'spi-v3.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: qup: Remove chip select function
  spi: qup: Fix order of spi_register_master
  spi: sh-sci: fix use-after-free in sh_sci_spi_remove()
  spi/pxa2xx: fix incorrect SW mode chipselect setting for BayTrail LPSS SPI
parents 4194976b 7216a418
...@@ -23,6 +23,12 @@ Optional properties: ...@@ -23,6 +23,12 @@ Optional properties:
- spi-max-frequency: Specifies maximum SPI clock frequency, - spi-max-frequency: Specifies maximum SPI clock frequency,
Units - Hz. Definition as per Units - Hz. Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt Documentation/devicetree/bindings/spi/spi-bus.txt
- num-cs: total number of chipselects
- cs-gpios: should specify GPIOs used for chipselects.
The gpios will be referred to as reg = <index> in the SPI child
nodes. If unspecified, a single SPI device without a chip
select can be used.
SPI slave nodes must be children of the SPI master node and can contain SPI slave nodes must be children of the SPI master node and can contain
properties described in Documentation/devicetree/bindings/spi/spi-bus.txt properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
......
...@@ -118,6 +118,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data) ...@@ -118,6 +118,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
*/ */
orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
/* Test SPI_CS_CONTROL_SW_MODE bit enabling */
value = orig | SPI_CS_CONTROL_SW_MODE; value = orig | SPI_CS_CONTROL_SW_MODE;
writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
...@@ -126,10 +127,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data) ...@@ -126,10 +127,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
goto detection_done; goto detection_done;
} }
value &= ~SPI_CS_CONTROL_SW_MODE; orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
/* Test SPI_CS_CONTROL_SW_MODE bit disabling */
value = orig & ~SPI_CS_CONTROL_SW_MODE;
writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
if (value != orig) { if (value != (orig & ~SPI_CS_CONTROL_SW_MODE)) {
offset = 0x800; offset = 0x800;
goto detection_done; goto detection_done;
} }
......
...@@ -424,31 +424,6 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) ...@@ -424,31 +424,6 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
return 0; return 0;
} }
static void spi_qup_set_cs(struct spi_device *spi, bool enable)
{
struct spi_qup *controller = spi_master_get_devdata(spi->master);
u32 iocontol, mask;
iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
/* Disable auto CS toggle and use manual */
iocontol &= ~SPI_IO_C_MX_CS_MODE;
iocontol |= SPI_IO_C_FORCE_CS;
iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
if (enable)
iocontol |= mask;
else
iocontol &= ~mask;
writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
}
static int spi_qup_transfer_one(struct spi_master *master, static int spi_qup_transfer_one(struct spi_master *master,
struct spi_device *spi, struct spi_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
...@@ -571,12 +546,16 @@ static int spi_qup_probe(struct platform_device *pdev) ...@@ -571,12 +546,16 @@ static int spi_qup_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
/* use num-cs unless not present or out of range */
if (of_property_read_u16(dev->of_node, "num-cs",
&master->num_chipselect) ||
(master->num_chipselect > SPI_NUM_CHIPSELECTS))
master->num_chipselect = SPI_NUM_CHIPSELECTS;
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
master->num_chipselect = SPI_NUM_CHIPSELECTS;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
master->max_speed_hz = max_freq; master->max_speed_hz = max_freq;
master->set_cs = spi_qup_set_cs;
master->transfer_one = spi_qup_transfer_one; master->transfer_one = spi_qup_transfer_one;
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
master->auto_runtime_pm = true; master->auto_runtime_pm = true;
...@@ -640,16 +619,19 @@ static int spi_qup_probe(struct platform_device *pdev) ...@@ -640,16 +619,19 @@ static int spi_qup_probe(struct platform_device *pdev)
if (ret) if (ret)
goto error; goto error;
ret = devm_spi_register_master(dev, master);
if (ret)
goto error;
pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
pm_runtime_use_autosuspend(dev); pm_runtime_use_autosuspend(dev);
pm_runtime_set_active(dev); pm_runtime_set_active(dev);
pm_runtime_enable(dev); pm_runtime_enable(dev);
ret = devm_spi_register_master(dev, master);
if (ret)
goto disable_pm;
return 0; return 0;
disable_pm:
pm_runtime_disable(&pdev->dev);
error: error:
clk_disable_unprepare(cclk); clk_disable_unprepare(cclk);
clk_disable_unprepare(iclk); clk_disable_unprepare(iclk);
......
...@@ -175,9 +175,9 @@ static int sh_sci_spi_remove(struct platform_device *dev) ...@@ -175,9 +175,9 @@ static int sh_sci_spi_remove(struct platform_device *dev)
{ {
struct sh_sci_spi *sp = platform_get_drvdata(dev); struct sh_sci_spi *sp = platform_get_drvdata(dev);
iounmap(sp->membase);
setbits(sp, PIN_INIT, 0);
spi_bitbang_stop(&sp->bitbang); spi_bitbang_stop(&sp->bitbang);
setbits(sp, PIN_INIT, 0);
iounmap(sp->membase);
spi_master_put(sp->bitbang.master); spi_master_put(sp->bitbang.master);
return 0; return 0;
} }
......
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