Commit 5d3fed70 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull spi updates from Mark Brown:
 "Business as usual for SPI - some new drivers, lots of fixes and
  updates to existing drivers plus some new framework features.  Notable
  changes are:

   - Support for dual and quad data lines, commonly used by flash chips
     to improve performance, from Wang Yuhang.
   - Factored out a common pattern for runtime PM implementation into
     the core saving a bunch of code.
   - A particularly nice set of updates to the ep93xx driver from
     H Hartley Sweeten, modernising it and reducing the code size a lot.
   - New drivers for Blackfin v3, EFM32, Freescale DSPI and TI QSPI"

* tag 'spi-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (133 commits)
  spi/qspi: fix missing unlock on error in ti_qspi_start_transfer_one()
  spi: quad: fix the name of DT property
  spi: core: Fix spi_register_master error handling
  spi: efm32: Fix build error
  spi: altera: Use DIV_ROUND_UP to calculate hw->bytes_per_word
  spi: rspi: Add spi_master_get() call to prevent use after free
  spi: quad: Make DT properties optional
  spi: quad: Fix missing return
  spi: Use dev_get_drvdata at appropriate places
  spi: use dev_get_platdata()
  spi: nuc900: Fix mode_bits setting
  spi: simplify devm_request_mem_region/devm_ioremap
  spi: altera: Simplify altera_spi_txrx implementation for noirq case
  spi: spi-rspi: fix inconsistent spin_lock_irqsave
  spi/qspi: Add compatible string for am4372.
  spi/qspi: Fix device table entry
  spi/sirf: fix the misunderstanding about len of spi_transfer
  spi/qspi: Add dual/quad spi read support
  spi: sirf: fix error return code in spi_sirfsoc_probe()
  spi: bcm2835: Add spi_master_get() call to prevent use after free
  ...
parents 8243b7f5 57873925
* Energy Micro EFM32 SPI
Required properties:
- #address-cells: see spi-bus.txt
- #size-cells: see spi-bus.txt
- compatible: should be "efm32,spi"
- reg: Offset and length of the register set for the controller
- interrupts: pair specifying rx and tx irq
- clocks: phandle to the spi clock
- cs-gpios: see spi-bus.txt
- location: Value to write to the ROUTE register's LOCATION bitfield to configure the pinmux for the device, see datasheet for values.
Example:
spi1: spi@0x4000c400 { /* USART1 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "efm32,spi";
reg = <0x4000c400 0x400>;
interrupts = <15 16>;
clocks = <&cmu 20>;
cs-gpios = <&gpio 51 1>; // D3
location = <1>;
status = "ok";
ks8851@0 {
compatible = "ks8851";
spi-max-frequency = <6000000>;
reg = <0>;
interrupt-parent = <&boardfpga>;
interrupts = <4>;
status = "ok";
};
};
...@@ -55,6 +55,16 @@ contain the following properties. ...@@ -55,6 +55,16 @@ contain the following properties.
chip select active high chip select active high
- spi-3wire - (optional) Empty property indicating device requires - spi-3wire - (optional) Empty property indicating device requires
3-wire mode. 3-wire mode.
- spi-tx-bus-width - (optional) The bus width(number of data wires) that
used for MOSI. Defaults to 1 if not present.
- spi-rx-bus-width - (optional) The bus width(number of data wires) that
used for MISO. Defaults to 1 if not present.
Some SPI controllers and devices support Dual and Quad SPI transfer mode.
It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is
only 1(SINGLE), 2(DUAL) and 4(QUAD).
Dual/Quad mode is not allowed when 3-wire mode is used.
If a gpio chipselect is used for the SPI slave the gpio number will be passed If a gpio chipselect is used for the SPI slave the gpio number will be passed
via the cs_gpio via the cs_gpio
......
ARM Freescale DSPI controller
Required properties:
- compatible : "fsl,vf610-dspi"
- reg : Offset and length of the register set for the device
- interrupts : Should contain SPI controller interrupt
- clocks: from common clock binding: handle to dspi clock.
- clock-names: from common clock binding: Shall be "dspi".
- pinctrl-0: pin control group to be used for this controller.
- pinctrl-names: must contain a "default" entry.
- spi-num-chipselects : the number of the chipselect signals.
- bus-num : the slave chip chipselect signal number.
Example:
dspi0@4002c000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,vf610-dspi";
reg = <0x4002c000 0x1000>;
interrupts = <0 67 0x04>;
clocks = <&clks VF610_CLK_DSPI0>;
clock-names = "dspi";
spi-num-chipselects = <5>;
bus-num = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dspi0_1>;
status = "okay";
sflash: at26df081a@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "atmel,at26df081a";
spi-max-frequency = <16000000>;
spi-cpol;
spi-cpha;
reg = <0>;
linux,modalias = "m25p80";
modal = "at26df081a";
};
};
TI QSPI controller.
Required properties:
- compatible : should be "ti,dra7xxx-qspi" or "ti,am4372-qspi".
- reg: Should contain QSPI registers location and length.
- #address-cells, #size-cells : Must be present if the device has sub-nodes
- ti,hwmods: Name of the hwmod associated to the QSPI
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
qspi: qspi@4b300000 {
compatible = "ti,dra7xxx-qspi";
reg = <0x4b300000 0x100>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <25000000>;
ti,hwmods = "qspi";
};
...@@ -215,7 +215,7 @@ So for example arch/.../mach-*/board-*.c files might have code like: ...@@ -215,7 +215,7 @@ So for example arch/.../mach-*/board-*.c files might have code like:
/* if your mach-* infrastructure doesn't support kernels that can /* if your mach-* infrastructure doesn't support kernels that can
* run on multiple boards, pdata wouldn't benefit from "__init". * run on multiple boards, pdata wouldn't benefit from "__init".
*/ */
static struct mysoc_spi_data __initdata pdata = { ... }; static struct mysoc_spi_data pdata __initdata = { ... };
static __init board_init(void) static __init board_init(void)
{ {
......
...@@ -70,14 +70,14 @@ config SPI_ATH79 ...@@ -70,14 +70,14 @@ config SPI_ATH79
config SPI_ATMEL config SPI_ATMEL
tristate "Atmel SPI Controller" tristate "Atmel SPI Controller"
depends on (ARCH_AT91 || AVR32) depends on (ARCH_AT91 || AVR32 || COMPILE_TEST)
help help
This selects a driver for the Atmel SPI Controller, present on This selects a driver for the Atmel SPI Controller, present on
many AT32 (AVR32) and AT91 (ARM) chips. many AT32 (AVR32) and AT91 (ARM) chips.
config SPI_BCM2835 config SPI_BCM2835
tristate "BCM2835 SPI controller" tristate "BCM2835 SPI controller"
depends on ARCH_BCM2835 depends on ARCH_BCM2835 || COMPILE_TEST
help help
This selects a driver for the Broadcom BCM2835 SPI master. This selects a driver for the Broadcom BCM2835 SPI master.
...@@ -88,10 +88,17 @@ config SPI_BCM2835 ...@@ -88,10 +88,17 @@ config SPI_BCM2835
config SPI_BFIN5XX config SPI_BFIN5XX
tristate "SPI controller driver for ADI Blackfin5xx" tristate "SPI controller driver for ADI Blackfin5xx"
depends on BLACKFIN depends on BLACKFIN && !BF60x
help help
This is the SPI controller master driver for Blackfin 5xx processor. This is the SPI controller master driver for Blackfin 5xx processor.
config SPI_BFIN_V3
tristate "SPI controller v3 for Blackfin"
depends on BF60x
help
This is the SPI controller v3 master driver
found on Blackfin 60x processor.
config SPI_BFIN_SPORT config SPI_BFIN_SPORT
tristate "SPI bus via Blackfin SPORT" tristate "SPI bus via Blackfin SPORT"
depends on BLACKFIN depends on BLACKFIN
...@@ -151,15 +158,22 @@ config SPI_COLDFIRE_QSPI ...@@ -151,15 +158,22 @@ config SPI_COLDFIRE_QSPI
config SPI_DAVINCI config SPI_DAVINCI
tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller" tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"
depends on ARCH_DAVINCI depends on ARCH_DAVINCI || ARCH_KEYSTONE
select SPI_BITBANG select SPI_BITBANG
select TI_EDMA select TI_EDMA
help help
SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules. SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
config SPI_EFM32
tristate "EFM32 SPI controller"
depends on OF && ARM && (ARCH_EFM32 || COMPILE_TEST)
select SPI_BITBANG
help
Driver for the spi controller found on Energy Micro's EFM32 SoCs.
config SPI_EP93XX config SPI_EP93XX
tristate "Cirrus Logic EP93xx SPI controller" tristate "Cirrus Logic EP93xx SPI controller"
depends on ARCH_EP93XX depends on ARCH_EP93XX || COMPILE_TEST
help help
This enables using the Cirrus EP93xx SPI controller in master This enables using the Cirrus EP93xx SPI controller in master
mode. mode.
...@@ -191,7 +205,7 @@ config SPI_GPIO ...@@ -191,7 +205,7 @@ config SPI_GPIO
config SPI_IMX config SPI_IMX
tristate "Freescale i.MX SPI controllers" tristate "Freescale i.MX SPI controllers"
depends on ARCH_MXC depends on ARCH_MXC || COMPILE_TEST
select SPI_BITBANG select SPI_BITBANG
default m if IMX_HAVE_PLATFORM_SPI_IMX default m if IMX_HAVE_PLATFORM_SPI_IMX
help help
...@@ -248,6 +262,13 @@ config SPI_FSL_SPI ...@@ -248,6 +262,13 @@ config SPI_FSL_SPI
This also enables using the Aeroflex Gaisler GRLIB SPI controller in This also enables using the Aeroflex Gaisler GRLIB SPI controller in
master mode. master mode.
config SPI_FSL_DSPI
tristate "Freescale DSPI controller"
select SPI_BITBANG
help
This enables support for the Freescale DSPI controller in master
mode. VF610 platform uses the controller.
config SPI_FSL_ESPI config SPI_FSL_ESPI
bool "Freescale eSPI controller" bool "Freescale eSPI controller"
depends on FSL_SOC depends on FSL_SOC
...@@ -280,20 +301,28 @@ config SPI_OMAP_UWIRE ...@@ -280,20 +301,28 @@ config SPI_OMAP_UWIRE
config SPI_OMAP24XX config SPI_OMAP24XX
tristate "McSPI driver for OMAP" tristate "McSPI driver for OMAP"
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS || COMPILE_TEST
help help
SPI master controller for OMAP24XX and later Multichannel SPI SPI master controller for OMAP24XX and later Multichannel SPI
(McSPI) modules. (McSPI) modules.
config SPI_TI_QSPI
tristate "DRA7xxx QSPI controller support"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
help
QSPI master controller for DRA7xxx used for flash devices.
This device supports single, dual and quad read support, while
it only supports single write mode.
config SPI_OMAP_100K config SPI_OMAP_100K
tristate "OMAP SPI 100K" tristate "OMAP SPI 100K"
depends on ARCH_OMAP850 || ARCH_OMAP730 depends on ARCH_OMAP850 || ARCH_OMAP730 || COMPILE_TEST
help help
OMAP SPI 100K master controller for omap7xx boards. OMAP SPI 100K master controller for omap7xx boards.
config SPI_ORION config SPI_ORION
tristate "Orion SPI master" tristate "Orion SPI master"
depends on PLAT_ORION depends on PLAT_ORION || COMPILE_TEST
help help
This enables using the SPI master controller on the Orion chips. This enables using the SPI master controller on the Orion chips.
...@@ -341,7 +370,7 @@ config SPI_PXA2XX_PCI ...@@ -341,7 +370,7 @@ config SPI_PXA2XX_PCI
config SPI_RSPI config SPI_RSPI
tristate "Renesas RSPI controller" tristate "Renesas RSPI controller"
depends on SUPERH depends on SUPERH && SH_DMAE_BASE
help help
SPI driver for Renesas RSPI blocks. SPI driver for Renesas RSPI blocks.
...@@ -385,7 +414,7 @@ config SPI_SH_MSIOF ...@@ -385,7 +414,7 @@ config SPI_SH_MSIOF
config SPI_SH config SPI_SH
tristate "SuperH SPI controller" tristate "SuperH SPI controller"
depends on SUPERH depends on SUPERH || COMPILE_TEST
help help
SPI driver for SuperH SPI blocks. SPI driver for SuperH SPI blocks.
...@@ -398,13 +427,13 @@ config SPI_SH_SCI ...@@ -398,13 +427,13 @@ config SPI_SH_SCI
config SPI_SH_HSPI config SPI_SH_HSPI
tristate "SuperH HSPI controller" tristate "SuperH HSPI controller"
depends on ARCH_SHMOBILE depends on ARCH_SHMOBILE || COMPILE_TEST
help help
SPI driver for SuperH HSPI blocks. SPI driver for SuperH HSPI blocks.
config SPI_SIRF config SPI_SIRF
tristate "CSR SiRFprimaII SPI controller" tristate "CSR SiRFprimaII SPI controller"
depends on ARCH_SIRF depends on SIRF_DMA
select SPI_BITBANG select SPI_BITBANG
help help
SPI driver for CSR SiRFprimaII SoCs SPI driver for CSR SiRFprimaII SoCs
...@@ -418,7 +447,7 @@ config SPI_MXS ...@@ -418,7 +447,7 @@ config SPI_MXS
config SPI_TEGRA114 config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller" tristate "NVIDIA Tegra114 SPI Controller"
depends on ARCH_TEGRA && TEGRA20_APB_DMA depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
help help
SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
is different than the older SoCs SPI controller and also register interface is different than the older SoCs SPI controller and also register interface
...@@ -426,7 +455,7 @@ config SPI_TEGRA114 ...@@ -426,7 +455,7 @@ config SPI_TEGRA114
config SPI_TEGRA20_SFLASH config SPI_TEGRA20_SFLASH
tristate "Nvidia Tegra20 Serial flash Controller" tristate "Nvidia Tegra20 Serial flash Controller"
depends on ARCH_TEGRA depends on ARCH_TEGRA || COMPILE_TEST
help help
SPI driver for Nvidia Tegra20 Serial flash Controller interface. SPI driver for Nvidia Tegra20 Serial flash Controller interface.
The main usecase of this controller is to use spi flash as boot The main usecase of this controller is to use spi flash as boot
...@@ -434,7 +463,7 @@ config SPI_TEGRA20_SFLASH ...@@ -434,7 +463,7 @@ config SPI_TEGRA20_SFLASH
config SPI_TEGRA20_SLINK config SPI_TEGRA20_SLINK
tristate "Nvidia Tegra20/Tegra30 SLINK Controller" tristate "Nvidia Tegra20/Tegra30 SLINK Controller"
depends on ARCH_TEGRA && TEGRA20_APB_DMA depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
help help
SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface.
...@@ -457,7 +486,7 @@ config SPI_TOPCLIFF_PCH ...@@ -457,7 +486,7 @@ config SPI_TOPCLIFF_PCH
config SPI_TXX9 config SPI_TXX9
tristate "Toshiba TXx9 SPI controller" tristate "Toshiba TXx9 SPI controller"
depends on GPIOLIB && CPU_TX49XX depends on GPIOLIB && (CPU_TX49XX || COMPILE_TEST)
help help
SPI driver for Toshiba TXx9 MIPS SoCs SPI driver for Toshiba TXx9 MIPS SoCs
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_AU1550) += spi-au1550.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o
obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o
obj-$(CONFIG_SPI_BFIN_V3) += spi-bfin-v3.o
obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o
obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o
...@@ -27,9 +28,11 @@ obj-$(CONFIG_SPI_DESIGNWARE) += spi-dw.o ...@@ -27,9 +28,11 @@ obj-$(CONFIG_SPI_DESIGNWARE) += spi-dw.o
obj-$(CONFIG_SPI_DW_MMIO) += spi-dw-mmio.o obj-$(CONFIG_SPI_DW_MMIO) += spi-dw-mmio.o
obj-$(CONFIG_SPI_DW_PCI) += spi-dw-midpci.o obj-$(CONFIG_SPI_DW_PCI) += spi-dw-midpci.o
spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o
obj-$(CONFIG_SPI_EFM32) += spi-efm32.o
obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o
obj-$(CONFIG_SPI_FALCON) += spi-falcon.o obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o 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_LIB) += spi-fsl-lib.o
obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o
obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
...@@ -46,6 +49,7 @@ obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o ...@@ -46,6 +49,7 @@ obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o
obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o
obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o
obj-$(CONFIG_SPI_ORION) += spi-orion.o obj-$(CONFIG_SPI_ORION) += spi-orion.o
obj-$(CONFIG_SPI_PL022) += spi-pl022.o obj-$(CONFIG_SPI_PL022) += spi-pl022.o
obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o
......
...@@ -103,16 +103,6 @@ static void altera_spi_chipsel(struct spi_device *spi, int value) ...@@ -103,16 +103,6 @@ static void altera_spi_chipsel(struct spi_device *spi, int value)
} }
} }
static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
{
return 0;
}
static int altera_spi_setup(struct spi_device *spi)
{
return 0;
}
static inline unsigned int hw_txbyte(struct altera_spi *hw, int count) static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
{ {
if (hw->tx) { if (hw->tx) {
...@@ -134,7 +124,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -134,7 +124,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
hw->tx = t->tx_buf; hw->tx = t->tx_buf;
hw->rx = t->rx_buf; hw->rx = t->rx_buf;
hw->count = 0; hw->count = 0;
hw->bytes_per_word = t->bits_per_word / 8; hw->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8);
hw->len = t->len / hw->bytes_per_word; hw->len = t->len / hw->bytes_per_word;
if (hw->irq >= 0) { if (hw->irq >= 0) {
...@@ -150,12 +140,12 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -150,12 +140,12 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
} else { } else {
/* send the first byte */ while (hw->count < hw->len) {
writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);
while (1) {
unsigned int rxd; unsigned int rxd;
writel(hw_txbyte(hw, hw->count),
hw->base + ALTERA_SPI_TXDATA);
while (!(readl(hw->base + ALTERA_SPI_STATUS) & while (!(readl(hw->base + ALTERA_SPI_STATUS) &
ALTERA_SPI_STATUS_RRDY_MSK)) ALTERA_SPI_STATUS_RRDY_MSK))
cpu_relax(); cpu_relax();
...@@ -174,14 +164,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -174,14 +164,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
} }
hw->count++; hw->count++;
if (hw->count < hw->len)
writel(hw_txbyte(hw, hw->count),
hw->base + ALTERA_SPI_TXDATA);
else
break;
} }
} }
return hw->count * hw->bytes_per_word; return hw->count * hw->bytes_per_word;
...@@ -217,7 +200,7 @@ static irqreturn_t altera_spi_irq(int irq, void *dev) ...@@ -217,7 +200,7 @@ static irqreturn_t altera_spi_irq(int irq, void *dev)
static int altera_spi_probe(struct platform_device *pdev) static int altera_spi_probe(struct platform_device *pdev)
{ {
struct altera_spi_platform_data *platp = pdev->dev.platform_data; struct altera_spi_platform_data *platp = dev_get_platdata(&pdev->dev);
struct altera_spi *hw; struct altera_spi *hw;
struct spi_master *master; struct spi_master *master;
struct resource *res; struct resource *res;
...@@ -231,7 +214,6 @@ static int altera_spi_probe(struct platform_device *pdev) ...@@ -231,7 +214,6 @@ static int altera_spi_probe(struct platform_device *pdev)
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->num_chipselect = 16; master->num_chipselect = 16;
master->mode_bits = SPI_CS_HIGH; master->mode_bits = SPI_CS_HIGH;
master->setup = altera_spi_setup;
hw = spi_master_get_devdata(master); hw = spi_master_get_devdata(master);
platform_set_drvdata(pdev, hw); platform_set_drvdata(pdev, hw);
...@@ -240,21 +222,16 @@ static int altera_spi_probe(struct platform_device *pdev) ...@@ -240,21 +222,16 @@ static int altera_spi_probe(struct platform_device *pdev)
hw->bitbang.master = spi_master_get(master); hw->bitbang.master = spi_master_get(master);
if (!hw->bitbang.master) if (!hw->bitbang.master)
return err; return err;
hw->bitbang.setup_transfer = altera_spi_setupxfer;
hw->bitbang.chipselect = altera_spi_chipsel; hw->bitbang.chipselect = altera_spi_chipsel;
hw->bitbang.txrx_bufs = altera_spi_txrx; hw->bitbang.txrx_bufs = altera_spi_txrx;
/* find and map our resources */ /* find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) hw->base = devm_ioremap_resource(&pdev->dev, res);
goto exit_busy; if (IS_ERR(hw->base)) {
if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), err = PTR_ERR(hw->base);
pdev->name)) goto exit;
goto exit_busy; }
hw->base = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (!hw->base)
goto exit_busy;
/* program defaults into the registers */ /* program defaults into the registers */
hw->imr = 0; /* disable spi interrupts */ hw->imr = 0; /* disable spi interrupts */
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
...@@ -281,9 +258,6 @@ static int altera_spi_probe(struct platform_device *pdev) ...@@ -281,9 +258,6 @@ static int altera_spi_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);
return 0; return 0;
exit_busy:
err = -EBUSY;
exit: exit:
spi_master_put(master); spi_master_put(master);
return err; return err;
......
...@@ -221,7 +221,7 @@ static int ath79_spi_probe(struct platform_device *pdev) ...@@ -221,7 +221,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
sp = spi_master_get_devdata(master); sp = spi_master_get_devdata(master);
platform_set_drvdata(pdev, sp); platform_set_drvdata(pdev, sp);
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->setup = ath79_spi_setup; master->setup = ath79_spi_setup;
......
...@@ -360,12 +360,12 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) ...@@ -360,12 +360,12 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
gpio_set_value(asd->npcs_pin, !active); gpio_set_value(asd->npcs_pin, !active);
} }
static void atmel_spi_lock(struct atmel_spi *as) static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock)
{ {
spin_lock_irqsave(&as->lock, as->flags); spin_lock_irqsave(&as->lock, as->flags);
} }
static void atmel_spi_unlock(struct atmel_spi *as) static void atmel_spi_unlock(struct atmel_spi *as) __releases(&as->lock)
{ {
spin_unlock_irqrestore(&as->lock, as->flags); spin_unlock_irqrestore(&as->lock, as->flags);
} }
...@@ -629,9 +629,9 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, ...@@ -629,9 +629,9 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
goto err_dma; goto err_dma;
dev_dbg(master->dev.parent, dev_dbg(master->dev.parent,
" start dma xfer %p: len %u tx %p/%08x rx %p/%08x\n", " start dma xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, xfer, xfer->len, xfer->tx_buf, (unsigned long long)xfer->tx_dma,
xfer->rx_buf, xfer->rx_dma); xfer->rx_buf, (unsigned long long)xfer->rx_dma);
/* Enable relevant interrupts */ /* Enable relevant interrupts */
spi_writel(as, IER, SPI_BIT(OVRES)); spi_writel(as, IER, SPI_BIT(OVRES));
...@@ -732,9 +732,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, ...@@ -732,9 +732,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,
spi_writel(as, TCR, len); spi_writel(as, TCR, len);
dev_dbg(&msg->spi->dev, dev_dbg(&msg->spi->dev,
" start xfer %p: len %u tx %p/%08x rx %p/%08x\n", " start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, xfer, xfer->len, xfer->tx_buf,
xfer->rx_buf, xfer->rx_dma); (unsigned long long)xfer->tx_dma, xfer->rx_buf,
(unsigned long long)xfer->rx_dma);
} else { } else {
xfer = as->next_transfer; xfer = as->next_transfer;
remaining = as->next_remaining_bytes; remaining = as->next_remaining_bytes;
...@@ -771,9 +772,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, ...@@ -771,9 +772,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,
spi_writel(as, TNCR, len); spi_writel(as, TNCR, len);
dev_dbg(&msg->spi->dev, dev_dbg(&msg->spi->dev,
" next xfer %p: len %u tx %p/%08x rx %p/%08x\n", " next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, xfer, xfer->len, xfer->tx_buf,
xfer->rx_buf, xfer->rx_dma); (unsigned long long)xfer->tx_dma, xfer->rx_buf,
(unsigned long long)xfer->rx_dma);
ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES);
} else { } else {
spi_writel(as, RNCR, 0); spi_writel(as, RNCR, 0);
...@@ -1579,7 +1581,9 @@ static int atmel_spi_probe(struct platform_device *pdev) ...@@ -1579,7 +1581,9 @@ static int atmel_spi_probe(struct platform_device *pdev)
goto out_unmap_regs; goto out_unmap_regs;
/* Initialize the hardware */ /* Initialize the hardware */
clk_enable(clk); ret = clk_prepare_enable(clk);
if (ret)
goto out_unmap_regs;
spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
if (as->caps.has_wdrbt) { if (as->caps.has_wdrbt) {
...@@ -1609,7 +1613,7 @@ static int atmel_spi_probe(struct platform_device *pdev) ...@@ -1609,7 +1613,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
clk_disable(clk); clk_disable_unprepare(clk);
free_irq(irq, master); free_irq(irq, master);
out_unmap_regs: out_unmap_regs:
iounmap(as->regs); iounmap(as->regs);
...@@ -1661,7 +1665,7 @@ static int atmel_spi_remove(struct platform_device *pdev) ...@@ -1661,7 +1665,7 @@ static int atmel_spi_remove(struct platform_device *pdev)
dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
as->buffer_dma); as->buffer_dma);
clk_disable(as->clk); clk_disable_unprepare(as->clk);
clk_put(as->clk); clk_put(as->clk);
free_irq(as->irq, master); free_irq(as->irq, master);
iounmap(as->regs); iounmap(as->regs);
...@@ -1678,7 +1682,7 @@ static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg) ...@@ -1678,7 +1682,7 @@ static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg)
struct spi_master *master = platform_get_drvdata(pdev); struct spi_master *master = platform_get_drvdata(pdev);
struct atmel_spi *as = spi_master_get_devdata(master); struct atmel_spi *as = spi_master_get_devdata(master);
clk_disable(as->clk); clk_disable_unprepare(as->clk);
return 0; return 0;
} }
...@@ -1687,7 +1691,7 @@ static int atmel_spi_resume(struct platform_device *pdev) ...@@ -1687,7 +1691,7 @@ static int atmel_spi_resume(struct platform_device *pdev)
struct spi_master *master = platform_get_drvdata(pdev); struct spi_master *master = platform_get_drvdata(pdev);
struct atmel_spi *as = spi_master_get_devdata(master); struct atmel_spi *as = spi_master_get_devdata(master);
clk_enable(as->clk); return clk_prepare_enable(as->clk);
return 0; return 0;
} }
......
...@@ -776,7 +776,7 @@ static int au1550_spi_probe(struct platform_device *pdev) ...@@ -776,7 +776,7 @@ static int au1550_spi_probe(struct platform_device *pdev)
hw = spi_master_get_devdata(master); hw = spi_master_get_devdata(master);
hw->master = spi_master_get(master); hw->master = spi_master_get(master);
hw->pdata = pdev->dev.platform_data; hw->pdata = dev_get_platdata(&pdev->dev);
hw->dev = &pdev->dev; hw->dev = &pdev->dev;
if (hw->pdata == NULL) { if (hw->pdata == NULL) {
......
...@@ -314,7 +314,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -314,7 +314,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
master->mode_bits = BCM2835_SPI_MODE_BITS; master->mode_bits = BCM2835_SPI_MODE_BITS;
master->bits_per_word_mask = BIT(8 - 1); master->bits_per_word_mask = SPI_BPW_MASK(8);
master->bus_num = -1; master->bus_num = -1;
master->num_chipselect = 3; master->num_chipselect = 3;
master->transfer_one_message = bcm2835_spi_transfer_one; master->transfer_one_message = bcm2835_spi_transfer_one;
...@@ -325,12 +325,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -325,12 +325,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
init_completion(&bs->done); init_completion(&bs->done);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "could not get memory resource\n");
err = -ENODEV;
goto out_master_put;
}
bs->regs = devm_ioremap_resource(&pdev->dev, res); bs->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(bs->regs)) { if (IS_ERR(bs->regs)) {
err = PTR_ERR(bs->regs); err = PTR_ERR(bs->regs);
...@@ -383,7 +377,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -383,7 +377,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
static int bcm2835_spi_remove(struct platform_device *pdev) static int bcm2835_spi_remove(struct platform_device *pdev)
{ {
struct spi_master *master = platform_get_drvdata(pdev); struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
struct bcm2835_spi *bs = spi_master_get_devdata(master); struct bcm2835_spi *bs = spi_master_get_devdata(master);
free_irq(bs->irq, master); free_irq(bs->irq, master);
......
...@@ -231,24 +231,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, ...@@ -231,24 +231,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
return 0; return 0;
} }
static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
pm_runtime_get_sync(&bs->pdev->dev);
return 0;
}
static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
pm_runtime_put(&bs->pdev->dev);
return 0;
}
static int bcm63xx_spi_transfer_one(struct spi_master *master, static int bcm63xx_spi_transfer_one(struct spi_master *master,
struct spi_message *m) struct spi_message *m)
{ {
...@@ -353,20 +335,13 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) ...@@ -353,20 +335,13 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
{ {
struct resource *r; struct resource *r;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data; struct bcm63xx_spi_pdata *pdata = dev_get_platdata(&pdev->dev);
int irq; int irq;
struct spi_master *master; struct spi_master *master;
struct clk *clk; struct clk *clk;
struct bcm63xx_spi *bs; struct bcm63xx_spi *bs;
int ret; int ret;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
dev_err(dev, "no iomem\n");
ret = -ENXIO;
goto out;
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(dev, "no irq\n"); dev_err(dev, "no irq\n");
...@@ -393,6 +368,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) ...@@ -393,6 +368,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
bs->pdev = pdev; bs->pdev = pdev;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bs->regs = devm_ioremap_resource(&pdev->dev, r); bs->regs = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(bs->regs)) { if (IS_ERR(bs->regs)) {
ret = PTR_ERR(bs->regs); ret = PTR_ERR(bs->regs);
...@@ -412,11 +388,10 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) ...@@ -412,11 +388,10 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
master->bus_num = pdata->bus_num; master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->num_chipselect; master->num_chipselect = pdata->num_chipselect;
master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
master->transfer_one_message = bcm63xx_spi_transfer_one; master->transfer_one_message = bcm63xx_spi_transfer_one;
master->mode_bits = MODEBITS; master->mode_bits = MODEBITS;
master->bits_per_word_mask = SPI_BPW_MASK(8); master->bits_per_word_mask = SPI_BPW_MASK(8);
master->auto_runtime_pm = true;
bs->msg_type_shift = pdata->msg_type_shift; bs->msg_type_shift = pdata->msg_type_shift;
bs->msg_ctl_width = pdata->msg_ctl_width; bs->msg_ctl_width = pdata->msg_ctl_width;
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
...@@ -480,8 +455,7 @@ static int bcm63xx_spi_remove(struct platform_device *pdev) ...@@ -480,8 +455,7 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int bcm63xx_spi_suspend(struct device *dev) static int bcm63xx_spi_suspend(struct device *dev)
{ {
struct spi_master *master = struct spi_master *master = dev_get_drvdata(dev);
platform_get_drvdata(to_platform_device(dev));
struct bcm63xx_spi *bs = spi_master_get_devdata(master); struct bcm63xx_spi *bs = spi_master_get_devdata(master);
spi_master_suspend(master); spi_master_suspend(master);
...@@ -493,8 +467,7 @@ static int bcm63xx_spi_suspend(struct device *dev) ...@@ -493,8 +467,7 @@ static int bcm63xx_spi_suspend(struct device *dev)
static int bcm63xx_spi_resume(struct device *dev) static int bcm63xx_spi_resume(struct device *dev)
{ {
struct spi_master *master = struct spi_master *master = dev_get_drvdata(dev);
platform_get_drvdata(to_platform_device(dev));
struct bcm63xx_spi *bs = spi_master_get_devdata(master); struct bcm63xx_spi *bs = spi_master_get_devdata(master);
clk_prepare_enable(bs->clk); clk_prepare_enable(bs->clk);
......
...@@ -756,7 +756,7 @@ static int bfin_sport_spi_probe(struct platform_device *pdev) ...@@ -756,7 +756,7 @@ static int bfin_sport_spi_probe(struct platform_device *pdev)
struct bfin_sport_spi_master_data *drv_data; struct bfin_sport_spi_master_data *drv_data;
int status; int status;
platform_info = dev->platform_data; platform_info = dev_get_platdata(dev);
/* Allocate master with space for drv_data */ /* Allocate master with space for drv_data */
master = spi_alloc_master(dev, sizeof(*master) + 16); master = spi_alloc_master(dev, sizeof(*master) + 16);
......
This diff is collapsed.
...@@ -1271,7 +1271,7 @@ static int bfin_spi_probe(struct platform_device *pdev) ...@@ -1271,7 +1271,7 @@ static int bfin_spi_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int status = 0; int status = 0;
platform_info = dev->platform_data; platform_info = dev_get_platdata(dev);
/* Allocate master with space for drv_data */ /* Allocate master with space for drv_data */
master = spi_alloc_master(dev, sizeof(*drv_data)); master = spi_alloc_master(dev, sizeof(*drv_data));
......
...@@ -255,150 +255,140 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) ...@@ -255,150 +255,140 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
* Drivers can provide word-at-a-time i/o primitives, or provide * Drivers can provide word-at-a-time i/o primitives, or provide
* transfer-at-a-time ones to leverage dma or fifo hardware. * transfer-at-a-time ones to leverage dma or fifo hardware.
*/ */
static void bitbang_work(struct work_struct *work)
static int spi_bitbang_prepare_hardware(struct spi_master *spi)
{ {
struct spi_bitbang *bitbang = struct spi_bitbang *bitbang;
container_of(work, struct spi_bitbang, work);
unsigned long flags; unsigned long flags;
struct spi_message *m, *_m;
bitbang = spi_master_get_devdata(spi);
spin_lock_irqsave(&bitbang->lock, flags); spin_lock_irqsave(&bitbang->lock, flags);
bitbang->busy = 1; bitbang->busy = 1;
list_for_each_entry_safe(m, _m, &bitbang->queue, queue) { spin_unlock_irqrestore(&bitbang->lock, flags);
struct spi_device *spi;
unsigned nsecs;
struct spi_transfer *t = NULL;
unsigned tmp;
unsigned cs_change;
int status;
int do_setup = -1;
list_del(&m->queue);
spin_unlock_irqrestore(&bitbang->lock, flags);
/* FIXME this is made-up ... the correct value is known to
* word-at-a-time bitbang code, and presumably chipselect()
* should enforce these requirements too?
*/
nsecs = 100;
spi = m->spi; return 0;
tmp = 0; }
cs_change = 1;
status = 0;
list_for_each_entry (t, &m->transfers, transfer_list) { static int spi_bitbang_transfer_one(struct spi_master *master,
struct spi_message *m)
/* override speed or wordsize? */ {
if (t->speed_hz || t->bits_per_word) struct spi_bitbang *bitbang;
do_setup = 1; unsigned nsecs;
struct spi_transfer *t = NULL;
/* init (-1) or override (1) transfer params */ unsigned cs_change;
if (do_setup != 0) { int status;
status = bitbang->setup_transfer(spi, t); int do_setup = -1;
if (status < 0) struct spi_device *spi = m->spi;
break;
if (do_setup == -1) bitbang = spi_master_get_devdata(master);
do_setup = 0;
} /* FIXME this is made-up ... the correct value is known to
* word-at-a-time bitbang code, and presumably chipselect()
/* set up default clock polarity, and activate chip; * should enforce these requirements too?
* this implicitly updates clock and spi modes as */
* previously recorded for this device via setup(). nsecs = 100;
* (and also deselects any other chip that might be
* selected ...)
*/
if (cs_change) {
bitbang->chipselect(spi, BITBANG_CS_ACTIVE);
ndelay(nsecs);
}
cs_change = t->cs_change;
if (!t->tx_buf && !t->rx_buf && t->len) {
status = -EINVAL;
break;
}
/* transfer data. the lower level code handles any cs_change = 1;
* new dma mappings it needs. our caller always gave status = 0;
* us dma-safe buffers.
*/ list_for_each_entry (t, &m->transfers, transfer_list) {
if (t->len) {
/* REVISIT dma API still needs a designated /* override speed or wordsize? */
* DMA_ADDR_INVALID; ~0 might be better. if (t->speed_hz || t->bits_per_word)
*/ do_setup = 1;
if (!m->is_dma_mapped)
t->rx_dma = t->tx_dma = 0; /* init (-1) or override (1) transfer params */
status = bitbang->txrx_bufs(spi, t); if (do_setup != 0) {
} status = bitbang->setup_transfer(spi, t);
if (status > 0) if (status < 0)
m->actual_length += status;
if (status != t->len) {
/* always report some kind of error */
if (status >= 0)
status = -EREMOTEIO;
break; break;
} if (do_setup == -1)
status = 0; do_setup = 0;
/* protocol tweaks before next transfer */
if (t->delay_usecs)
udelay(t->delay_usecs);
if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) {
/* sometimes a short mid-message deselect of the chip
* may be needed to terminate a mode or command
*/
ndelay(nsecs);
bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
ndelay(nsecs);
}
} }
m->status = status; /* set up default clock polarity, and activate chip;
m->complete(m->context); * this implicitly updates clock and spi modes as
* previously recorded for this device via setup().
* (and also deselects any other chip that might be
* selected ...)
*/
if (cs_change) {
bitbang->chipselect(spi, BITBANG_CS_ACTIVE);
ndelay(nsecs);
}
cs_change = t->cs_change;
if (!t->tx_buf && !t->rx_buf && t->len) {
status = -EINVAL;
break;
}
/* normally deactivate chipselect ... unless no error and /* transfer data. the lower level code handles any
* cs_change has hinted that the next message will probably * new dma mappings it needs. our caller always gave
* be for this chip too. * us dma-safe buffers.
*/ */
if (!(status == 0 && cs_change)) { if (t->len) {
/* REVISIT dma API still needs a designated
* DMA_ADDR_INVALID; ~0 might be better.
*/
if (!m->is_dma_mapped)
t->rx_dma = t->tx_dma = 0;
status = bitbang->txrx_bufs(spi, t);
}
if (status > 0)
m->actual_length += status;
if (status != t->len) {
/* always report some kind of error */
if (status >= 0)
status = -EREMOTEIO;
break;
}
status = 0;
/* protocol tweaks before next transfer */
if (t->delay_usecs)
udelay(t->delay_usecs);
if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) {
/* sometimes a short mid-message deselect of the chip
* may be needed to terminate a mode or command
*/
ndelay(nsecs); ndelay(nsecs);
bitbang->chipselect(spi, BITBANG_CS_INACTIVE); bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
ndelay(nsecs); ndelay(nsecs);
} }
}
m->status = status;
spin_lock_irqsave(&bitbang->lock, flags); /* normally deactivate chipselect ... unless no error and
* cs_change has hinted that the next message will probably
* be for this chip too.
*/
if (!(status == 0 && cs_change)) {
ndelay(nsecs);
bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
ndelay(nsecs);
} }
bitbang->busy = 0;
spin_unlock_irqrestore(&bitbang->lock, flags); spi_finalize_current_message(master);
return status;
} }
/** static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
* spi_bitbang_transfer - default submit to transfer queue
*/
int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
{ {
struct spi_bitbang *bitbang; struct spi_bitbang *bitbang;
unsigned long flags; unsigned long flags;
int status = 0;
m->actual_length = 0; bitbang = spi_master_get_devdata(spi);
m->status = -EINPROGRESS;
bitbang = spi_master_get_devdata(spi->master);
spin_lock_irqsave(&bitbang->lock, flags); spin_lock_irqsave(&bitbang->lock, flags);
if (!spi->max_speed_hz) bitbang->busy = 0;
status = -ENETDOWN;
else {
list_add_tail(&m->queue, &bitbang->queue);
queue_work(bitbang->workqueue, &bitbang->work);
}
spin_unlock_irqrestore(&bitbang->lock, flags); spin_unlock_irqrestore(&bitbang->lock, flags);
return status; return 0;
} }
EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
...@@ -428,20 +418,22 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer); ...@@ -428,20 +418,22 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
int spi_bitbang_start(struct spi_bitbang *bitbang) int spi_bitbang_start(struct spi_bitbang *bitbang)
{ {
struct spi_master *master = bitbang->master; struct spi_master *master = bitbang->master;
int status;
if (!master || !bitbang->chipselect) if (!master || !bitbang->chipselect)
return -EINVAL; return -EINVAL;
INIT_WORK(&bitbang->work, bitbang_work);
spin_lock_init(&bitbang->lock); spin_lock_init(&bitbang->lock);
INIT_LIST_HEAD(&bitbang->queue);
if (!master->mode_bits) if (!master->mode_bits)
master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
if (!master->transfer) if (master->transfer || master->transfer_one_message)
master->transfer = spi_bitbang_transfer; return -EINVAL;
master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
master->transfer_one_message = spi_bitbang_transfer_one;
if (!bitbang->txrx_bufs) { if (!bitbang->txrx_bufs) {
bitbang->use_dma = 0; bitbang->use_dma = 0;
bitbang->txrx_bufs = spi_bitbang_bufs; bitbang->txrx_bufs = spi_bitbang_bufs;
...@@ -452,34 +444,12 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) ...@@ -452,34 +444,12 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
master->setup = spi_bitbang_setup; master->setup = spi_bitbang_setup;
master->cleanup = spi_bitbang_cleanup; master->cleanup = spi_bitbang_cleanup;
} }
} else if (!master->setup)
return -EINVAL;
if (master->transfer == spi_bitbang_transfer &&
!bitbang->setup_transfer)
return -EINVAL;
/* this task is the only thing to touch the SPI bits */
bitbang->busy = 0;
bitbang->workqueue = create_singlethread_workqueue(
dev_name(master->dev.parent));
if (bitbang->workqueue == NULL) {
status = -EBUSY;
goto err1;
} }
/* driver may get busy before register() returns, especially /* driver may get busy before register() returns, especially
* if someone registered boardinfo for devices * if someone registered boardinfo for devices
*/ */
status = spi_register_master(master); return spi_register_master(master);
if (status < 0)
goto err2;
return status;
err2:
destroy_workqueue(bitbang->workqueue);
err1:
return status;
} }
EXPORT_SYMBOL_GPL(spi_bitbang_start); EXPORT_SYMBOL_GPL(spi_bitbang_start);
...@@ -490,10 +460,6 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang) ...@@ -490,10 +460,6 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
{ {
spi_unregister_master(bitbang->master); spi_unregister_master(bitbang->master);
WARN_ON(!list_empty(&bitbang->queue));
destroy_workqueue(bitbang->workqueue);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(spi_bitbang_stop); EXPORT_SYMBOL_GPL(spi_bitbang_stop);
......
...@@ -239,11 +239,8 @@ static int spi_clps711x_probe(struct platform_device *pdev) ...@@ -239,11 +239,8 @@ static int spi_clps711x_probe(struct platform_device *pdev)
} }
dev_err(&pdev->dev, "Failed to register master\n"); dev_err(&pdev->dev, "Failed to register master\n");
devm_free_irq(&pdev->dev, IRQ_SSEOTI, hw);
clk_out: clk_out:
devm_clk_put(&pdev->dev, hw->spi_clk);
err_out: err_out:
while (--i >= 0) while (--i >= 0)
if (gpio_is_valid(hw->chipselect[i])) if (gpio_is_valid(hw->chipselect[i]))
...@@ -261,13 +258,10 @@ static int spi_clps711x_remove(struct platform_device *pdev) ...@@ -261,13 +258,10 @@ static int spi_clps711x_remove(struct platform_device *pdev)
struct spi_master *master = platform_get_drvdata(pdev); struct spi_master *master = platform_get_drvdata(pdev);
struct spi_clps711x_data *hw = spi_master_get_devdata(master); struct spi_clps711x_data *hw = spi_master_get_devdata(master);
devm_free_irq(&pdev->dev, IRQ_SSEOTI, hw);
for (i = 0; i < master->num_chipselect; i++) for (i = 0; i < master->num_chipselect; i++)
if (gpio_is_valid(hw->chipselect[i])) if (gpio_is_valid(hw->chipselect[i]))
gpio_free(hw->chipselect[i]); gpio_free(hw->chipselect[i]);
devm_clk_put(&pdev->dev, hw->spi_clk);
spi_unregister_master(master); spi_unregister_master(master);
kfree(master); kfree(master);
......
...@@ -354,24 +354,6 @@ static int mcfqspi_transfer_one_message(struct spi_master *master, ...@@ -354,24 +354,6 @@ static int mcfqspi_transfer_one_message(struct spi_master *master,
} }
static int mcfqspi_prepare_transfer_hw(struct spi_master *master)
{
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
pm_runtime_get_sync(mcfqspi->dev);
return 0;
}
static int mcfqspi_unprepare_transfer_hw(struct spi_master *master)
{
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
pm_runtime_put_sync(mcfqspi->dev);
return 0;
}
static int mcfqspi_setup(struct spi_device *spi) static int mcfqspi_setup(struct spi_device *spi)
{ {
if (spi->chip_select >= spi->master->num_chipselect) { if (spi->chip_select >= spi->master->num_chipselect) {
...@@ -400,7 +382,7 @@ static int mcfqspi_probe(struct platform_device *pdev) ...@@ -400,7 +382,7 @@ static int mcfqspi_probe(struct platform_device *pdev)
struct mcfqspi_platform_data *pdata; struct mcfqspi_platform_data *pdata;
int status; int status;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
if (!pdata) { if (!pdata) {
dev_dbg(&pdev->dev, "platform data is missing\n"); dev_dbg(&pdev->dev, "platform data is missing\n");
return -ENOENT; return -ENOENT;
...@@ -473,8 +455,7 @@ static int mcfqspi_probe(struct platform_device *pdev) ...@@ -473,8 +455,7 @@ static int mcfqspi_probe(struct platform_device *pdev)
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
master->setup = mcfqspi_setup; master->setup = mcfqspi_setup;
master->transfer_one_message = mcfqspi_transfer_one_message; master->transfer_one_message = mcfqspi_transfer_one_message;
master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw; master->auto_runtime_pm = true;
master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw;
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
...@@ -558,7 +539,7 @@ static int mcfqspi_resume(struct device *dev) ...@@ -558,7 +539,7 @@ static int mcfqspi_resume(struct device *dev)
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_RUNTIME
static int mcfqspi_runtime_suspend(struct device *dev) static int mcfqspi_runtime_suspend(struct device *dev)
{ {
struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); struct mcfqspi *mcfqspi = dev_get_drvdata(dev);
clk_disable(mcfqspi->clk); clk_disable(mcfqspi->clk);
...@@ -567,7 +548,7 @@ static int mcfqspi_runtime_suspend(struct device *dev) ...@@ -567,7 +548,7 @@ static int mcfqspi_runtime_suspend(struct device *dev)
static int mcfqspi_runtime_resume(struct device *dev) static int mcfqspi_runtime_resume(struct device *dev)
{ {
struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); struct mcfqspi *mcfqspi = dev_get_drvdata(dev);
clk_enable(mcfqspi->clk); clk_enable(mcfqspi->clk);
......
...@@ -872,8 +872,8 @@ static int davinci_spi_probe(struct platform_device *pdev) ...@@ -872,8 +872,8 @@ static int davinci_spi_probe(struct platform_device *pdev)
goto free_master; goto free_master;
} }
if (pdev->dev.platform_data) { if (dev_get_platdata(&pdev->dev)) {
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
dspi->pdata = *pdata; dspi->pdata = *pdata;
} else { } else {
/* update dspi pdata with that from the DT */ /* update dspi pdata with that from the DT */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -584,7 +584,7 @@ static void fsl_espi_remove(struct mpc8xxx_spi *mspi) ...@@ -584,7 +584,7 @@ static void fsl_espi_remove(struct mpc8xxx_spi *mspi)
static struct spi_master * fsl_espi_probe(struct device *dev, static struct spi_master * fsl_espi_probe(struct device *dev,
struct resource *mem, unsigned int irq) struct resource *mem, unsigned int irq)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct spi_master *master; struct spi_master *master;
struct mpc8xxx_spi *mpc8xxx_spi; struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base; struct fsl_espi_reg *reg_base;
...@@ -665,7 +665,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, ...@@ -665,7 +665,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
static int of_fsl_espi_get_chipselects(struct device *dev) static int of_fsl_espi_get_chipselects(struct device *dev)
{ {
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
const u32 *prop; const u32 *prop;
int len; int len;
......
...@@ -122,7 +122,7 @@ const char *mpc8xxx_spi_strmode(unsigned int flags) ...@@ -122,7 +122,7 @@ const char *mpc8xxx_spi_strmode(unsigned int flags)
int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, int mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
unsigned int irq) unsigned int irq)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct spi_master *master; struct spi_master *master;
struct mpc8xxx_spi *mpc8xxx_spi; struct mpc8xxx_spi *mpc8xxx_spi;
int ret = 0; int ret = 0;
......
...@@ -574,7 +574,7 @@ static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on) ...@@ -574,7 +574,7 @@ static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on)
static void fsl_spi_grlib_probe(struct device *dev) static void fsl_spi_grlib_probe(struct device *dev)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct fsl_spi_reg *reg_base = mpc8xxx_spi->reg_base; struct fsl_spi_reg *reg_base = mpc8xxx_spi->reg_base;
...@@ -600,7 +600,7 @@ static void fsl_spi_grlib_probe(struct device *dev) ...@@ -600,7 +600,7 @@ static void fsl_spi_grlib_probe(struct device *dev)
static struct spi_master * fsl_spi_probe(struct device *dev, static struct spi_master * fsl_spi_probe(struct device *dev,
struct resource *mem, unsigned int irq) struct resource *mem, unsigned int irq)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct spi_master *master; struct spi_master *master;
struct mpc8xxx_spi *mpc8xxx_spi; struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_spi_reg *reg_base; struct fsl_spi_reg *reg_base;
...@@ -700,7 +700,8 @@ static struct spi_master * fsl_spi_probe(struct device *dev, ...@@ -700,7 +700,8 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
static void fsl_spi_cs_control(struct spi_device *spi, bool on) static void fsl_spi_cs_control(struct spi_device *spi, bool on)
{ {
struct device *dev = spi->dev.parent->parent; struct device *dev = spi->dev.parent->parent;
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
u16 cs = spi->chip_select; u16 cs = spi->chip_select;
int gpio = pinfo->gpios[cs]; int gpio = pinfo->gpios[cs];
bool alow = pinfo->alow_flags[cs]; bool alow = pinfo->alow_flags[cs];
...@@ -711,7 +712,7 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on) ...@@ -711,7 +712,7 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on)
static int of_fsl_spi_get_chipselects(struct device *dev) static int of_fsl_spi_get_chipselects(struct device *dev)
{ {
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
int ngpios; int ngpios;
int i = 0; int i = 0;
...@@ -790,7 +791,7 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ...@@ -790,7 +791,7 @@ static int of_fsl_spi_get_chipselects(struct device *dev)
static int of_fsl_spi_free_chipselects(struct device *dev) static int of_fsl_spi_free_chipselects(struct device *dev)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
int i; int i;
...@@ -889,7 +890,7 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev) ...@@ -889,7 +890,7 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev)
int irq; int irq;
struct spi_master *master; struct spi_master *master;
if (!pdev->dev.platform_data) if (!dev_get_platdata(&pdev->dev))
return -EINVAL; return -EINVAL;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......
...@@ -420,7 +420,7 @@ static int spi_gpio_probe(struct platform_device *pdev) ...@@ -420,7 +420,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
if (status > 0) if (status > 0)
use_of = 1; use_of = 1;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
#ifdef GENERIC_BITBANG #ifdef GENERIC_BITBANG
if (!pdata || !pdata->num_chipselect) if (!pdata || !pdata->num_chipselect)
return -ENODEV; return -ENODEV;
...@@ -506,7 +506,7 @@ static int spi_gpio_remove(struct platform_device *pdev) ...@@ -506,7 +506,7 @@ static int spi_gpio_remove(struct platform_device *pdev)
int status; int status;
spi_gpio = platform_get_drvdata(pdev); spi_gpio = platform_get_drvdata(pdev);
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
/* stop() unregisters child devices too */ /* stop() unregisters child devices too */
status = spi_bitbang_stop(&spi_gpio->bitbang); status = spi_bitbang_stop(&spi_gpio->bitbang);
......
...@@ -619,6 +619,7 @@ static const struct of_device_id spi_imx_dt_ids[] = { ...@@ -619,6 +619,7 @@ static const struct of_device_id spi_imx_dt_ids[] = {
{ .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, }, { .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, spi_imx_dt_ids);
static void spi_imx_chipselect(struct spi_device *spi, int is_active) static void spi_imx_chipselect(struct spi_device *spi, int is_active)
{ {
...@@ -796,10 +797,11 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -796,10 +797,11 @@ static int spi_imx_probe(struct platform_device *pdev)
if (!gpio_is_valid(cs_gpio)) if (!gpio_is_valid(cs_gpio))
continue; continue;
ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); ret = devm_gpio_request(&pdev->dev, spi_imx->chipselect[i],
DRIVER_NAME);
if (ret) { if (ret) {
dev_err(&pdev->dev, "can't get cs gpios\n"); dev_err(&pdev->dev, "can't get cs gpios\n");
goto out_gpio_free; goto out_master_put;
} }
} }
...@@ -816,50 +818,44 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -816,50 +818,44 @@ static int spi_imx_probe(struct platform_device *pdev)
(struct spi_imx_devtype_data *) pdev->id_entry->driver_data; (struct spi_imx_devtype_data *) pdev->id_entry->driver_data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { spi_imx->base = devm_ioremap_resource(&pdev->dev, res);
dev_err(&pdev->dev, "can't get platform resource\n"); if (IS_ERR(spi_imx->base)) {
ret = -ENOMEM; ret = PTR_ERR(spi_imx->base);
goto out_gpio_free; goto out_master_put;
}
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "request_mem_region failed\n");
ret = -EBUSY;
goto out_gpio_free;
}
spi_imx->base = ioremap(res->start, resource_size(res));
if (!spi_imx->base) {
ret = -EINVAL;
goto out_release_mem;
} }
spi_imx->irq = platform_get_irq(pdev, 0); spi_imx->irq = platform_get_irq(pdev, 0);
if (spi_imx->irq < 0) { if (spi_imx->irq < 0) {
ret = -EINVAL; ret = -EINVAL;
goto out_iounmap; goto out_master_put;
} }
ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx); ret = devm_request_irq(&pdev->dev, spi_imx->irq, spi_imx_isr, 0,
DRIVER_NAME, spi_imx);
if (ret) { if (ret) {
dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret); dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
goto out_iounmap; goto out_master_put;
} }
spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(spi_imx->clk_ipg)) { if (IS_ERR(spi_imx->clk_ipg)) {
ret = PTR_ERR(spi_imx->clk_ipg); ret = PTR_ERR(spi_imx->clk_ipg);
goto out_free_irq; goto out_master_put;
} }
spi_imx->clk_per = devm_clk_get(&pdev->dev, "per"); spi_imx->clk_per = devm_clk_get(&pdev->dev, "per");
if (IS_ERR(spi_imx->clk_per)) { if (IS_ERR(spi_imx->clk_per)) {
ret = PTR_ERR(spi_imx->clk_per); ret = PTR_ERR(spi_imx->clk_per);
goto out_free_irq; goto out_master_put;
} }
clk_prepare_enable(spi_imx->clk_per); ret = clk_prepare_enable(spi_imx->clk_per);
clk_prepare_enable(spi_imx->clk_ipg); if (ret)
goto out_master_put;
ret = clk_prepare_enable(spi_imx->clk_ipg);
if (ret)
goto out_put_per;
spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per);
...@@ -879,47 +875,27 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -879,47 +875,27 @@ static int spi_imx_probe(struct platform_device *pdev)
return ret; return ret;
out_clk_put: out_clk_put:
clk_disable_unprepare(spi_imx->clk_per);
clk_disable_unprepare(spi_imx->clk_ipg); clk_disable_unprepare(spi_imx->clk_ipg);
out_free_irq: out_put_per:
free_irq(spi_imx->irq, spi_imx); clk_disable_unprepare(spi_imx->clk_per);
out_iounmap: out_master_put:
iounmap(spi_imx->base);
out_release_mem:
release_mem_region(res->start, resource_size(res));
out_gpio_free:
while (--i >= 0) {
if (gpio_is_valid(spi_imx->chipselect[i]))
gpio_free(spi_imx->chipselect[i]);
}
spi_master_put(master); spi_master_put(master);
kfree(master);
return ret; return ret;
} }
static int spi_imx_remove(struct platform_device *pdev) static int spi_imx_remove(struct platform_device *pdev)
{ {
struct spi_master *master = platform_get_drvdata(pdev); struct spi_master *master = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
int i;
spi_bitbang_stop(&spi_imx->bitbang); spi_bitbang_stop(&spi_imx->bitbang);
writel(0, spi_imx->base + MXC_CSPICTRL); writel(0, spi_imx->base + MXC_CSPICTRL);
clk_disable_unprepare(spi_imx->clk_per);
clk_disable_unprepare(spi_imx->clk_ipg); clk_disable_unprepare(spi_imx->clk_ipg);
free_irq(spi_imx->irq, spi_imx); clk_disable_unprepare(spi_imx->clk_per);
iounmap(spi_imx->base);
for (i = 0; i < master->num_chipselect; i++)
if (gpio_is_valid(spi_imx->chipselect[i]))
gpio_free(spi_imx->chipselect[i]);
spi_master_put(master); spi_master_put(master);
release_mem_region(res->start, resource_size(res));
return 0; return 0;
} }
......
...@@ -38,7 +38,8 @@ struct mpc512x_psc_spi { ...@@ -38,7 +38,8 @@ struct mpc512x_psc_spi {
struct mpc512x_psc_fifo __iomem *fifo; struct mpc512x_psc_fifo __iomem *fifo;
unsigned int irq; unsigned int irq;
u8 bits_per_word; u8 bits_per_word;
u32 mclk; struct clk *clk_mclk;
u32 mclk_rate;
struct completion txisrdone; struct completion txisrdone;
}; };
...@@ -72,6 +73,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) ...@@ -72,6 +73,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
struct mpc52xx_psc __iomem *psc = mps->psc; struct mpc52xx_psc __iomem *psc = mps->psc;
u32 sicr; u32 sicr;
u32 ccr; u32 ccr;
int speed;
u16 bclkdiv; u16 bclkdiv;
sicr = in_be32(&psc->sicr); sicr = in_be32(&psc->sicr);
...@@ -95,10 +97,10 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) ...@@ -95,10 +97,10 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
ccr = in_be32(&psc->ccr); ccr = in_be32(&psc->ccr);
ccr &= 0xFF000000; ccr &= 0xFF000000;
if (cs->speed_hz) speed = cs->speed_hz;
bclkdiv = (mps->mclk / cs->speed_hz) - 1; if (!speed)
else speed = 1000000; /* default 1MHz */
bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ bclkdiv = (mps->mclk_rate / speed) - 1;
ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
out_be32(&psc->ccr, ccr); out_be32(&psc->ccr, ccr);
...@@ -386,19 +388,11 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ...@@ -386,19 +388,11 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
{ {
struct mpc52xx_psc __iomem *psc = mps->psc; struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
struct clk *spiclk;
int ret = 0;
char name[32];
u32 sicr; u32 sicr;
u32 ccr; u32 ccr;
int speed;
u16 bclkdiv; u16 bclkdiv;
sprintf(name, "psc%d_mclk", master->bus_num);
spiclk = clk_get(&master->dev, name);
clk_enable(spiclk);
mps->mclk = clk_get_rate(spiclk);
clk_put(spiclk);
/* Reset the PSC into a known state */ /* Reset the PSC into a known state */
out_8(&psc->command, MPC52xx_PSC_RST_RX); out_8(&psc->command, MPC52xx_PSC_RST_RX);
out_8(&psc->command, MPC52xx_PSC_RST_TX); out_8(&psc->command, MPC52xx_PSC_RST_TX);
...@@ -425,7 +419,8 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ...@@ -425,7 +419,8 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
ccr = in_be32(&psc->ccr); ccr = in_be32(&psc->ccr);
ccr &= 0xFF000000; ccr &= 0xFF000000;
bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ speed = 1000000; /* default 1MHz */
bclkdiv = (mps->mclk_rate / speed) - 1;
ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
out_be32(&psc->ccr, ccr); out_be32(&psc->ccr, ccr);
...@@ -445,7 +440,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ...@@ -445,7 +440,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
mps->bits_per_word = 8; mps->bits_per_word = 8;
return ret; return 0;
} }
static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
...@@ -474,11 +469,14 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, ...@@ -474,11 +469,14 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
u32 size, unsigned int irq, u32 size, unsigned int irq,
s16 bus_num) s16 bus_num)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc512x_psc_spi *mps; struct mpc512x_psc_spi *mps;
struct spi_master *master; struct spi_master *master;
int ret; int ret;
void *tempp; void *tempp;
int psc_num;
char clk_name[16];
struct clk *clk;
master = spi_alloc_master(dev, sizeof *mps); master = spi_alloc_master(dev, sizeof *mps);
if (master == NULL) if (master == NULL)
...@@ -521,16 +519,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, ...@@ -521,16 +519,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
goto free_master; goto free_master;
init_completion(&mps->txisrdone); init_completion(&mps->txisrdone);
psc_num = master->bus_num;
snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
clk = devm_clk_get(dev, clk_name);
if (IS_ERR(clk))
goto free_irq;
ret = clk_prepare_enable(clk);
if (ret)
goto free_irq;
mps->clk_mclk = clk;
mps->mclk_rate = clk_get_rate(clk);
ret = mpc512x_psc_spi_port_config(master, mps); ret = mpc512x_psc_spi_port_config(master, mps);
if (ret < 0) if (ret < 0)
goto free_irq; goto free_clock;
ret = spi_register_master(master); ret = spi_register_master(master);
if (ret < 0) if (ret < 0)
goto free_irq; goto free_clock;
return ret; return ret;
free_clock:
clk_disable_unprepare(mps->clk_mclk);
free_irq: free_irq:
free_irq(mps->irq, mps); free_irq(mps->irq, mps);
free_master: free_master:
...@@ -547,6 +558,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev) ...@@ -547,6 +558,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev)
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
spi_unregister_master(master); spi_unregister_master(master);
clk_disable_unprepare(mps->clk_mclk);
free_irq(mps->irq, mps); free_irq(mps->irq, mps);
if (mps->psc) if (mps->psc)
iounmap(mps->psc); iounmap(mps->psc);
......
...@@ -366,7 +366,7 @@ static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id) ...@@ -366,7 +366,7 @@ static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id)
static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
u32 size, unsigned int irq, s16 bus_num) u32 size, unsigned int irq, s16 bus_num)
{ {
struct fsl_spi_platform_data *pdata = dev->platform_data; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc52xx_psc_spi *mps; struct mpc52xx_psc_spi *mps;
struct spi_master *master; struct spi_master *master;
int ret; int ret;
......
...@@ -67,13 +67,8 @@ static int mxs_spi_setup_transfer(struct spi_device *dev, ...@@ -67,13 +67,8 @@ static int mxs_spi_setup_transfer(struct spi_device *dev,
{ {
struct mxs_spi *spi = spi_master_get_devdata(dev->master); struct mxs_spi *spi = spi_master_get_devdata(dev->master);
struct mxs_ssp *ssp = &spi->ssp; struct mxs_ssp *ssp = &spi->ssp;
uint8_t bits_per_word;
uint32_t hz = 0; uint32_t hz = 0;
bits_per_word = dev->bits_per_word;
if (t && t->bits_per_word)
bits_per_word = t->bits_per_word;
hz = dev->max_speed_hz; hz = dev->max_speed_hz;
if (t && t->speed_hz) if (t && t->speed_hz)
hz = min(hz, t->speed_hz); hz = min(hz, t->speed_hz);
...@@ -513,7 +508,7 @@ static int mxs_spi_probe(struct platform_device *pdev) ...@@ -513,7 +508,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq_err = platform_get_irq(pdev, 0); irq_err = platform_get_irq(pdev, 0);
if (!iores || irq_err < 0) if (irq_err < 0)
return -EINVAL; return -EINVAL;
base = devm_ioremap_resource(&pdev->dev, iores); base = devm_ioremap_resource(&pdev->dev, iores);
...@@ -563,25 +558,31 @@ static int mxs_spi_probe(struct platform_device *pdev) ...@@ -563,25 +558,31 @@ static int mxs_spi_probe(struct platform_device *pdev)
goto out_master_free; goto out_master_free;
} }
clk_prepare_enable(ssp->clk); ret = clk_prepare_enable(ssp->clk);
if (ret)
goto out_dma_release;
clk_set_rate(ssp->clk, clk_freq); clk_set_rate(ssp->clk, clk_freq);
ssp->clk_rate = clk_get_rate(ssp->clk) / 1000; ssp->clk_rate = clk_get_rate(ssp->clk) / 1000;
stmp_reset_block(ssp->base); ret = stmp_reset_block(ssp->base);
if (ret)
goto out_disable_clk;
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
ret = spi_register_master(master); ret = spi_register_master(master);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret); dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);
goto out_free_dma; goto out_disable_clk;
} }
return 0; return 0;
out_free_dma: out_disable_clk:
dma_release_channel(ssp->dmach);
clk_disable_unprepare(ssp->clk); clk_disable_unprepare(ssp->clk);
out_dma_release:
dma_release_channel(ssp->dmach);
out_master_free: out_master_free:
spi_master_put(master); spi_master_put(master);
return ret; return ret;
...@@ -598,11 +599,8 @@ static int mxs_spi_remove(struct platform_device *pdev) ...@@ -598,11 +599,8 @@ static int mxs_spi_remove(struct platform_device *pdev)
ssp = &spi->ssp; ssp = &spi->ssp;
spi_unregister_master(master); spi_unregister_master(master);
dma_release_channel(ssp->dmach);
clk_disable_unprepare(ssp->clk); clk_disable_unprepare(ssp->clk);
dma_release_channel(ssp->dmach);
spi_master_put(master); spi_master_put(master);
return 0; return 0;
......
...@@ -174,17 +174,6 @@ static void nuc900_spi_gobusy(struct nuc900_spi *hw) ...@@ -174,17 +174,6 @@ static void nuc900_spi_gobusy(struct nuc900_spi *hw)
spin_unlock_irqrestore(&hw->lock, flags); spin_unlock_irqrestore(&hw->lock, flags);
} }
static int nuc900_spi_setupxfer(struct spi_device *spi,
struct spi_transfer *t)
{
return 0;
}
static int nuc900_spi_setup(struct spi_device *spi)
{
return 0;
}
static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count) static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
{ {
return hw->tx ? hw->tx[count] : 0; return hw->tx ? hw->tx[count] : 0;
...@@ -361,7 +350,7 @@ static int nuc900_spi_probe(struct platform_device *pdev) ...@@ -361,7 +350,7 @@ static int nuc900_spi_probe(struct platform_device *pdev)
hw = spi_master_get_devdata(master); hw = spi_master_get_devdata(master);
hw->master = spi_master_get(master); hw->master = spi_master_get(master);
hw->pdata = pdev->dev.platform_data; hw->pdata = dev_get_platdata(&pdev->dev);
hw->dev = &pdev->dev; hw->dev = &pdev->dev;
if (hw->pdata == NULL) { if (hw->pdata == NULL) {
...@@ -373,14 +362,12 @@ static int nuc900_spi_probe(struct platform_device *pdev) ...@@ -373,14 +362,12 @@ static int nuc900_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hw); platform_set_drvdata(pdev, hw);
init_completion(&hw->done); init_completion(&hw->done);
master->mode_bits = SPI_MODE_0; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->num_chipselect = hw->pdata->num_cs; master->num_chipselect = hw->pdata->num_cs;
master->bus_num = hw->pdata->bus_num; master->bus_num = hw->pdata->bus_num;
hw->bitbang.master = hw->master; hw->bitbang.master = hw->master;
hw->bitbang.setup_transfer = nuc900_spi_setupxfer;
hw->bitbang.chipselect = nuc900_spi_chipsel; hw->bitbang.chipselect = nuc900_spi_chipsel;
hw->bitbang.txrx_bufs = nuc900_spi_txrx; hw->bitbang.txrx_bufs = nuc900_spi_txrx;
hw->bitbang.master->setup = nuc900_spi_setup;
hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (hw->res == NULL) { if (hw->res == NULL) {
......
...@@ -285,7 +285,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev) ...@@ -285,7 +285,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
static int tiny_spi_probe(struct platform_device *pdev) static int tiny_spi_probe(struct platform_device *pdev)
{ {
struct tiny_spi_platform_data *platp = pdev->dev.platform_data; struct tiny_spi_platform_data *platp = dev_get_platdata(&pdev->dev);
struct tiny_spi *hw; struct tiny_spi *hw;
struct spi_master *master; struct spi_master *master;
struct resource *res; struct resource *res;
...@@ -315,15 +315,11 @@ static int tiny_spi_probe(struct platform_device *pdev) ...@@ -315,15 +315,11 @@ static int tiny_spi_probe(struct platform_device *pdev)
/* find and map our resources */ /* find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) hw->base = devm_ioremap_resource(&pdev->dev, res);
goto exit_busy; if (IS_ERR(hw->base)) {
if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), err = PTR_ERR(hw->base);
pdev->name)) goto exit;
goto exit_busy; }
hw->base = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (!hw->base)
goto exit_busy;
/* irq is optional */ /* irq is optional */
hw->irq = platform_get_irq(pdev, 0); hw->irq = platform_get_irq(pdev, 0);
if (hw->irq >= 0) { if (hw->irq >= 0) {
...@@ -337,8 +333,10 @@ static int tiny_spi_probe(struct platform_device *pdev) ...@@ -337,8 +333,10 @@ static int tiny_spi_probe(struct platform_device *pdev)
if (platp) { if (platp) {
hw->gpio_cs_count = platp->gpio_cs_count; hw->gpio_cs_count = platp->gpio_cs_count;
hw->gpio_cs = platp->gpio_cs; hw->gpio_cs = platp->gpio_cs;
if (platp->gpio_cs_count && !platp->gpio_cs) if (platp->gpio_cs_count && !platp->gpio_cs) {
goto exit_busy; err = -EBUSY;
goto exit;
}
hw->freq = platp->freq; hw->freq = platp->freq;
hw->baudwidth = platp->baudwidth; hw->baudwidth = platp->baudwidth;
} else { } else {
...@@ -365,8 +363,6 @@ static int tiny_spi_probe(struct platform_device *pdev) ...@@ -365,8 +363,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
exit_gpio: exit_gpio:
while (i-- > 0) while (i-- > 0)
gpio_free(hw->gpio_cs[i]); gpio_free(hw->gpio_cs[i]);
exit_busy:
err = -EBUSY;
exit: exit:
spi_master_put(master); spi_master_put(master);
return err; return err;
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#define OCTEON_SPI_MAX_CLOCK_HZ 16000000 #define OCTEON_SPI_MAX_CLOCK_HZ 16000000
struct octeon_spi { struct octeon_spi {
struct spi_master *my_master;
u64 register_base; u64 register_base;
u64 last_cfg; u64 last_cfg;
u64 cs_enax; u64 cs_enax;
...@@ -64,7 +63,6 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, ...@@ -64,7 +63,6 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
unsigned int speed_hz; unsigned int speed_hz;
int mode; int mode;
bool cpha, cpol; bool cpha, cpol;
int bits_per_word;
const u8 *tx_buf; const u8 *tx_buf;
u8 *rx_buf; u8 *rx_buf;
int len; int len;
...@@ -76,12 +74,9 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, ...@@ -76,12 +74,9 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
mode = msg_setup->mode; mode = msg_setup->mode;
cpha = mode & SPI_CPHA; cpha = mode & SPI_CPHA;
cpol = mode & SPI_CPOL; cpol = mode & SPI_CPOL;
bits_per_word = msg_setup->bits_per_word;
if (xfer->speed_hz) if (xfer->speed_hz)
speed_hz = xfer->speed_hz; speed_hz = xfer->speed_hz;
if (xfer->bits_per_word)
bits_per_word = xfer->bits_per_word;
if (speed_hz > OCTEON_SPI_MAX_CLOCK_HZ) if (speed_hz > OCTEON_SPI_MAX_CLOCK_HZ)
speed_hz = OCTEON_SPI_MAX_CLOCK_HZ; speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
...@@ -166,19 +161,6 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, ...@@ -166,19 +161,6 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
return xfer->len; return xfer->len;
} }
static int octeon_spi_validate_bpw(struct spi_device *spi, u32 speed)
{
switch (speed) {
case 8:
break;
default:
dev_err(&spi->dev, "Error: %d bits per word not supported\n",
speed);
return -EINVAL;
}
return 0;
}
static int octeon_spi_transfer_one_message(struct spi_master *master, static int octeon_spi_transfer_one_message(struct spi_master *master,
struct spi_message *msg) struct spi_message *msg)
{ {
...@@ -196,15 +178,6 @@ static int octeon_spi_transfer_one_message(struct spi_master *master, ...@@ -196,15 +178,6 @@ static int octeon_spi_transfer_one_message(struct spi_master *master,
goto err; goto err;
} }
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (xfer->bits_per_word) {
status = octeon_spi_validate_bpw(msg->spi,
xfer->bits_per_word);
if (status)
goto err;
}
}
list_for_each_entry(xfer, &msg->transfers, transfer_list) { list_for_each_entry(xfer, &msg->transfers, transfer_list) {
bool last_xfer = &xfer->transfer_list == msg->transfers.prev; bool last_xfer = &xfer->transfer_list == msg->transfers.prev;
int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer); int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer);
...@@ -236,14 +209,9 @@ static struct octeon_spi_setup *octeon_spi_new_setup(struct spi_device *spi) ...@@ -236,14 +209,9 @@ static struct octeon_spi_setup *octeon_spi_new_setup(struct spi_device *spi)
static int octeon_spi_setup(struct spi_device *spi) static int octeon_spi_setup(struct spi_device *spi)
{ {
int r;
struct octeon_spi_setup *new_setup; struct octeon_spi_setup *new_setup;
struct octeon_spi_setup *old_setup = spi_get_ctldata(spi); struct octeon_spi_setup *old_setup = spi_get_ctldata(spi);
r = octeon_spi_validate_bpw(spi, spi->bits_per_word);
if (r)
return r;
new_setup = octeon_spi_new_setup(spi); new_setup = octeon_spi_new_setup(spi);
if (!new_setup) if (!new_setup)
return -ENOMEM; return -ENOMEM;
...@@ -261,14 +229,8 @@ static void octeon_spi_cleanup(struct spi_device *spi) ...@@ -261,14 +229,8 @@ static void octeon_spi_cleanup(struct spi_device *spi)
kfree(old_setup); kfree(old_setup);
} }
static int octeon_spi_nop_transfer_hardware(struct spi_master *master)
{
return 0;
}
static int octeon_spi_probe(struct platform_device *pdev) static int octeon_spi_probe(struct platform_device *pdev)
{ {
struct resource *res_mem; struct resource *res_mem;
struct spi_master *master; struct spi_master *master;
struct octeon_spi *p; struct octeon_spi *p;
...@@ -278,8 +240,7 @@ static int octeon_spi_probe(struct platform_device *pdev) ...@@ -278,8 +240,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
p = spi_master_get_devdata(master); p = spi_master_get_devdata(master);
platform_set_drvdata(pdev, p); platform_set_drvdata(pdev, master);
p->my_master = master;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -307,9 +268,8 @@ static int octeon_spi_probe(struct platform_device *pdev) ...@@ -307,9 +268,8 @@ static int octeon_spi_probe(struct platform_device *pdev)
master->setup = octeon_spi_setup; master->setup = octeon_spi_setup;
master->cleanup = octeon_spi_cleanup; master->cleanup = octeon_spi_cleanup;
master->prepare_transfer_hardware = octeon_spi_nop_transfer_hardware;
master->transfer_one_message = octeon_spi_transfer_one_message; master->transfer_one_message = octeon_spi_transfer_one_message;
master->unprepare_transfer_hardware = octeon_spi_nop_transfer_hardware; master->bits_per_word_mask = SPI_BPW_MASK(8);
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
err = spi_register_master(master); err = spi_register_master(master);
...@@ -328,10 +288,11 @@ static int octeon_spi_probe(struct platform_device *pdev) ...@@ -328,10 +288,11 @@ static int octeon_spi_probe(struct platform_device *pdev)
static int octeon_spi_remove(struct platform_device *pdev) static int octeon_spi_remove(struct platform_device *pdev)
{ {
struct octeon_spi *p = platform_get_drvdata(pdev); struct spi_master *master = platform_get_drvdata(pdev);
struct octeon_spi *p = spi_master_get_devdata(master);
u64 register_base = p->register_base; u64 register_base = p->register_base;
spi_unregister_master(p->my_master); spi_unregister_master(master);
/* Clear the CSENA* and put everything in a known state. */ /* Clear the CSENA* and put everything in a known state. */
cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0); cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
......
This diff is collapsed.
...@@ -335,23 +335,6 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) ...@@ -335,23 +335,6 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
} }
static int omap2_prepare_transfer(struct spi_master *master)
{
struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
pm_runtime_get_sync(mcspi->dev);
return 0;
}
static int omap2_unprepare_transfer(struct spi_master *master)
{
struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
pm_runtime_mark_last_busy(mcspi->dev);
pm_runtime_put_autosuspend(mcspi->dev);
return 0;
}
static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
{ {
unsigned long timeout; unsigned long timeout;
...@@ -1318,8 +1301,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) ...@@ -1318,8 +1301,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
master->setup = omap2_mcspi_setup; master->setup = omap2_mcspi_setup;
master->prepare_transfer_hardware = omap2_prepare_transfer; master->auto_runtime_pm = true;
master->unprepare_transfer_hardware = omap2_unprepare_transfer;
master->transfer_one_message = omap2_mcspi_transfer_one_message; master->transfer_one_message = omap2_mcspi_transfer_one_message;
master->cleanup = omap2_mcspi_cleanup; master->cleanup = omap2_mcspi_cleanup;
master->dev.of_node = node; master->dev.of_node = node;
...@@ -1340,7 +1322,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) ...@@ -1340,7 +1322,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL)) if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL))
mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
} else { } else {
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
master->num_chipselect = pdata->num_cs; master->num_chipselect = pdata->num_cs;
if (pdev->id != -1) if (pdev->id != -1)
master->bus_num = pdev->id; master->bus_num = pdev->id;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/sizes.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#define DRIVER_NAME "orion_spi" #define DRIVER_NAME "orion_spi"
...@@ -446,30 +447,22 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -446,30 +447,22 @@ static int orion_spi_probe(struct platform_device *pdev)
spi->min_speed = DIV_ROUND_UP(tclk_hz, 30); spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) { spi->base = devm_ioremap_resource(&pdev->dev, r);
status = -ENODEV; if (IS_ERR(spi->base)) {
status = PTR_ERR(spi->base);
goto out_rel_clk; goto out_rel_clk;
} }
if (!request_mem_region(r->start, resource_size(r),
dev_name(&pdev->dev))) {
status = -EBUSY;
goto out_rel_clk;
}
spi->base = ioremap(r->start, SZ_1K);
if (orion_spi_reset(spi) < 0) if (orion_spi_reset(spi) < 0)
goto out_rel_mem; goto out_rel_clk;
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)
goto out_rel_mem; goto out_rel_clk;
return status; return status;
out_rel_mem:
release_mem_region(r->start, resource_size(r));
out_rel_clk: out_rel_clk:
clk_disable_unprepare(spi->clk); clk_disable_unprepare(spi->clk);
clk_put(spi->clk); clk_put(spi->clk);
...@@ -482,7 +475,6 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -482,7 +475,6 @@ static int orion_spi_probe(struct platform_device *pdev)
static int orion_spi_remove(struct platform_device *pdev) static int orion_spi_remove(struct platform_device *pdev)
{ {
struct spi_master *master; struct spi_master *master;
struct resource *r;
struct orion_spi *spi; struct orion_spi *spi;
master = platform_get_drvdata(pdev); master = platform_get_drvdata(pdev);
...@@ -491,9 +483,6 @@ static int orion_spi_remove(struct platform_device *pdev) ...@@ -491,9 +483,6 @@ static int orion_spi_remove(struct platform_device *pdev)
clk_disable_unprepare(spi->clk); clk_disable_unprepare(spi->clk);
clk_put(spi->clk); clk_put(spi->clk);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(r->start, resource_size(r));
spi_unregister_master(master); spi_unregister_master(master);
return 0; return 0;
......
...@@ -1555,18 +1555,6 @@ static int pl022_transfer_one_message(struct spi_master *master, ...@@ -1555,18 +1555,6 @@ static int pl022_transfer_one_message(struct spi_master *master,
return 0; return 0;
} }
static int pl022_prepare_transfer_hardware(struct spi_master *master)
{
struct pl022 *pl022 = spi_master_get_devdata(master);
/*
* Just make sure we have all we need to run the transfer by syncing
* with the runtime PM framework.
*/
pm_runtime_get_sync(&pl022->adev->dev);
return 0;
}
static int pl022_unprepare_transfer_hardware(struct spi_master *master) static int pl022_unprepare_transfer_hardware(struct spi_master *master)
{ {
struct pl022 *pl022 = spi_master_get_devdata(master); struct pl022 *pl022 = spi_master_get_devdata(master);
...@@ -1575,13 +1563,6 @@ static int pl022_unprepare_transfer_hardware(struct spi_master *master) ...@@ -1575,13 +1563,6 @@ static int pl022_unprepare_transfer_hardware(struct spi_master *master)
writew((readw(SSP_CR1(pl022->virtbase)) & writew((readw(SSP_CR1(pl022->virtbase)) &
(~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
if (pl022->master_info->autosuspend_delay > 0) {
pm_runtime_mark_last_busy(&pl022->adev->dev);
pm_runtime_put_autosuspend(&pl022->adev->dev);
} else {
pm_runtime_put(&pl022->adev->dev);
}
return 0; return 0;
} }
...@@ -2091,7 +2072,8 @@ pl022_platform_data_dt_get(struct device *dev) ...@@ -2091,7 +2072,8 @@ pl022_platform_data_dt_get(struct device *dev)
static int pl022_probe(struct amba_device *adev, const struct amba_id *id) static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
{ {
struct device *dev = &adev->dev; struct device *dev = &adev->dev;
struct pl022_ssp_controller *platform_info = adev->dev.platform_data; struct pl022_ssp_controller *platform_info =
dev_get_platdata(&adev->dev);
struct spi_master *master; struct spi_master *master;
struct pl022 *pl022 = NULL; /*Data for this driver */ struct pl022 *pl022 = NULL; /*Data for this driver */
struct device_node *np = adev->dev.of_node; struct device_node *np = adev->dev.of_node;
...@@ -2139,7 +2121,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -2139,7 +2121,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
master->num_chipselect = num_cs; master->num_chipselect = num_cs;
master->cleanup = pl022_cleanup; master->cleanup = pl022_cleanup;
master->setup = pl022_setup; master->setup = pl022_setup;
master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; master->auto_runtime_pm = true;
master->transfer_one_message = pl022_transfer_one_message; master->transfer_one_message = pl022_transfer_one_message;
master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
master->rt = platform_info->rt; master->rt = platform_info->rt;
...@@ -2193,8 +2175,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -2193,8 +2175,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
status = -ENOMEM; status = -ENOMEM;
goto err_no_ioremap; goto err_no_ioremap;
} }
printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", printk(KERN_INFO "pl022: mapped registers from %pa to %p\n",
adev->res.start, pl022->virtbase); &adev->res.start, pl022->virtbase);
pl022->clk = devm_clk_get(&adev->dev, NULL); pl022->clk = devm_clk_get(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) { if (IS_ERR(pl022->clk)) {
......
...@@ -69,6 +69,8 @@ MODULE_ALIAS("platform:pxa2xx-spi"); ...@@ -69,6 +69,8 @@ MODULE_ALIAS("platform:pxa2xx-spi");
#define LPSS_TX_HITHRESH_DFLT 224 #define LPSS_TX_HITHRESH_DFLT 224
/* Offset from drv_data->lpss_base */ /* Offset from drv_data->lpss_base */
#define GENERAL_REG 0x08
#define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24)
#define SSP_REG 0x0c #define SSP_REG 0x0c
#define SPI_CS_CONTROL 0x18 #define SPI_CS_CONTROL 0x18
#define SPI_CS_CONTROL_SW_MODE BIT(0) #define SPI_CS_CONTROL_SW_MODE BIT(0)
...@@ -142,8 +144,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data) ...@@ -142,8 +144,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
__lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value); __lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value);
/* Enable multiblock DMA transfers */ /* Enable multiblock DMA transfers */
if (drv_data->master_info->enable_dma) if (drv_data->master_info->enable_dma) {
__lpss_ssp_write_priv(drv_data, SSP_REG, 1); __lpss_ssp_write_priv(drv_data, SSP_REG, 1);
value = __lpss_ssp_read_priv(drv_data, GENERAL_REG);
value |= GENERAL_REG_RXTO_HOLDOFF_DISABLE;
__lpss_ssp_write_priv(drv_data, GENERAL_REG, value);
}
} }
static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable) static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
...@@ -804,14 +811,6 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master, ...@@ -804,14 +811,6 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master,
return 0; return 0;
} }
static int pxa2xx_spi_prepare_transfer(struct spi_master *master)
{
struct driver_data *drv_data = spi_master_get_devdata(master);
pm_runtime_get_sync(&drv_data->pdev->dev);
return 0;
}
static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) static int pxa2xx_spi_unprepare_transfer(struct spi_master *master)
{ {
struct driver_data *drv_data = spi_master_get_devdata(master); struct driver_data *drv_data = spi_master_get_devdata(master);
...@@ -820,8 +819,6 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) ...@@ -820,8 +819,6 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master)
write_SSCR0(read_SSCR0(drv_data->ioaddr) & ~SSCR0_SSE, write_SSCR0(read_SSCR0(drv_data->ioaddr) & ~SSCR0_SSE,
drv_data->ioaddr); drv_data->ioaddr);
pm_runtime_mark_last_busy(&drv_data->pdev->dev);
pm_runtime_put_autosuspend(&drv_data->pdev->dev);
return 0; return 0;
} }
...@@ -1134,8 +1131,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1134,8 +1131,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
master->cleanup = cleanup; master->cleanup = cleanup;
master->setup = setup; master->setup = setup;
master->transfer_one_message = pxa2xx_spi_transfer_one_message; master->transfer_one_message = pxa2xx_spi_transfer_one_message;
master->prepare_transfer_hardware = pxa2xx_spi_prepare_transfer;
master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer; master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer;
master->auto_runtime_pm = true;
drv_data->ssp_type = ssp->type; drv_data->ssp_type = ssp->type;
drv_data->null_dma_buf = (u32 *)PTR_ALIGN(&drv_data[1], DMA_ALIGNMENT); drv_data->null_dma_buf = (u32 *)PTR_ALIGN(&drv_data[1], DMA_ALIGNMENT);
......
...@@ -564,8 +564,12 @@ static void rspi_work(struct work_struct *work) ...@@ -564,8 +564,12 @@ static void rspi_work(struct work_struct *work)
unsigned long flags; unsigned long flags;
int ret; int ret;
spin_lock_irqsave(&rspi->lock, flags); while (1) {
while (!list_empty(&rspi->queue)) { spin_lock_irqsave(&rspi->lock, flags);
if (list_empty(&rspi->queue)) {
spin_unlock_irqrestore(&rspi->lock, flags);
break;
}
mesg = list_entry(rspi->queue.next, struct spi_message, queue); mesg = list_entry(rspi->queue.next, struct spi_message, queue);
list_del_init(&mesg->queue); list_del_init(&mesg->queue);
spin_unlock_irqrestore(&rspi->lock, flags); spin_unlock_irqrestore(&rspi->lock, flags);
...@@ -595,8 +599,6 @@ static void rspi_work(struct work_struct *work) ...@@ -595,8 +599,6 @@ static void rspi_work(struct work_struct *work)
mesg->status = 0; mesg->status = 0;
mesg->complete(mesg->context); mesg->complete(mesg->context);
spin_lock_irqsave(&rspi->lock, flags);
} }
return; return;
...@@ -664,12 +666,13 @@ static irqreturn_t rspi_irq(int irq, void *_sr) ...@@ -664,12 +666,13 @@ static irqreturn_t rspi_irq(int irq, void *_sr)
static int rspi_request_dma(struct rspi_data *rspi, static int rspi_request_dma(struct rspi_data *rspi,
struct platform_device *pdev) struct platform_device *pdev)
{ {
struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dma_cap_mask_t mask; dma_cap_mask_t mask;
struct dma_slave_config cfg; struct dma_slave_config cfg;
int ret; int ret;
if (!rspi_pd) if (!res || !rspi_pd)
return 0; /* The driver assumes no error. */ return 0; /* The driver assumes no error. */
rspi->dma_width_16bit = rspi_pd->dma_width_16bit; rspi->dma_width_16bit = rspi_pd->dma_width_16bit;
...@@ -683,6 +686,8 @@ static int rspi_request_dma(struct rspi_data *rspi, ...@@ -683,6 +686,8 @@ static int rspi_request_dma(struct rspi_data *rspi,
if (rspi->chan_rx) { if (rspi->chan_rx) {
cfg.slave_id = rspi_pd->dma_rx_id; cfg.slave_id = rspi_pd->dma_rx_id;
cfg.direction = DMA_DEV_TO_MEM; cfg.direction = DMA_DEV_TO_MEM;
cfg.dst_addr = 0;
cfg.src_addr = res->start + RSPI_SPDR;
ret = dmaengine_slave_config(rspi->chan_rx, &cfg); ret = dmaengine_slave_config(rspi->chan_rx, &cfg);
if (!ret) if (!ret)
dev_info(&pdev->dev, "Use DMA when rx.\n"); dev_info(&pdev->dev, "Use DMA when rx.\n");
...@@ -698,6 +703,8 @@ static int rspi_request_dma(struct rspi_data *rspi, ...@@ -698,6 +703,8 @@ static int rspi_request_dma(struct rspi_data *rspi,
if (rspi->chan_tx) { if (rspi->chan_tx) {
cfg.slave_id = rspi_pd->dma_tx_id; cfg.slave_id = rspi_pd->dma_tx_id;
cfg.direction = DMA_MEM_TO_DEV; cfg.direction = DMA_MEM_TO_DEV;
cfg.dst_addr = res->start + RSPI_SPDR;
cfg.src_addr = 0;
ret = dmaengine_slave_config(rspi->chan_tx, &cfg); ret = dmaengine_slave_config(rspi->chan_tx, &cfg);
if (!ret) if (!ret)
dev_info(&pdev->dev, "Use DMA when tx\n"); dev_info(&pdev->dev, "Use DMA when tx\n");
...@@ -719,7 +726,7 @@ static void rspi_release_dma(struct rspi_data *rspi) ...@@ -719,7 +726,7 @@ static void rspi_release_dma(struct rspi_data *rspi)
static int rspi_remove(struct platform_device *pdev) static int rspi_remove(struct platform_device *pdev)
{ {
struct rspi_data *rspi = platform_get_drvdata(pdev); struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev));
spi_unregister_master(rspi->master); spi_unregister_master(rspi->master);
rspi_release_dma(rspi); rspi_release_dma(rspi);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -130,7 +130,7 @@ static int sh_sci_spi_probe(struct platform_device *dev) ...@@ -130,7 +130,7 @@ static int sh_sci_spi_probe(struct platform_device *dev)
sp = spi_master_get_devdata(master); sp = spi_master_get_devdata(master);
platform_set_drvdata(dev, sp); platform_set_drvdata(dev, sp);
sp->info = dev->dev.platform_data; sp->info = dev_get_platdata(&dev->dev);
/* setup spi bitbang adaptor */ /* setup spi bitbang adaptor */
sp->bitbang.master = spi_master_get(master); sp->bitbang.master = spi_master_get(master);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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