diff options
Diffstat (limited to 'drivers/spi')
78 files changed, 7448 insertions, 5134 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b9c53cc40e1..213b5cbb9dc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -91,8 +91,8 @@ config SPI_BFIN5XX  	help  	  This is the SPI controller master driver for Blackfin 5xx processor. -config SPI_BFIN_V3 -	tristate "SPI controller v3 for Blackfin" +config SPI_ADI_V3 +	tristate "SPI controller v3 for ADI"  	depends on BF60x  	help  	  This is the SPI controller v3 master driver @@ -118,6 +118,13 @@ config SPI_BCM63XX  	help            Enable support for the SPI controller on the Broadcom BCM63xx SoCs. +config SPI_BCM63XX_HSSPI +	tristate "Broadcom BCM63XX HS SPI controller driver" +	depends on BCM63XX || COMPILE_TEST +	help +	  This enables support for the High Speed SPI controller present on +	  newer Broadcom BCM63XX SoCs. +  config SPI_BITBANG  	tristate "Utilities for Bitbanging SPI masters"  	help @@ -141,9 +148,16 @@ config SPI_BUTTERFLY  	  inexpensive battery powered microcontroller evaluation board.  	  This same cable can be used to flash new firmware. +config SPI_CADENCE +	tristate "Cadence SPI controller" +	depends on ARM +	help +	  This selects the Cadence SPI controller master driver +	  used by Xilinx Zynq. +  config SPI_CLPS711X  	tristate "CLPS711X host SPI controller" -	depends on ARCH_CLPS711X +	depends on ARCH_CLPS711X || COMPILE_TEST  	help  	  This enables dedicated general purpose SPI/Microwire1-compatible  	  master mode interface (SSI1) for CLPS711X-based CPUs. @@ -159,7 +173,6 @@ config SPI_DAVINCI  	tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"  	depends on ARCH_DAVINCI || ARCH_KEYSTONE  	select SPI_BITBANG -	select TI_EDMA  	help  	  SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules. @@ -206,7 +219,6 @@ config SPI_IMX  	tristate "Freescale i.MX SPI controllers"  	depends on ARCH_MXC || COMPILE_TEST  	select SPI_BITBANG -	default m if IMX_HAVE_PLATFORM_SPI_IMX  	help  	  This enables using the Freescale i.MX SPI controllers in master  	  mode. @@ -264,6 +276,8 @@ config SPI_FSL_SPI  config SPI_FSL_DSPI  	tristate "Freescale DSPI controller"  	select SPI_BITBANG +	select REGMAP_MMIO +	depends on SOC_VF610 || COMPILE_TEST  	help  	  This enables support for the Freescale DSPI controller in master  	  mode. VF610 platform uses the controller. @@ -300,6 +314,7 @@ config SPI_OMAP_UWIRE  config SPI_OMAP24XX  	tristate "McSPI driver for OMAP" +	depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH  	depends on ARCH_OMAP2PLUS || COMPILE_TEST  	help  	  SPI master controller for OMAP24XX and later Multichannel SPI @@ -368,10 +383,23 @@ config SPI_PXA2XX_PCI  	def_tristate SPI_PXA2XX && PCI  config SPI_RSPI -	tristate "Renesas RSPI controller" -	depends on SUPERH && SH_DMAE_BASE +	tristate "Renesas RSPI/QSPI controller" +	depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE +	help +	  SPI driver for Renesas RSPI and QSPI blocks. + +config SPI_QUP +	tristate "Qualcomm SPI controller with QUP interface" +	depends on ARCH_QCOM || (ARM && COMPILE_TEST)  	help -	  SPI driver for Renesas RSPI blocks. +	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that +	  provides a common data path (an output FIFO and an input FIFO) +	  for serial peripheral interface (SPI) mini-core. SPI in master +	  mode supports up to 50MHz, up to four chip selects, programmable +	  data path from 4 bits to 32 bits and numerous protocol variants. + +	  This driver can also be built as a module.  If so, the module +	  will be called spi_qup.  config SPI_S3C24XX  	tristate "Samsung S3C24XX series SPI" @@ -393,8 +421,8 @@ config SPI_S3C24XX_FIQ  config SPI_S3C64XX  	tristate "Samsung S3C64XX series type SPI" -	depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS) -	select S3C64XX_DMA if ARCH_S3C64XX +	depends on PLAT_SAMSUNG +	select S3C64XX_PL080 if ARCH_S3C64XX  	help  	  SPI driver for Samsung S3C64XX and newer SoCs. @@ -406,8 +434,8 @@ config SPI_SC18IS602  config SPI_SH_MSIOF  	tristate "SuperH MSIOF SPI controller" -	depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK -	select SPI_BITBANG +	depends on HAVE_CLK +	depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST  	help  	  SPI driver for SuperH and SH Mobile MSIOF blocks. @@ -437,6 +465,19 @@ config SPI_SIRF  	help  	  SPI driver for CSR SiRFprimaII SoCs +config SPI_SUN4I +	tristate "Allwinner A10 SoCs SPI controller" +	depends on ARCH_SUNXI || COMPILE_TEST +	help +	  SPI driver for Allwinner sun4i, sun5i and sun7i SoCs + +config SPI_SUN6I +	tristate "Allwinner A31 SPI controller" +	depends on ARCH_SUNXI || COMPILE_TEST +	depends on RESET_CONTROLLER +	help +	  This enables using the SPI controller on the Allwinner A31 SoCs. +  config SPI_MXS  	tristate "Freescale MXS SPI controller"  	depends on ARCH_MXS @@ -447,6 +488,7 @@ config SPI_MXS  config SPI_TEGRA114  	tristate "NVIDIA Tegra114 SPI Controller"  	depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST +	depends on RESET_CONTROLLER  	help  	  SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller  	  is different than the older SoCs SPI controller and also register interface @@ -455,6 +497,7 @@ config SPI_TEGRA114  config SPI_TEGRA20_SFLASH  	tristate "Nvidia Tegra20 Serial flash Controller"  	depends on ARCH_TEGRA || COMPILE_TEST +	depends on RESET_CONTROLLER  	help  	  SPI driver for Nvidia Tegra20 Serial flash Controller interface.  	  The main usecase of this controller is to use spi flash as boot @@ -463,19 +506,13 @@ config SPI_TEGRA20_SFLASH  config SPI_TEGRA20_SLINK  	tristate "Nvidia Tegra20/Tegra30 SLINK Controller"  	depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST +	depends on RESET_CONTROLLER  	help  	  SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. -config SPI_TI_SSP -	tristate "TI Sequencer Serial Port - SPI Support" -	depends on MFD_TI_SSP -	help -	  This selects an SPI master implementation using a TI sequencer -	  serial port. -  config SPI_TOPCLIFF_PCH  	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" -	depends on PCI +	depends on PCI && (X86_32 || COMPILE_TEST)  	help  	  SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus  	  used in some x86 embedded processors. @@ -508,6 +545,19 @@ config SPI_XILINX  	  Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)" +config SPI_XTENSA_XTFPGA +	tristate "Xtensa SPI controller for xtfpga" +	depends on (XTENSA && XTENSA_PLATFORM_XTFPGA) || COMPILE_TEST +	select SPI_BITBANG +	help +	  SPI driver for xtfpga SPI master controller. + +	  This simple SPI master controller is built into xtfpga bitstreams +	  and is used to control daughterboard audio codec. It always transfers +	  16 bit words in SPI mode 0, automatically asserting CS on transfer +	  start and deasserting on end. + +  config SPI_NUC900  	tristate "Nuvoton NUC900 series SPI"  	depends on ARCH_W90X900 @@ -534,7 +584,7 @@ config SPI_DW_MID_DMA  config SPI_DW_MMIO  	tristate "Memory-mapped io interface driver for DW SPI core" -	depends on SPI_DESIGNWARE && HAVE_CLK +	depends on SPI_DESIGNWARE  #  # There are lots of SPI device types, with sensors and memory diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ab8d8644af0..929c9f5eac0 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -16,11 +16,13 @@ obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o  obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o  obj-$(CONFIG_SPI_BCM2835)		+= spi-bcm2835.o  obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o +obj-$(CONFIG_SPI_BCM63XX_HSSPI)		+= spi-bcm63xx-hsspi.o  obj-$(CONFIG_SPI_BFIN5XX)		+= spi-bfin5xx.o -obj-$(CONFIG_SPI_BFIN_V3)               += spi-bfin-v3.o +obj-$(CONFIG_SPI_ADI_V3)                += spi-adi-v3.o  obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o  obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o  obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o +obj-$(CONFIG_SPI_CADENCE)		+= spi-cadence.o  obj-$(CONFIG_SPI_CLPS711X)		+= spi-clps711x.o  obj-$(CONFIG_SPI_COLDFIRE_QSPI)		+= spi-coldfire-qspi.o  obj-$(CONFIG_SPI_DAVINCI)		+= spi-davinci.o @@ -58,6 +60,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_PXADMA)	+= spi-pxa2xx-pxadma.o  spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA)	+= spi-pxa2xx-dma.o  obj-$(CONFIG_SPI_PXA2XX)		+= spi-pxa2xx-platform.o  obj-$(CONFIG_SPI_PXA2XX_PCI)		+= spi-pxa2xx-pci.o +obj-$(CONFIG_SPI_QUP)			+= spi-qup.o  obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o  obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o  spi-s3c24xx-hw-y			:= spi-s3c24xx.o @@ -69,12 +72,14 @@ obj-$(CONFIG_SPI_SH_HSPI)		+= spi-sh-hspi.o  obj-$(CONFIG_SPI_SH_MSIOF)		+= spi-sh-msiof.o  obj-$(CONFIG_SPI_SH_SCI)		+= spi-sh-sci.o  obj-$(CONFIG_SPI_SIRF)		+= spi-sirf.o +obj-$(CONFIG_SPI_SUN4I)			+= spi-sun4i.o +obj-$(CONFIG_SPI_SUN6I)			+= spi-sun6i.o  obj-$(CONFIG_SPI_TEGRA114)		+= spi-tegra114.o  obj-$(CONFIG_SPI_TEGRA20_SFLASH)	+= spi-tegra20-sflash.o  obj-$(CONFIG_SPI_TEGRA20_SLINK)		+= spi-tegra20-slink.o -obj-$(CONFIG_SPI_TI_SSP)		+= spi-ti-ssp.o  obj-$(CONFIG_SPI_TLE62X0)		+= spi-tle62x0.o  obj-$(CONFIG_SPI_TOPCLIFF_PCH)		+= spi-topcliff-pch.o  obj-$(CONFIG_SPI_TXX9)			+= spi-txx9.o  obj-$(CONFIG_SPI_XCOMM)		+= spi-xcomm.o  obj-$(CONFIG_SPI_XILINX)		+= spi-xilinx.o +obj-$(CONFIG_SPI_XTENSA_XTFPGA)		+= spi-xtensa-xtfpga.o diff --git a/drivers/spi/spi-bfin-v3.c b/drivers/spi/spi-adi-v3.c index f4bf81347d6..dcb2287c7f8 100644 --- a/drivers/spi/spi-bfin-v3.c +++ b/drivers/spi/spi-adi-v3.c @@ -1,7 +1,7 @@  /*   * Analog Devices SPI3 controller driver   * - * Copyright (c) 2013 Analog Devices Inc. + * Copyright (c) 2014 Analog Devices Inc.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 as @@ -13,6 +13,7 @@   * GNU General Public License for more details.   */ +#include <linux/clk.h>  #include <linux/delay.h>  #include <linux/device.h>  #include <linux/dma-mapping.h> @@ -26,35 +27,34 @@  #include <linux/platform_device.h>  #include <linux/slab.h>  #include <linux/spi/spi.h> +#include <linux/spi/adi_spi3.h>  #include <linux/types.h> -#include <asm/bfin_spi3.h> -#include <asm/cacheflush.h>  #include <asm/dma.h>  #include <asm/portmux.h> -enum bfin_spi_state { +enum adi_spi_state {  	START_STATE,  	RUNNING_STATE,  	DONE_STATE,  	ERROR_STATE  }; -struct bfin_spi_master; +struct adi_spi_master; -struct bfin_spi_transfer_ops { -	void (*write) (struct bfin_spi_master *); -	void (*read) (struct bfin_spi_master *); -	void (*duplex) (struct bfin_spi_master *); +struct adi_spi_transfer_ops { +	void (*write) (struct adi_spi_master *); +	void (*read) (struct adi_spi_master *); +	void (*duplex) (struct adi_spi_master *);  };  /* runtime info for spi master */ -struct bfin_spi_master { +struct adi_spi_master {  	/* SPI framework hookup */  	struct spi_master *master;  	/* Regs base of SPI controller */ -	struct bfin_spi_regs __iomem *regs; +	struct adi_spi_regs __iomem *regs;  	/* Pin request list */  	u16 *pin_req; @@ -65,7 +65,7 @@ struct bfin_spi_master {  	/* Current message transfer state info */  	struct spi_message *cur_msg;  	struct spi_transfer *cur_transfer; -	struct bfin_spi_device *cur_chip; +	struct adi_spi_device *cur_chip;  	unsigned transfer_len;  	/* transfer buffer */ @@ -90,12 +90,12 @@ struct bfin_spi_master {  	u32 ssel;  	unsigned long sclk; -	enum bfin_spi_state state; +	enum adi_spi_state state; -	const struct bfin_spi_transfer_ops *ops; +	const struct adi_spi_transfer_ops *ops;  }; -struct bfin_spi_device { +struct adi_spi_device {  	u32 control;  	u32 clock;  	u32 ssel; @@ -105,17 +105,25 @@ struct bfin_spi_device {  	u32 cs_gpio;  	u32 tx_dummy_val; /* tx value for rx only transfer */  	bool enable_dma; -	const struct bfin_spi_transfer_ops *ops; +	const struct adi_spi_transfer_ops *ops;  }; -static void bfin_spi_enable(struct bfin_spi_master *drv_data) +static void adi_spi_enable(struct adi_spi_master *drv_data)  { -	bfin_write_or(&drv_data->regs->control, SPI_CTL_EN); +	u32 ctl; + +	ctl = ioread32(&drv_data->regs->control); +	ctl |= SPI_CTL_EN; +	iowrite32(ctl, &drv_data->regs->control);  } -static void bfin_spi_disable(struct bfin_spi_master *drv_data) +static void adi_spi_disable(struct adi_spi_master *drv_data)  { -	bfin_write_and(&drv_data->regs->control, ~SPI_CTL_EN); +	u32 ctl; + +	ctl = ioread32(&drv_data->regs->control); +	ctl &= ~SPI_CTL_EN; +	iowrite32(ctl, &drv_data->regs->control);  }  /* Caculate the SPI_CLOCK register value based on input HZ */ @@ -128,35 +136,43 @@ static u32 hz_to_spi_clock(u32 sclk, u32 speed_hz)  	return spi_clock;  } -static int bfin_spi_flush(struct bfin_spi_master *drv_data) +static int adi_spi_flush(struct adi_spi_master *drv_data)  {  	unsigned long limit = loops_per_jiffy << 1;  	/* wait for stop and clear stat */ -	while (!(bfin_read(&drv_data->regs->status) & SPI_STAT_SPIF) && --limit) +	while (!(ioread32(&drv_data->regs->status) & SPI_STAT_SPIF) && --limit)  		cpu_relax(); -	bfin_write(&drv_data->regs->status, 0xFFFFFFFF); +	iowrite32(0xFFFFFFFF, &drv_data->regs->status);  	return limit;  }  /* Chip select operation functions for cs_change flag */ -static void bfin_spi_cs_active(struct bfin_spi_master *drv_data, struct bfin_spi_device *chip) +static void adi_spi_cs_active(struct adi_spi_master *drv_data, struct adi_spi_device *chip)  { -	if (likely(chip->cs < MAX_CTRL_CS)) -		bfin_write_and(&drv_data->regs->ssel, ~chip->ssel); -	else +	if (likely(chip->cs < MAX_CTRL_CS)) { +		u32 reg; +		reg = ioread32(&drv_data->regs->ssel); +		reg &= ~chip->ssel; +		iowrite32(reg, &drv_data->regs->ssel); +	} else {  		gpio_set_value(chip->cs_gpio, 0); +	}  } -static void bfin_spi_cs_deactive(struct bfin_spi_master *drv_data, -				struct bfin_spi_device *chip) +static void adi_spi_cs_deactive(struct adi_spi_master *drv_data, +				struct adi_spi_device *chip)  { -	if (likely(chip->cs < MAX_CTRL_CS)) -		bfin_write_or(&drv_data->regs->ssel, chip->ssel); -	else +	if (likely(chip->cs < MAX_CTRL_CS)) { +		u32 reg; +		reg = ioread32(&drv_data->regs->ssel); +		reg |= chip->ssel; +		iowrite32(reg, &drv_data->regs->ssel); +	} else {  		gpio_set_value(chip->cs_gpio, 1); +	}  	/* Move delay here for consistency */  	if (chip->cs_chg_udelay) @@ -164,187 +180,192 @@ static void bfin_spi_cs_deactive(struct bfin_spi_master *drv_data,  }  /* enable or disable the pin muxed by GPIO and SPI CS to work as SPI CS */ -static inline void bfin_spi_cs_enable(struct bfin_spi_master *drv_data, -					struct bfin_spi_device *chip) +static inline void adi_spi_cs_enable(struct adi_spi_master *drv_data, +					struct adi_spi_device *chip)  { -	if (chip->cs < MAX_CTRL_CS) -		bfin_write_or(&drv_data->regs->ssel, chip->ssel >> 8); +	if (chip->cs < MAX_CTRL_CS) { +		u32 reg; +		reg = ioread32(&drv_data->regs->ssel); +		reg |= chip->ssel >> 8; +		iowrite32(reg, &drv_data->regs->ssel); +	}  } -static inline void bfin_spi_cs_disable(struct bfin_spi_master *drv_data, -					struct bfin_spi_device *chip) +static inline void adi_spi_cs_disable(struct adi_spi_master *drv_data, +					struct adi_spi_device *chip)  { -	if (chip->cs < MAX_CTRL_CS) -		bfin_write_and(&drv_data->regs->ssel, ~(chip->ssel >> 8)); +	if (chip->cs < MAX_CTRL_CS) { +		u32 reg; +		reg = ioread32(&drv_data->regs->ssel); +		reg &= ~(chip->ssel >> 8); +		iowrite32(reg, &drv_data->regs->ssel); +	}  }  /* stop controller and re-config current chip*/ -static void bfin_spi_restore_state(struct bfin_spi_master *drv_data) +static void adi_spi_restore_state(struct adi_spi_master *drv_data)  { -	struct bfin_spi_device *chip = drv_data->cur_chip; +	struct adi_spi_device *chip = drv_data->cur_chip;  	/* Clear status and disable clock */ -	bfin_write(&drv_data->regs->status, 0xFFFFFFFF); -	bfin_write(&drv_data->regs->rx_control, 0x0); -	bfin_write(&drv_data->regs->tx_control, 0x0); -	bfin_spi_disable(drv_data); - -	SSYNC(); +	iowrite32(0xFFFFFFFF, &drv_data->regs->status); +	iowrite32(0x0, &drv_data->regs->rx_control); +	iowrite32(0x0, &drv_data->regs->tx_control); +	adi_spi_disable(drv_data);  	/* Load the registers */ -	bfin_write(&drv_data->regs->control, chip->control); -	bfin_write(&drv_data->regs->clock, chip->clock); +	iowrite32(chip->control, &drv_data->regs->control); +	iowrite32(chip->clock, &drv_data->regs->clock); -	bfin_spi_enable(drv_data); +	adi_spi_enable(drv_data);  	drv_data->tx_num = drv_data->rx_num = 0;  	/* we always choose tx transfer initiate */ -	bfin_write(&drv_data->regs->rx_control, SPI_RXCTL_REN); -	bfin_write(&drv_data->regs->tx_control, -			SPI_TXCTL_TEN | SPI_TXCTL_TTI); -	bfin_spi_cs_active(drv_data, chip); +	iowrite32(SPI_RXCTL_REN, &drv_data->regs->rx_control); +	iowrite32(SPI_TXCTL_TEN | SPI_TXCTL_TTI, &drv_data->regs->tx_control); +	adi_spi_cs_active(drv_data, chip);  }  /* discard invalid rx data and empty rfifo */ -static inline void dummy_read(struct bfin_spi_master *drv_data) +static inline void dummy_read(struct adi_spi_master *drv_data)  { -	while (!(bfin_read(&drv_data->regs->status) & SPI_STAT_RFE)) -		bfin_read(&drv_data->regs->rfifo); +	while (!(ioread32(&drv_data->regs->status) & SPI_STAT_RFE)) +		ioread32(&drv_data->regs->rfifo);  } -static void bfin_spi_u8_write(struct bfin_spi_master *drv_data) +static void adi_spi_u8_write(struct adi_spi_master *drv_data)  {  	dummy_read(drv_data);  	while (drv_data->tx < drv_data->tx_end) { -		bfin_write(&drv_data->regs->tfifo, (*(u8 *)(drv_data->tx++))); -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		iowrite32(*(u8 *)(drv_data->tx++), &drv_data->regs->tfifo); +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		bfin_read(&drv_data->regs->rfifo); +		ioread32(&drv_data->regs->rfifo);  	}  } -static void bfin_spi_u8_read(struct bfin_spi_master *drv_data) +static void adi_spi_u8_read(struct adi_spi_master *drv_data)  {  	u32 tx_val = drv_data->cur_chip->tx_dummy_val;  	dummy_read(drv_data);  	while (drv_data->rx < drv_data->rx_end) { -		bfin_write(&drv_data->regs->tfifo, tx_val); -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		iowrite32(tx_val, &drv_data->regs->tfifo); +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		*(u8 *)(drv_data->rx++) = bfin_read(&drv_data->regs->rfifo); +		*(u8 *)(drv_data->rx++) = ioread32(&drv_data->regs->rfifo);  	}  } -static void bfin_spi_u8_duplex(struct bfin_spi_master *drv_data) +static void adi_spi_u8_duplex(struct adi_spi_master *drv_data)  {  	dummy_read(drv_data);  	while (drv_data->rx < drv_data->rx_end) { -		bfin_write(&drv_data->regs->tfifo, (*(u8 *)(drv_data->tx++))); -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		iowrite32(*(u8 *)(drv_data->tx++), &drv_data->regs->tfifo); +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		*(u8 *)(drv_data->rx++) = bfin_read(&drv_data->regs->rfifo); +		*(u8 *)(drv_data->rx++) = ioread32(&drv_data->regs->rfifo);  	}  } -static const struct bfin_spi_transfer_ops bfin_bfin_spi_transfer_ops_u8 = { -	.write  = bfin_spi_u8_write, -	.read   = bfin_spi_u8_read, -	.duplex = bfin_spi_u8_duplex, +static const struct adi_spi_transfer_ops adi_spi_transfer_ops_u8 = { +	.write  = adi_spi_u8_write, +	.read   = adi_spi_u8_read, +	.duplex = adi_spi_u8_duplex,  }; -static void bfin_spi_u16_write(struct bfin_spi_master *drv_data) +static void adi_spi_u16_write(struct adi_spi_master *drv_data)  {  	dummy_read(drv_data);  	while (drv_data->tx < drv_data->tx_end) { -		bfin_write(&drv_data->regs->tfifo, (*(u16 *)drv_data->tx)); +		iowrite32(*(u16 *)drv_data->tx, &drv_data->regs->tfifo);  		drv_data->tx += 2; -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		bfin_read(&drv_data->regs->rfifo); +		ioread32(&drv_data->regs->rfifo);  	}  } -static void bfin_spi_u16_read(struct bfin_spi_master *drv_data) +static void adi_spi_u16_read(struct adi_spi_master *drv_data)  {  	u32 tx_val = drv_data->cur_chip->tx_dummy_val;  	dummy_read(drv_data);  	while (drv_data->rx < drv_data->rx_end) { -		bfin_write(&drv_data->regs->tfifo, tx_val); -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		iowrite32(tx_val, &drv_data->regs->tfifo); +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		*(u16 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); +		*(u16 *)drv_data->rx = ioread32(&drv_data->regs->rfifo);  		drv_data->rx += 2;  	}  } -static void bfin_spi_u16_duplex(struct bfin_spi_master *drv_data) +static void adi_spi_u16_duplex(struct adi_spi_master *drv_data)  {  	dummy_read(drv_data);  	while (drv_data->rx < drv_data->rx_end) { -		bfin_write(&drv_data->regs->tfifo, (*(u16 *)drv_data->tx)); +		iowrite32(*(u16 *)drv_data->tx, &drv_data->regs->tfifo);  		drv_data->tx += 2; -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		*(u16 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); +		*(u16 *)drv_data->rx = ioread32(&drv_data->regs->rfifo);  		drv_data->rx += 2;  	}  } -static const struct bfin_spi_transfer_ops bfin_bfin_spi_transfer_ops_u16 = { -	.write  = bfin_spi_u16_write, -	.read   = bfin_spi_u16_read, -	.duplex = bfin_spi_u16_duplex, +static const struct adi_spi_transfer_ops adi_spi_transfer_ops_u16 = { +	.write  = adi_spi_u16_write, +	.read   = adi_spi_u16_read, +	.duplex = adi_spi_u16_duplex,  }; -static void bfin_spi_u32_write(struct bfin_spi_master *drv_data) +static void adi_spi_u32_write(struct adi_spi_master *drv_data)  {  	dummy_read(drv_data);  	while (drv_data->tx < drv_data->tx_end) { -		bfin_write(&drv_data->regs->tfifo, (*(u32 *)drv_data->tx)); +		iowrite32(*(u32 *)drv_data->tx, &drv_data->regs->tfifo);  		drv_data->tx += 4; -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		bfin_read(&drv_data->regs->rfifo); +		ioread32(&drv_data->regs->rfifo);  	}  } -static void bfin_spi_u32_read(struct bfin_spi_master *drv_data) +static void adi_spi_u32_read(struct adi_spi_master *drv_data)  {  	u32 tx_val = drv_data->cur_chip->tx_dummy_val;  	dummy_read(drv_data);  	while (drv_data->rx < drv_data->rx_end) { -		bfin_write(&drv_data->regs->tfifo, tx_val); -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		iowrite32(tx_val, &drv_data->regs->tfifo); +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		*(u32 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); +		*(u32 *)drv_data->rx = ioread32(&drv_data->regs->rfifo);  		drv_data->rx += 4;  	}  } -static void bfin_spi_u32_duplex(struct bfin_spi_master *drv_data) +static void adi_spi_u32_duplex(struct adi_spi_master *drv_data)  {  	dummy_read(drv_data);  	while (drv_data->rx < drv_data->rx_end) { -		bfin_write(&drv_data->regs->tfifo, (*(u32 *)drv_data->tx)); +		iowrite32(*(u32 *)drv_data->tx, &drv_data->regs->tfifo);  		drv_data->tx += 4; -		while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) +		while (ioread32(&drv_data->regs->status) & SPI_STAT_RFE)  			cpu_relax(); -		*(u32 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); +		*(u32 *)drv_data->rx = ioread32(&drv_data->regs->rfifo);  		drv_data->rx += 4;  	}  } -static const struct bfin_spi_transfer_ops bfin_bfin_spi_transfer_ops_u32 = { -	.write  = bfin_spi_u32_write, -	.read   = bfin_spi_u32_read, -	.duplex = bfin_spi_u32_duplex, +static const struct adi_spi_transfer_ops adi_spi_transfer_ops_u32 = { +	.write  = adi_spi_u32_write, +	.read   = adi_spi_u32_read, +	.duplex = adi_spi_u32_duplex,  };  /* test if there is more transfer to be done */ -static void bfin_spi_next_transfer(struct bfin_spi_master *drv) +static void adi_spi_next_transfer(struct adi_spi_master *drv)  {  	struct spi_message *msg = drv->cur_msg;  	struct spi_transfer *t = drv->cur_transfer; @@ -360,15 +381,15 @@ static void bfin_spi_next_transfer(struct bfin_spi_master *drv)  	}  } -static void bfin_spi_giveback(struct bfin_spi_master *drv_data) +static void adi_spi_giveback(struct adi_spi_master *drv_data)  { -	struct bfin_spi_device *chip = drv_data->cur_chip; +	struct adi_spi_device *chip = drv_data->cur_chip; -	bfin_spi_cs_deactive(drv_data, chip); +	adi_spi_cs_deactive(drv_data, chip);  	spi_finalize_current_message(drv_data->master);  } -static int bfin_spi_setup_transfer(struct bfin_spi_master *drv) +static int adi_spi_setup_transfer(struct adi_spi_master *drv)  {  	struct spi_transfer *t = drv->cur_transfer;  	u32 cr, cr_width; @@ -393,34 +414,33 @@ static int bfin_spi_setup_transfer(struct bfin_spi_master *drv)  	switch (t->bits_per_word) {  	case 8:  		cr_width = SPI_CTL_SIZE08; -		drv->ops = &bfin_bfin_spi_transfer_ops_u8; +		drv->ops = &adi_spi_transfer_ops_u8;  		break;  	case 16:  		cr_width = SPI_CTL_SIZE16; -		drv->ops = &bfin_bfin_spi_transfer_ops_u16; +		drv->ops = &adi_spi_transfer_ops_u16;  		break;  	case 32:  		cr_width = SPI_CTL_SIZE32; -		drv->ops = &bfin_bfin_spi_transfer_ops_u32; +		drv->ops = &adi_spi_transfer_ops_u32;  		break;  	default:  		return -EINVAL;  	} -	cr = bfin_read(&drv->regs->control) & ~SPI_CTL_SIZE; +	cr = ioread32(&drv->regs->control) & ~SPI_CTL_SIZE;  	cr |= cr_width; -	bfin_write(&drv->regs->control, cr); +	iowrite32(cr, &drv->regs->control);  	/* speed setup */ -	bfin_write(&drv->regs->clock, -			hz_to_spi_clock(drv->sclk, t->speed_hz)); +	iowrite32(hz_to_spi_clock(drv->sclk, t->speed_hz), &drv->regs->clock);  	return 0;  } -static int bfin_spi_dma_xfer(struct bfin_spi_master *drv_data) +static int adi_spi_dma_xfer(struct adi_spi_master *drv_data)  {  	struct spi_transfer *t = drv_data->cur_transfer;  	struct spi_message *msg = drv_data->cur_msg; -	struct bfin_spi_device *chip = drv_data->cur_chip; +	struct adi_spi_device *chip = drv_data->cur_chip;  	u32 dma_config;  	unsigned long word_count, word_size;  	void *tx_buf, *rx_buf; @@ -498,17 +518,16 @@ static int bfin_spi_dma_xfer(struct bfin_spi_master *drv_data)  	set_dma_config(drv_data->rx_dma, dma_config | WNR);  	enable_dma(drv_data->tx_dma);  	enable_dma(drv_data->rx_dma); -	SSYNC(); -	bfin_write(&drv_data->regs->rx_control, SPI_RXCTL_REN | SPI_RXCTL_RDR_NE); -	SSYNC(); -	bfin_write(&drv_data->regs->tx_control, -			SPI_TXCTL_TEN | SPI_TXCTL_TTI | SPI_TXCTL_TDR_NF); +	iowrite32(SPI_RXCTL_REN | SPI_RXCTL_RDR_NE, +			&drv_data->regs->rx_control); +	iowrite32(SPI_TXCTL_TEN | SPI_TXCTL_TTI | SPI_TXCTL_TDR_NF, +			&drv_data->regs->tx_control);  	return 0;  } -static int bfin_spi_pio_xfer(struct bfin_spi_master *drv_data) +static int adi_spi_pio_xfer(struct adi_spi_master *drv_data)  {  	struct spi_message *msg = drv_data->cur_msg; @@ -529,19 +548,19 @@ static int bfin_spi_pio_xfer(struct bfin_spi_master *drv_data)  			return -EIO;  	} -	if (!bfin_spi_flush(drv_data)) +	if (!adi_spi_flush(drv_data))  		return -EIO;  	msg->actual_length += drv_data->transfer_len;  	tasklet_schedule(&drv_data->pump_transfers);  	return 0;  } -static void bfin_spi_pump_transfers(unsigned long data) +static void adi_spi_pump_transfers(unsigned long data)  { -	struct bfin_spi_master *drv_data = (struct bfin_spi_master *)data; +	struct adi_spi_master *drv_data = (struct adi_spi_master *)data;  	struct spi_message *msg = NULL;  	struct spi_transfer *t = NULL; -	struct bfin_spi_device *chip = NULL; +	struct adi_spi_device *chip = NULL;  	int ret;  	/* Get current state information */ @@ -552,7 +571,7 @@ static void bfin_spi_pump_transfers(unsigned long data)  	/* Handle for abort */  	if (drv_data->state == ERROR_STATE) {  		msg->status = -EIO; -		bfin_spi_giveback(drv_data); +		adi_spi_giveback(drv_data);  		return;  	} @@ -560,14 +579,14 @@ static void bfin_spi_pump_transfers(unsigned long data)  		if (t->delay_usecs)  			udelay(t->delay_usecs);  		if (t->cs_change) -			bfin_spi_cs_deactive(drv_data, chip); -		bfin_spi_next_transfer(drv_data); +			adi_spi_cs_deactive(drv_data, chip); +		adi_spi_next_transfer(drv_data);  		t = drv_data->cur_transfer;  	}  	/* Handle end of message */  	if (drv_data->state == DONE_STATE) {  		msg->status = 0; -		bfin_spi_giveback(drv_data); +		adi_spi_giveback(drv_data);  		return;  	} @@ -577,34 +596,34 @@ static void bfin_spi_pump_transfers(unsigned long data)  		return;  	} -	ret = bfin_spi_setup_transfer(drv_data); +	ret = adi_spi_setup_transfer(drv_data);  	if (ret) {  		msg->status = ret; -		bfin_spi_giveback(drv_data); +		adi_spi_giveback(drv_data);  	} -	bfin_write(&drv_data->regs->status, 0xFFFFFFFF); -	bfin_spi_cs_active(drv_data, chip); +	iowrite32(0xFFFFFFFF, &drv_data->regs->status); +	adi_spi_cs_active(drv_data, chip);  	drv_data->state = RUNNING_STATE;  	if (chip->enable_dma) -		ret = bfin_spi_dma_xfer(drv_data); +		ret = adi_spi_dma_xfer(drv_data);  	else -		ret = bfin_spi_pio_xfer(drv_data); +		ret = adi_spi_pio_xfer(drv_data);  	if (ret) {  		msg->status = ret; -		bfin_spi_giveback(drv_data); +		adi_spi_giveback(drv_data);  	}  } -static int bfin_spi_transfer_one_message(struct spi_master *master, +static int adi_spi_transfer_one_message(struct spi_master *master,  					struct spi_message *m)  { -	struct bfin_spi_master *drv_data = spi_master_get_devdata(master); +	struct adi_spi_master *drv_data = spi_master_get_devdata(master);  	drv_data->cur_msg = m;  	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); -	bfin_spi_restore_state(drv_data); +	adi_spi_restore_state(drv_data);  	drv_data->state = START_STATE;  	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, @@ -630,15 +649,15 @@ static const u16 ssel[][MAX_SPI_SSEL] = {  	P_SPI2_SSEL6, P_SPI2_SSEL7},  }; -static int bfin_spi_setup(struct spi_device *spi) +static int adi_spi_setup(struct spi_device *spi)  { -	struct bfin_spi_master *drv_data = spi_master_get_devdata(spi->master); -	struct bfin_spi_device *chip = spi_get_ctldata(spi); -	u32 bfin_ctl_reg = SPI_CTL_ODM | SPI_CTL_PSSE; +	struct adi_spi_master *drv_data = spi_master_get_devdata(spi->master); +	struct adi_spi_device *chip = spi_get_ctldata(spi); +	u32 ctl_reg = SPI_CTL_ODM | SPI_CTL_PSSE;  	int ret = -EINVAL;  	if (!chip) { -		struct bfin_spi3_chip *chip_info = spi->controller_data; +		struct adi_spi3_chip *chip_info = spi->controller_data;  		chip = kzalloc(sizeof(*chip), GFP_KERNEL);  		if (!chip) { @@ -646,7 +665,7 @@ static int bfin_spi_setup(struct spi_device *spi)  			return -ENOMEM;  		}  		if (chip_info) { -			if (chip_info->control & ~bfin_ctl_reg) { +			if (chip_info->control & ~ctl_reg) {  				dev_err(&spi->dev,  					"do not set bits that the SPI framework manages\n");  				goto error; @@ -657,6 +676,7 @@ static int bfin_spi_setup(struct spi_device *spi)  			chip->enable_dma = chip_info->enable_dma;  		}  		chip->cs = spi->chip_select; +  		if (chip->cs < MAX_CTRL_CS) {  			chip->ssel = (1 << chip->cs) << 8;  			ret = peripheral_request(ssel[spi->master->bus_num] @@ -678,7 +698,7 @@ static int bfin_spi_setup(struct spi_device *spi)  	}  	/* force a default base state */ -	chip->control &= bfin_ctl_reg; +	chip->control &= ctl_reg;  	if (spi->mode & SPI_CPOL)  		chip->control |= SPI_CTL_CPOL; @@ -692,8 +712,8 @@ static int bfin_spi_setup(struct spi_device *spi)  	chip->clock = hz_to_spi_clock(drv_data->sclk, spi->max_speed_hz); -	bfin_spi_cs_enable(drv_data, chip); -	bfin_spi_cs_deactive(drv_data, chip); +	adi_spi_cs_enable(drv_data, chip); +	adi_spi_cs_deactive(drv_data, chip);  	return 0;  error: @@ -705,10 +725,10 @@ error:  	return ret;  } -static void bfin_spi_cleanup(struct spi_device *spi) +static void adi_spi_cleanup(struct spi_device *spi)  { -	struct bfin_spi_device *chip = spi_get_ctldata(spi); -	struct bfin_spi_master *drv_data = spi_master_get_devdata(spi->master); +	struct adi_spi_device *chip = spi_get_ctldata(spi); +	struct adi_spi_master *drv_data = spi_master_get_devdata(spi->master);  	if (!chip)  		return; @@ -716,7 +736,7 @@ static void bfin_spi_cleanup(struct spi_device *spi)  	if (chip->cs < MAX_CTRL_CS) {  		peripheral_free(ssel[spi->master->bus_num]  					[chip->cs-1]); -		bfin_spi_cs_disable(drv_data, chip); +		adi_spi_cs_disable(drv_data, chip);  	} else {  		gpio_free(chip->cs_gpio);  	} @@ -725,10 +745,11 @@ static void bfin_spi_cleanup(struct spi_device *spi)  	spi_set_ctldata(spi, NULL);  } -static irqreturn_t bfin_spi_tx_dma_isr(int irq, void *dev_id) +static irqreturn_t adi_spi_tx_dma_isr(int irq, void *dev_id)  { -	struct bfin_spi_master *drv_data = dev_id; +	struct adi_spi_master *drv_data = dev_id;  	u32 dma_stat = get_dma_curr_irqstat(drv_data->tx_dma); +	u32 tx_ctl;  	clear_dma_irqstat(drv_data->tx_dma);  	if (dma_stat & DMA_DONE) { @@ -739,13 +760,15 @@ static irqreturn_t bfin_spi_tx_dma_isr(int irq, void *dev_id)  		if (drv_data->tx)  			drv_data->state = ERROR_STATE;  	} -	bfin_write_and(&drv_data->regs->tx_control, ~SPI_TXCTL_TDR_NF); +	tx_ctl = ioread32(&drv_data->regs->tx_control); +	tx_ctl &= ~SPI_TXCTL_TDR_NF; +	iowrite32(tx_ctl, &drv_data->regs->tx_control);  	return IRQ_HANDLED;  } -static irqreturn_t bfin_spi_rx_dma_isr(int irq, void *dev_id) +static irqreturn_t adi_spi_rx_dma_isr(int irq, void *dev_id)  { -	struct bfin_spi_master *drv_data = dev_id; +	struct adi_spi_master *drv_data = dev_id;  	struct spi_message *msg = drv_data->cur_msg;  	u32 dma_stat = get_dma_curr_irqstat(drv_data->rx_dma); @@ -760,8 +783,8 @@ static irqreturn_t bfin_spi_rx_dma_isr(int irq, void *dev_id)  		dev_err(&drv_data->master->dev,  				"spi rx dma error: %d\n", dma_stat);  	} -	bfin_write(&drv_data->regs->tx_control, 0); -	bfin_write(&drv_data->regs->rx_control, 0); +	iowrite32(0, &drv_data->regs->tx_control); +	iowrite32(0, &drv_data->regs->rx_control);  	if (drv_data->rx_num != drv_data->tx_num)  		dev_dbg(&drv_data->master->dev,  				"dma interrupt missing: tx=%d,rx=%d\n", @@ -770,15 +793,15 @@ static irqreturn_t bfin_spi_rx_dma_isr(int irq, void *dev_id)  	return IRQ_HANDLED;  } -static int bfin_spi_probe(struct platform_device *pdev) +static int adi_spi_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; -	struct bfin_spi3_master *info = dev_get_platdata(dev); +	struct adi_spi3_master *info = dev_get_platdata(dev);  	struct spi_master *master; -	struct bfin_spi_master *drv_data; +	struct adi_spi_master *drv_data;  	struct resource *mem, *res;  	unsigned int tx_dma, rx_dma; -	unsigned long sclk; +	struct clk *sclk;  	int ret;  	if (!info) { @@ -786,10 +809,10 @@ static int bfin_spi_probe(struct platform_device *pdev)  		return -ENODEV;  	} -	sclk = get_sclk1(); -	if (!sclk) { -		dev_err(dev, "can not get sclk1\n"); -		return -ENXIO; +	sclk = devm_clk_get(dev, "spi"); +	if (IS_ERR(sclk)) { +		dev_err(dev, "can not get spi clock\n"); +		return PTR_ERR(sclk);  	}  	res = platform_get_resource(pdev, IORESOURCE_DMA, 0); @@ -819,17 +842,18 @@ static int bfin_spi_probe(struct platform_device *pdev)  	master->bus_num = pdev->id;  	master->num_chipselect = info->num_chipselect; -	master->cleanup = bfin_spi_cleanup; -	master->setup = bfin_spi_setup; -	master->transfer_one_message = bfin_spi_transfer_one_message; -	master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1); +	master->cleanup = adi_spi_cleanup; +	master->setup = adi_spi_setup; +	master->transfer_one_message = adi_spi_transfer_one_message; +	master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | +				     SPI_BPW_MASK(8);  	drv_data = spi_master_get_devdata(master);  	drv_data->master = master;  	drv_data->tx_dma = tx_dma;  	drv_data->rx_dma = rx_dma;  	drv_data->pin_req = info->pin_req; -	drv_data->sclk = sclk; +	drv_data->sclk = clk_get_rate(sclk);  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	drv_data->regs = devm_ioremap_resource(dev, mem); @@ -844,30 +868,30 @@ static int bfin_spi_probe(struct platform_device *pdev)  		dev_err(dev, "can not request SPI TX DMA channel\n");  		goto err_put_master;  	} -	set_dma_callback(tx_dma, bfin_spi_tx_dma_isr, drv_data); +	set_dma_callback(tx_dma, adi_spi_tx_dma_isr, drv_data);  	ret = request_dma(rx_dma, "SPI_RX_DMA");  	if (ret) {  		dev_err(dev, "can not request SPI RX DMA channel\n");  		goto err_free_tx_dma;  	} -	set_dma_callback(drv_data->rx_dma, bfin_spi_rx_dma_isr, drv_data); +	set_dma_callback(drv_data->rx_dma, adi_spi_rx_dma_isr, drv_data);  	/* request CLK, MOSI and MISO */ -	ret = peripheral_request_list(drv_data->pin_req, "bfin-spi3"); +	ret = peripheral_request_list(drv_data->pin_req, "adi-spi3");  	if (ret < 0) {  		dev_err(dev, "can not request spi pins\n");  		goto err_free_rx_dma;  	} -	bfin_write(&drv_data->regs->control, SPI_CTL_MSTR | SPI_CTL_CPHA); -	bfin_write(&drv_data->regs->ssel, 0x0000FE00); -	bfin_write(&drv_data->regs->delay, 0x0); +	iowrite32(SPI_CTL_MSTR | SPI_CTL_CPHA, &drv_data->regs->control); +	iowrite32(0x0000FE00, &drv_data->regs->ssel); +	iowrite32(0x0, &drv_data->regs->delay);  	tasklet_init(&drv_data->pump_transfers, -			bfin_spi_pump_transfers, (unsigned long)drv_data); +			adi_spi_pump_transfers, (unsigned long)drv_data);  	/* register with the SPI framework */ -	ret = spi_register_master(master); +	ret = devm_spi_register_master(dev, master);  	if (ret) {  		dev_err(dev, "can not  register spi master\n");  		goto err_free_peripheral; @@ -887,44 +911,41 @@ err_put_master:  	return ret;  } -static int bfin_spi_remove(struct platform_device *pdev) +static int adi_spi_remove(struct platform_device *pdev)  {  	struct spi_master *master = platform_get_drvdata(pdev); -	struct bfin_spi_master *drv_data = spi_master_get_devdata(master); - -	bfin_spi_disable(drv_data); +	struct adi_spi_master *drv_data = spi_master_get_devdata(master); +	adi_spi_disable(drv_data);  	peripheral_free_list(drv_data->pin_req);  	free_dma(drv_data->rx_dma);  	free_dma(drv_data->tx_dma); - -	spi_unregister_master(drv_data->master);  	return 0;  }  #ifdef CONFIG_PM -static int bfin_spi_suspend(struct device *dev) +static int adi_spi_suspend(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev); -	struct bfin_spi_master *drv_data = spi_master_get_devdata(master); +	struct adi_spi_master *drv_data = spi_master_get_devdata(master);  	spi_master_suspend(master); -	drv_data->control = bfin_read(&drv_data->regs->control); -	drv_data->ssel = bfin_read(&drv_data->regs->ssel); +	drv_data->control = ioread32(&drv_data->regs->control); +	drv_data->ssel = ioread32(&drv_data->regs->ssel); -	bfin_write(&drv_data->regs->control, SPI_CTL_MSTR | SPI_CTL_CPHA); -	bfin_write(&drv_data->regs->ssel, 0x0000FE00); +	iowrite32(SPI_CTL_MSTR | SPI_CTL_CPHA, &drv_data->regs->control); +	iowrite32(0x0000FE00, &drv_data->regs->ssel);  	dma_disable_irq(drv_data->rx_dma);  	dma_disable_irq(drv_data->tx_dma);  	return 0;  } -static int bfin_spi_resume(struct device *dev) +static int adi_spi_resume(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev); -	struct bfin_spi_master *drv_data = spi_master_get_devdata(master); +	struct adi_spi_master *drv_data = spi_master_get_devdata(master);  	int ret = 0;  	/* bootrom may modify spi and dma status when resume in spi boot mode */ @@ -932,8 +953,8 @@ static int bfin_spi_resume(struct device *dev)  	dma_enable_irq(drv_data->rx_dma);  	dma_enable_irq(drv_data->tx_dma); -	bfin_write(&drv_data->regs->control, drv_data->control); -	bfin_write(&drv_data->regs->ssel, drv_data->ssel); +	iowrite32(drv_data->control, &drv_data->regs->control); +	iowrite32(drv_data->ssel, &drv_data->regs->ssel);  	ret = spi_master_resume(master);  	if (ret) { @@ -944,21 +965,21 @@ static int bfin_spi_resume(struct device *dev)  	return ret;  }  #endif -static const struct dev_pm_ops bfin_spi_pm_ops = { -	SET_SYSTEM_SLEEP_PM_OPS(bfin_spi_suspend, bfin_spi_resume) +static const struct dev_pm_ops adi_spi_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(adi_spi_suspend, adi_spi_resume)  }; -MODULE_ALIAS("platform:bfin-spi3"); -static struct platform_driver bfin_spi_driver = { +MODULE_ALIAS("platform:adi-spi3"); +static struct platform_driver adi_spi_driver = {  	.driver	= { -		.name	= "bfin-spi3", +		.name	= "adi-spi3",  		.owner	= THIS_MODULE, -		.pm     = &bfin_spi_pm_ops, +		.pm     = &adi_spi_pm_ops,  	}, -	.remove		= bfin_spi_remove, +	.remove		= adi_spi_remove,  }; -module_platform_driver_probe(bfin_spi_driver, bfin_spi_probe); +module_platform_driver_probe(adi_spi_driver, adi_spi_probe);  MODULE_DESCRIPTION("Analog Devices SPI3 controller driver");  MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index 9a64c3fee21..5b5709a5c95 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c @@ -13,7 +13,6 @@   * published by the Free Software Foundation.   */ -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/errno.h>  #include <linux/module.h> @@ -200,7 +199,6 @@ static irqreturn_t altera_spi_irq(int irq, void *dev)  static int altera_spi_probe(struct platform_device *pdev)  { -	struct altera_spi_platform_data *platp = dev_get_platdata(&pdev->dev);  	struct altera_spi *hw;  	struct spi_master *master;  	struct resource *res; @@ -214,14 +212,14 @@ static int altera_spi_probe(struct platform_device *pdev)  	master->bus_num = pdev->id;  	master->num_chipselect = 16;  	master->mode_bits = SPI_CS_HIGH; +	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16); +	master->dev.of_node = pdev->dev.of_node;  	hw = spi_master_get_devdata(master);  	platform_set_drvdata(pdev, hw);  	/* setup the state for the bitbang driver */ -	hw->bitbang.master = spi_master_get(master); -	if (!hw->bitbang.master) -		return err; +	hw->bitbang.master = master;  	hw->bitbang.chipselect = altera_spi_chipsel;  	hw->bitbang.txrx_bufs = altera_spi_txrx; @@ -247,9 +245,6 @@ static int altera_spi_probe(struct platform_device *pdev)  		if (err)  			goto exit;  	} -	/* find platform data */ -	if (!platp) -		hw->bitbang.master->dev.of_node = pdev->dev.of_node;  	/* register our spi controller */  	err = spi_bitbang_start(&hw->bitbang); diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 37bad952ab3..058db0fe8dc 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -14,10 +14,8 @@  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/delay.h>  #include <linux/spinlock.h> -#include <linux/workqueue.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/spi/spi.h> @@ -132,9 +130,9 @@ static int ath79_spi_setup_cs(struct spi_device *spi)  		flags = GPIOF_DIR_OUT;  		if (spi->mode & SPI_CS_HIGH) -			flags |= GPIOF_INIT_HIGH; -		else  			flags |= GPIOF_INIT_LOW; +		else +			flags |= GPIOF_INIT_HIGH;  		status = gpio_request_one(cdata->gpio, flags,  					  dev_name(&spi->dev)); @@ -231,7 +229,7 @@ static int ath79_spi_probe(struct platform_device *pdev)  		master->num_chipselect = pdata->num_chipselect;  	} -	sp->bitbang.master = spi_master_get(master); +	sp->bitbang.master = master;  	sp->bitbang.chipselect = ath79_spi_chipselect;  	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;  	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; @@ -243,21 +241,21 @@ static int ath79_spi_probe(struct platform_device *pdev)  		goto err_put_master;  	} -	sp->base = ioremap(r->start, resource_size(r)); +	sp->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));  	if (!sp->base) {  		ret = -ENXIO;  		goto err_put_master;  	} -	sp->clk = clk_get(&pdev->dev, "ahb"); +	sp->clk = devm_clk_get(&pdev->dev, "ahb");  	if (IS_ERR(sp->clk)) {  		ret = PTR_ERR(sp->clk); -		goto err_unmap; +		goto err_put_master;  	}  	ret = clk_enable(sp->clk);  	if (ret) -		goto err_clk_put; +		goto err_put_master;  	rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);  	if (!rate) { @@ -280,10 +278,6 @@ err_disable:  	ath79_spi_disable(sp);  err_clk_disable:  	clk_disable(sp->clk); -err_clk_put: -	clk_put(sp->clk); -err_unmap: -	iounmap(sp->base);  err_put_master:  	spi_master_put(sp->bitbang.master); @@ -297,8 +291,6 @@ static int ath79_spi_remove(struct platform_device *pdev)  	spi_bitbang_stop(&sp->bitbang);  	ath79_spi_disable(sp);  	clk_disable(sp->clk); -	clk_put(sp->clk); -	iounmap(sp->base);  	spi_master_put(sp->bitbang.master);  	return 0; diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index fd7cc566095..92a6f0d9323 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -9,7 +9,6 @@   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/clk.h>  #include <linux/module.h>  #include <linux/platform_device.h> @@ -26,6 +25,7 @@  #include <linux/io.h>  #include <linux/gpio.h> +#include <linux/pinctrl/consumer.h>  /* SPI register offsets */  #define SPI_CR					0x0000 @@ -170,18 +170,18 @@  /* Bit manipulation macros */  #define SPI_BIT(name) \  	(1 << SPI_##name##_OFFSET) -#define SPI_BF(name,value) \ +#define SPI_BF(name, value) \  	(((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET) -#define SPI_BFEXT(name,value) \ +#define SPI_BFEXT(name, value) \  	(((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1)) -#define SPI_BFINS(name,value,old) \ -	( ((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \ -	  | SPI_BF(name,value)) +#define SPI_BFINS(name, value, old) \ +	(((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \ +	  | SPI_BF(name, value))  /* Register access macros */ -#define spi_readl(port,reg) \ +#define spi_readl(port, reg) \  	__raw_readl((port)->regs + SPI_##reg) -#define spi_writel(port,reg,value) \ +#define spi_writel(port, reg, value) \  	__raw_writel((value), (port)->regs + SPI_##reg)  /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -189,6 +189,8 @@   */  #define DMA_MIN_BYTES	16 +#define SPI_DMA_TIMEOUT		(msecs_to_jiffies(1000)) +  struct atmel_spi_dma {  	struct dma_chan			*chan_rx;  	struct dma_chan			*chan_tx; @@ -220,17 +222,13 @@ struct atmel_spi {  	int			irq;  	struct clk		*clk;  	struct platform_device	*pdev; -	struct spi_device	*stay; -	u8			stopping; -	struct list_head	queue; -	struct tasklet_struct	tasklet;  	struct spi_transfer	*current_transfer; -	unsigned long		current_remaining_bytes; -	struct spi_transfer	*next_transfer; -	unsigned long		next_remaining_bytes; +	int			current_remaining_bytes;  	int			done_status; +	struct completion	xfer_completion; +  	/* scratch buffer */  	void			*buffer;  	dma_addr_t		buffer_dma; @@ -241,6 +239,9 @@ struct atmel_spi {  	bool			use_pdc;  	/* dmaengine data */  	struct atmel_spi_dma	dma; + +	bool			keep_cs; +	bool			cs_active;  };  /* Controller-specific per-slave state */ @@ -376,17 +377,6 @@ static inline bool atmel_spi_use_dma(struct atmel_spi *as,  	return as->use_dma && xfer->len >= DMA_MIN_BYTES;  } -static inline int atmel_spi_xfer_is_last(struct spi_message *msg, -					struct spi_transfer *xfer) -{ -	return msg->transfers.prev == &xfer->transfer_list; -} - -static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) -{ -	return xfer->delay_usecs == 0 && !xfer->cs_change; -} -  static int atmel_spi_dma_slave_config(struct atmel_spi *as,  				struct dma_slave_config *slave_config,  				u8 bits_per_word) @@ -513,23 +503,20 @@ static void dma_callback(void *data)  	struct spi_master	*master = data;  	struct atmel_spi	*as = spi_master_get_devdata(master); -	/* trigger SPI tasklet */ -	tasklet_schedule(&as->tasklet); +	complete(&as->xfer_completion);  }  /*   * Next transfer using PIO. - * lock is held, spi tasklet is blocked   */  static void atmel_spi_next_xfer_pio(struct spi_master *master,  				struct spi_transfer *xfer)  {  	struct atmel_spi	*as = spi_master_get_devdata(master); +	unsigned long xfer_pos = xfer->len - as->current_remaining_bytes;  	dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_pio\n"); -	as->current_remaining_bytes = xfer->len; -  	/* Make sure data is not remaining in RDR */  	spi_readl(as, RDR);  	while (spi_readl(as, SR) & SPI_BIT(RDRF)) { @@ -537,13 +524,14 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master,  		cpu_relax();  	} -	if (xfer->tx_buf) +	if (xfer->tx_buf) {  		if (xfer->bits_per_word > 8) -			spi_writel(as, TDR, *(u16 *)(xfer->tx_buf)); +			spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos));  		else -			spi_writel(as, TDR, *(u8 *)(xfer->tx_buf)); -	else +			spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos)); +	} else {  		spi_writel(as, TDR, 0); +	}  	dev_dbg(master->dev.parent,  		"  start pio xfer %p: len %u tx %p rx %p bitpw %d\n", @@ -556,7 +544,6 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master,  /*   * Submit next transfer for DMA. - * lock is held, spi tasklet is blocked   */  static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,  				struct spi_transfer *xfer, @@ -694,74 +681,90 @@ static void atmel_spi_next_xfer_data(struct spi_master *master,  	*plen = len;  } +static int atmel_spi_set_xfer_speed(struct atmel_spi *as, +				    struct spi_device *spi, +				    struct spi_transfer *xfer) +{ +	u32			scbr, csr; +	unsigned long		bus_hz; + +	/* v1 chips start out at half the peripheral bus speed. */ +	bus_hz = clk_get_rate(as->clk); +	if (!atmel_spi_is_v2(as)) +		bus_hz /= 2; + +	/* +	 * Calculate the lowest divider that satisfies the +	 * constraint, assuming div32/fdiv/mbz == 0. +	 */ +	if (xfer->speed_hz) +		scbr = DIV_ROUND_UP(bus_hz, xfer->speed_hz); +	else +		/* +		 * This can happend if max_speed is null. +		 * In this case, we set the lowest possible speed +		 */ +		scbr = 0xff; + +	/* +	 * If the resulting divider doesn't fit into the +	 * register bitfield, we can't satisfy the constraint. +	 */ +	if (scbr >= (1 << SPI_SCBR_SIZE)) { +		dev_err(&spi->dev, +			"setup: %d Hz too slow, scbr %u; min %ld Hz\n", +			xfer->speed_hz, scbr, bus_hz/255); +		return -EINVAL; +	} +	if (scbr == 0) { +		dev_err(&spi->dev, +			"setup: %d Hz too high, scbr %u; max %ld Hz\n", +			xfer->speed_hz, scbr, bus_hz); +		return -EINVAL; +	} +	csr = spi_readl(as, CSR0 + 4 * spi->chip_select); +	csr = SPI_BFINS(SCBR, scbr, csr); +	spi_writel(as, CSR0 + 4 * spi->chip_select, csr); + +	return 0; +} +  /*   * Submit next transfer for PDC.   * lock is held, spi irq is blocked   */  static void atmel_spi_pdc_next_xfer(struct spi_master *master, -				struct spi_message *msg) +					struct spi_message *msg, +					struct spi_transfer *xfer)  {  	struct atmel_spi	*as = spi_master_get_devdata(master); -	struct spi_transfer	*xfer; -	u32			len, remaining; -	u32			ieval; +	u32			len;  	dma_addr_t		tx_dma, rx_dma; -	if (!as->current_transfer) -		xfer = list_entry(msg->transfers.next, -				struct spi_transfer, transfer_list); -	else if (!as->next_transfer) -		xfer = list_entry(as->current_transfer->transfer_list.next, -				struct spi_transfer, transfer_list); -	else -		xfer = NULL; - -	if (xfer) { -		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); - -		len = xfer->len; -		atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); -		remaining = xfer->len - len; - -		spi_writel(as, RPR, rx_dma); -		spi_writel(as, TPR, tx_dma); - -		if (msg->spi->bits_per_word > 8) -			len >>= 1; -		spi_writel(as, RCR, len); -		spi_writel(as, TCR, len); - -		dev_dbg(&msg->spi->dev, -			"  start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", -			xfer, xfer->len, xfer->tx_buf, -			(unsigned long long)xfer->tx_dma, xfer->rx_buf, -			(unsigned long long)xfer->rx_dma); -	} else { -		xfer = as->next_transfer; -		remaining = as->next_remaining_bytes; -	} +	spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); -	as->current_transfer = xfer; -	as->current_remaining_bytes = remaining; +	len = as->current_remaining_bytes; +	atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); +	as->current_remaining_bytes -= len; -	if (remaining > 0) -		len = remaining; -	else if (!atmel_spi_xfer_is_last(msg, xfer) -			&& atmel_spi_xfer_can_be_chained(xfer)) { -		xfer = list_entry(xfer->transfer_list.next, -				struct spi_transfer, transfer_list); -		len = xfer->len; -	} else -		xfer = NULL; +	spi_writel(as, RPR, rx_dma); +	spi_writel(as, TPR, tx_dma); -	as->next_transfer = xfer; +	if (msg->spi->bits_per_word > 8) +		len >>= 1; +	spi_writel(as, RCR, len); +	spi_writel(as, TCR, len); -	if (xfer) { -		u32	total; +	dev_dbg(&msg->spi->dev, +		"  start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", +		xfer, xfer->len, xfer->tx_buf, +		(unsigned long long)xfer->tx_dma, xfer->rx_buf, +		(unsigned long long)xfer->rx_dma); -		total = len; +	if (as->current_remaining_bytes) { +		len = as->current_remaining_bytes;  		atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); -		as->next_remaining_bytes = total - len; +		as->current_remaining_bytes -= len;  		spi_writel(as, RNPR, rx_dma);  		spi_writel(as, TNPR, tx_dma); @@ -776,11 +779,6 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,  			xfer, xfer->len, xfer->tx_buf,  			(unsigned long long)xfer->tx_dma, xfer->rx_buf,  			(unsigned long long)xfer->rx_dma); -		ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); -	} else { -		spi_writel(as, RNCR, 0); -		spi_writel(as, TNCR, 0); -		ieval = SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) | SPI_BIT(OVRES);  	}  	/* REVISIT: We're waiting for ENDRX before we start the next @@ -793,83 +791,11 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,  	 *  	 * It should be doable, though. Just not now...  	 */ -	spi_writel(as, IER, ieval); +	spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES));  	spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));  }  /* - * Choose way to submit next transfer and start it. - * lock is held, spi tasklet is blocked - */ -static void atmel_spi_dma_next_xfer(struct spi_master *master, -				struct spi_message *msg) -{ -	struct atmel_spi	*as = spi_master_get_devdata(master); -	struct spi_transfer	*xfer; -	u32	remaining, len; - -	remaining = as->current_remaining_bytes; -	if (remaining) { -		xfer = as->current_transfer; -		len = remaining; -	} else { -		if (!as->current_transfer) -			xfer = list_entry(msg->transfers.next, -				struct spi_transfer, transfer_list); -		else -			xfer = list_entry( -				as->current_transfer->transfer_list.next, -					struct spi_transfer, transfer_list); - -		as->current_transfer = xfer; -		len = xfer->len; -	} - -	if (atmel_spi_use_dma(as, xfer)) { -		u32 total = len; -		if (!atmel_spi_next_xfer_dma_submit(master, xfer, &len)) { -			as->current_remaining_bytes = total - len; -			return; -		} else { -			dev_err(&msg->spi->dev, "unable to use DMA, fallback to PIO\n"); -		} -	} - -	/* use PIO if error appened using DMA */ -	atmel_spi_next_xfer_pio(master, xfer); -} - -static void atmel_spi_next_message(struct spi_master *master) -{ -	struct atmel_spi	*as = spi_master_get_devdata(master); -	struct spi_message	*msg; -	struct spi_device	*spi; - -	BUG_ON(as->current_transfer); - -	msg = list_entry(as->queue.next, struct spi_message, queue); -	spi = msg->spi; - -	dev_dbg(master->dev.parent, "start message %p for %s\n", -			msg, dev_name(&spi->dev)); - -	/* select chip if it's not still active */ -	if (as->stay) { -		if (as->stay != spi) { -			cs_deactivate(as, as->stay); -			cs_activate(as, spi); -		} -		as->stay = NULL; -	} else -		cs_activate(as, spi); - -	if (as->use_pdc) -		atmel_spi_pdc_next_xfer(master, msg); -	else -		atmel_spi_dma_next_xfer(master, msg); -} - -/*   * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma:   *  - The buffer is either valid for CPU access, else NULL   *  - If the buffer is valid, so is its DMA address @@ -924,41 +850,7 @@ static void atmel_spi_disable_pdc_transfer(struct atmel_spi *as)  	spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));  } -static void -atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as, -		struct spi_message *msg, int stay) -{ -	if (!stay || as->done_status < 0) -		cs_deactivate(as, msg->spi); -	else -		as->stay = msg->spi; - -	list_del(&msg->queue); -	msg->status = as->done_status; - -	dev_dbg(master->dev.parent, -		"xfer complete: %u bytes transferred\n", -		msg->actual_length); - -	atmel_spi_unlock(as); -	msg->complete(msg->context); -	atmel_spi_lock(as); - -	as->current_transfer = NULL; -	as->next_transfer = NULL; -	as->done_status = 0; - -	/* continue if needed */ -	if (list_empty(&as->queue) || as->stopping) { -		if (as->use_pdc) -			atmel_spi_disable_pdc_transfer(as); -	} else { -		atmel_spi_next_message(master); -	} -} -  /* Called from IRQ - * lock is held   *   * Must update "current_remaining_bytes" to keep track of data   * to transfer. @@ -966,9 +858,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,  static void  atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)  { -	u8		*txp;  	u8		*rxp; -	u16		*txp16;  	u16		*rxp16;  	unsigned long	xfer_pos = xfer->len - as->current_remaining_bytes; @@ -984,102 +874,19 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)  		spi_readl(as, RDR);  	}  	if (xfer->bits_per_word > 8) { -		as->current_remaining_bytes -= 2; -		if (as->current_remaining_bytes < 0) +		if (as->current_remaining_bytes > 2) +			as->current_remaining_bytes -= 2; +		else  			as->current_remaining_bytes = 0;  	} else {  		as->current_remaining_bytes--;  	} - -	if (as->current_remaining_bytes) { -		if (xfer->tx_buf) { -			if (xfer->bits_per_word > 8) { -				txp16 = (u16 *)(((u8 *)xfer->tx_buf) -							+ xfer_pos + 2); -				spi_writel(as, TDR, *txp16); -			} else { -				txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1; -				spi_writel(as, TDR, *txp); -			} -		} else { -			spi_writel(as, TDR, 0); -		} -	} -} - -/* Tasklet - * Called from DMA callback + pio transfer and overrun IRQ. - */ -static void atmel_spi_tasklet_func(unsigned long data) -{ -	struct spi_master	*master = (struct spi_master *)data; -	struct atmel_spi	*as = spi_master_get_devdata(master); -	struct spi_message	*msg; -	struct spi_transfer	*xfer; - -	dev_vdbg(master->dev.parent, "atmel_spi_tasklet_func\n"); - -	atmel_spi_lock(as); - -	xfer = as->current_transfer; - -	if (xfer == NULL) -		/* already been there */ -		goto tasklet_out; - -	msg = list_entry(as->queue.next, struct spi_message, queue); - -	if (as->current_remaining_bytes == 0) { -		if (as->done_status < 0) { -			/* error happened (overrun) */ -			if (atmel_spi_use_dma(as, xfer)) -				atmel_spi_stop_dma(as); -		} else { -			/* only update length if no error */ -			msg->actual_length += xfer->len; -		} - -		if (atmel_spi_use_dma(as, xfer)) -			if (!msg->is_dma_mapped) -				atmel_spi_dma_unmap_xfer(master, xfer); - -		if (xfer->delay_usecs) -			udelay(xfer->delay_usecs); - -		if (atmel_spi_xfer_is_last(msg, xfer) || as->done_status < 0) { -			/* report completed (or erroneous) message */ -			atmel_spi_msg_done(master, as, msg, xfer->cs_change); -		} else { -			if (xfer->cs_change) { -				cs_deactivate(as, msg->spi); -				udelay(1); -				cs_activate(as, msg->spi); -			} - -			/* -			 * Not done yet. Submit the next transfer. -			 * -			 * FIXME handle protocol options for xfer -			 */ -			atmel_spi_dma_next_xfer(master, msg); -		} -	} else { -		/* -		 * Keep going, we still have data to send in -		 * the current transfer. -		 */ -		atmel_spi_dma_next_xfer(master, msg); -	} - -tasklet_out: -	atmel_spi_unlock(as);  }  /* Interrupt   *   * No need for locking in this Interrupt handler: done_status is the - * only information modified. What we need is the update of this field - * before tasklet runs. This is ensured by using barrier. + * only information modified.   */  static irqreturn_t  atmel_spi_pio_interrupt(int irq, void *dev_id) @@ -1107,8 +914,6 @@ atmel_spi_pio_interrupt(int irq, void *dev_id)  		 *  		 * We will also not process any remaning transfers in  		 * the message. -		 * -		 * All actions are done in tasklet with done_status indication  		 */  		as->done_status = -EIO;  		smp_wmb(); @@ -1116,7 +921,7 @@ atmel_spi_pio_interrupt(int irq, void *dev_id)  		/* Clear any overrun happening while cleaning up */  		spi_readl(as, SR); -		tasklet_schedule(&as->tasklet); +		complete(&as->xfer_completion);  	} else if (pending & SPI_BIT(RDRF)) {  		atmel_spi_lock(as); @@ -1125,11 +930,10 @@ atmel_spi_pio_interrupt(int irq, void *dev_id)  			ret = IRQ_HANDLED;  			xfer = as->current_transfer;  			atmel_spi_pump_pio_data(as, xfer); -			if (!as->current_remaining_bytes) { -				/* no more data to xfer, kick tasklet */ +			if (!as->current_remaining_bytes)  				spi_writel(as, IDR, pending); -				tasklet_schedule(&as->tasklet); -			} + +			complete(&as->xfer_completion);  		}  		atmel_spi_unlock(as); @@ -1147,116 +951,35 @@ atmel_spi_pdc_interrupt(int irq, void *dev_id)  {  	struct spi_master	*master = dev_id;  	struct atmel_spi	*as = spi_master_get_devdata(master); -	struct spi_message	*msg; -	struct spi_transfer	*xfer;  	u32			status, pending, imr;  	int			ret = IRQ_NONE; -	atmel_spi_lock(as); - -	xfer = as->current_transfer; -	msg = list_entry(as->queue.next, struct spi_message, queue); -  	imr = spi_readl(as, IMR);  	status = spi_readl(as, SR);  	pending = status & imr;  	if (pending & SPI_BIT(OVRES)) { -		int timeout;  		ret = IRQ_HANDLED;  		spi_writel(as, IDR, (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX)  				     | SPI_BIT(OVRES))); -		/* -		 * When we get an overrun, we disregard the current -		 * transfer. Data will not be copied back from any -		 * bounce buffer and msg->actual_len will not be -		 * updated with the last xfer. -		 * -		 * We will also not process any remaning transfers in -		 * the message. -		 * -		 * First, stop the transfer and unmap the DMA buffers. -		 */ -		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); -		if (!msg->is_dma_mapped) -			atmel_spi_dma_unmap_xfer(master, xfer); - -		/* REVISIT: udelay in irq is unfriendly */ -		if (xfer->delay_usecs) -			udelay(xfer->delay_usecs); - -		dev_warn(master->dev.parent, "overrun (%u/%u remaining)\n", -			 spi_readl(as, TCR), spi_readl(as, RCR)); - -		/* -		 * Clean up DMA registers and make sure the data -		 * registers are empty. -		 */ -		spi_writel(as, RNCR, 0); -		spi_writel(as, TNCR, 0); -		spi_writel(as, RCR, 0); -		spi_writel(as, TCR, 0); -		for (timeout = 1000; timeout; timeout--) -			if (spi_readl(as, SR) & SPI_BIT(TXEMPTY)) -				break; -		if (!timeout) -			dev_warn(master->dev.parent, -				 "timeout waiting for TXEMPTY"); -		while (spi_readl(as, SR) & SPI_BIT(RDRF)) -			spi_readl(as, RDR); -  		/* Clear any overrun happening while cleaning up */  		spi_readl(as, SR);  		as->done_status = -EIO; -		atmel_spi_msg_done(master, as, msg, 0); + +		complete(&as->xfer_completion); +  	} else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) {  		ret = IRQ_HANDLED;  		spi_writel(as, IDR, pending); -		if (as->current_remaining_bytes == 0) { -			msg->actual_length += xfer->len; - -			if (!msg->is_dma_mapped) -				atmel_spi_dma_unmap_xfer(master, xfer); - -			/* REVISIT: udelay in irq is unfriendly */ -			if (xfer->delay_usecs) -				udelay(xfer->delay_usecs); - -			if (atmel_spi_xfer_is_last(msg, xfer)) { -				/* report completed message */ -				atmel_spi_msg_done(master, as, msg, -						xfer->cs_change); -			} else { -				if (xfer->cs_change) { -					cs_deactivate(as, msg->spi); -					udelay(1); -					cs_activate(as, msg->spi); -				} - -				/* -				 * Not done yet. Submit the next transfer. -				 * -				 * FIXME handle protocol options for xfer -				 */ -				atmel_spi_pdc_next_xfer(master, msg); -			} -		} else { -			/* -			 * Keep going, we still have data to send in -			 * the current transfer. -			 */ -			atmel_spi_pdc_next_xfer(master, msg); -		} +		complete(&as->xfer_completion);  	} -	atmel_spi_unlock(as); -  	return ret;  } @@ -1264,24 +987,13 @@ static int atmel_spi_setup(struct spi_device *spi)  {  	struct atmel_spi	*as;  	struct atmel_spi_device	*asd; -	u32			scbr, csr; +	u32			csr;  	unsigned int		bits = spi->bits_per_word; -	unsigned long		bus_hz;  	unsigned int		npcs_pin;  	int			ret;  	as = spi_master_get_devdata(spi->master); -	if (as->stopping) -		return -ESHUTDOWN; - -	if (spi->chip_select > spi->master->num_chipselect) { -		dev_dbg(&spi->dev, -				"setup: invalid chipselect %u (%u defined)\n", -				spi->chip_select, spi->master->num_chipselect); -		return -EINVAL; -	} -  	/* see notes above re chipselect */  	if (!atmel_spi_is_v2(as)  			&& spi->chip_select == 0 @@ -1290,33 +1002,7 @@ static int atmel_spi_setup(struct spi_device *spi)  		return -EINVAL;  	} -	/* v1 chips start out at half the peripheral bus speed. */ -	bus_hz = clk_get_rate(as->clk); -	if (!atmel_spi_is_v2(as)) -		bus_hz /= 2; - -	if (spi->max_speed_hz) { -		/* -		 * Calculate the lowest divider that satisfies the -		 * constraint, assuming div32/fdiv/mbz == 0. -		 */ -		scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz); - -		/* -		 * If the resulting divider doesn't fit into the -		 * register bitfield, we can't satisfy the constraint. -		 */ -		if (scbr >= (1 << SPI_SCBR_SIZE)) { -			dev_dbg(&spi->dev, -				"setup: %d Hz too slow, scbr %u; min %ld Hz\n", -				spi->max_speed_hz, scbr, bus_hz/255); -			return -EINVAL; -		} -	} else -		/* speed zero means "as slow as possible" */ -		scbr = 0xff; - -	csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8); +	csr = SPI_BF(BITS, bits - 8);  	if (spi->mode & SPI_CPOL)  		csr |= SPI_BIT(CPOL);  	if (!(spi->mode & SPI_CPHA)) @@ -1352,19 +1038,13 @@ static int atmel_spi_setup(struct spi_device *spi)  		asd->npcs_pin = npcs_pin;  		spi->controller_state = asd;  		gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); -	} else { -		atmel_spi_lock(as); -		if (as->stay == spi) -			as->stay = NULL; -		cs_deactivate(as, spi); -		atmel_spi_unlock(as);  	}  	asd->csr = csr;  	dev_dbg(&spi->dev, -		"setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", -		bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); +		"setup: bpw %u mode 0x%x -> csr%d %08x\n", +		bits, spi->mode, spi->chip_select, csr);  	if (!atmel_spi_is_v2(as))  		spi_writel(as, CSR0 + 4 * spi->chip_select, csr); @@ -1372,103 +1052,212 @@ static int atmel_spi_setup(struct spi_device *spi)  	return 0;  } -static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) +static int atmel_spi_one_transfer(struct spi_master *master, +					struct spi_message *msg, +					struct spi_transfer *xfer)  {  	struct atmel_spi	*as; -	struct spi_transfer	*xfer; -	struct device		*controller = spi->master->dev.parent; +	struct spi_device	*spi = msg->spi;  	u8			bits; +	u32			len;  	struct atmel_spi_device	*asd; +	int			timeout; +	int			ret; -	as = spi_master_get_devdata(spi->master); - -	dev_dbg(controller, "new message %p submitted for %s\n", -			msg, dev_name(&spi->dev)); +	as = spi_master_get_devdata(master); -	if (unlikely(list_empty(&msg->transfers))) +	if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) { +		dev_dbg(&spi->dev, "missing rx or tx buf\n");  		return -EINVAL; +	} -	if (as->stopping) -		return -ESHUTDOWN; - -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) { -			dev_dbg(&spi->dev, "missing rx or tx buf\n"); -			return -EINVAL; +	if (xfer->bits_per_word) { +		asd = spi->controller_state; +		bits = (asd->csr >> 4) & 0xf; +		if (bits != xfer->bits_per_word - 8) { +			dev_dbg(&spi->dev, +			"you can't yet change bits_per_word in transfers\n"); +			return -ENOPROTOOPT;  		} +	} + +	/* +	 * DMA map early, for performance (empties dcache ASAP) and +	 * better fault reporting. +	 */ +	if ((!msg->is_dma_mapped) +		&& (atmel_spi_use_dma(as, xfer)	|| as->use_pdc)) { +		if (atmel_spi_dma_map_xfer(as, xfer) < 0) +			return -ENOMEM; +	} -		if (xfer->bits_per_word) { -			asd = spi->controller_state; -			bits = (asd->csr >> 4) & 0xf; -			if (bits != xfer->bits_per_word - 8) { -				dev_dbg(&spi->dev, "you can't yet change " -					 "bits_per_word in transfers\n"); -				return -ENOPROTOOPT; +	atmel_spi_set_xfer_speed(as, msg->spi, xfer); + +	as->done_status = 0; +	as->current_transfer = xfer; +	as->current_remaining_bytes = xfer->len; +	while (as->current_remaining_bytes) { +		reinit_completion(&as->xfer_completion); + +		if (as->use_pdc) { +			atmel_spi_pdc_next_xfer(master, msg, xfer); +		} else if (atmel_spi_use_dma(as, xfer)) { +			len = as->current_remaining_bytes; +			ret = atmel_spi_next_xfer_dma_submit(master, +								xfer, &len); +			if (ret) { +				dev_err(&spi->dev, +					"unable to use DMA, fallback to PIO\n"); +				atmel_spi_next_xfer_pio(master, xfer); +			} else { +				as->current_remaining_bytes -= len; +				if (as->current_remaining_bytes < 0) +					as->current_remaining_bytes = 0;  			} +		} else { +			atmel_spi_next_xfer_pio(master, xfer);  		} -		if (xfer->bits_per_word > 8) { -			if (xfer->len % 2) { -				dev_dbg(&spi->dev, "buffer len should be 16 bits aligned\n"); -				return -EINVAL; -			} +		/* interrupts are disabled, so free the lock for schedule */ +		atmel_spi_unlock(as); +		ret = wait_for_completion_timeout(&as->xfer_completion, +							SPI_DMA_TIMEOUT); +		atmel_spi_lock(as); +		if (WARN_ON(ret == 0)) { +			dev_err(&spi->dev, +				"spi trasfer timeout, err %d\n", ret); +			as->done_status = -EIO; +		} else { +			ret = 0;  		} -		/* FIXME implement these protocol options!! */ -		if (xfer->speed_hz < spi->max_speed_hz) { -			dev_dbg(&spi->dev, "can't change speed in transfer\n"); -			return -ENOPROTOOPT; +		if (as->done_status) +			break; +	} + +	if (as->done_status) { +		if (as->use_pdc) { +			dev_warn(master->dev.parent, +				"overrun (%u/%u remaining)\n", +				spi_readl(as, TCR), spi_readl(as, RCR)); + +			/* +			 * Clean up DMA registers and make sure the data +			 * registers are empty. +			 */ +			spi_writel(as, RNCR, 0); +			spi_writel(as, TNCR, 0); +			spi_writel(as, RCR, 0); +			spi_writel(as, TCR, 0); +			for (timeout = 1000; timeout; timeout--) +				if (spi_readl(as, SR) & SPI_BIT(TXEMPTY)) +					break; +			if (!timeout) +				dev_warn(master->dev.parent, +					 "timeout waiting for TXEMPTY"); +			while (spi_readl(as, SR) & SPI_BIT(RDRF)) +				spi_readl(as, RDR); + +			/* Clear any overrun happening while cleaning up */ +			spi_readl(as, SR); + +		} else if (atmel_spi_use_dma(as, xfer)) { +			atmel_spi_stop_dma(as);  		} -		/* -		 * DMA map early, for performance (empties dcache ASAP) and -		 * better fault reporting. -		 */ -		if ((!msg->is_dma_mapped) && (atmel_spi_use_dma(as, xfer) -			|| as->use_pdc)) { -			if (atmel_spi_dma_map_xfer(as, xfer) < 0) -				return -ENOMEM; +		if (!msg->is_dma_mapped +			&& (atmel_spi_use_dma(as, xfer) || as->use_pdc)) +			atmel_spi_dma_unmap_xfer(master, xfer); + +		return 0; + +	} else { +		/* only update length if no error */ +		msg->actual_length += xfer->len; +	} + +	if (!msg->is_dma_mapped +		&& (atmel_spi_use_dma(as, xfer) || as->use_pdc)) +		atmel_spi_dma_unmap_xfer(master, xfer); + +	if (xfer->delay_usecs) +		udelay(xfer->delay_usecs); + +	if (xfer->cs_change) { +		if (list_is_last(&xfer->transfer_list, +				 &msg->transfers)) { +			as->keep_cs = true; +		} else { +			as->cs_active = !as->cs_active; +			if (as->cs_active) +				cs_activate(as, msg->spi); +			else +				cs_deactivate(as, msg->spi);  		}  	} -#ifdef VERBOSE +	return 0; +} + +static int atmel_spi_transfer_one_message(struct spi_master *master, +						struct spi_message *msg) +{ +	struct atmel_spi *as; +	struct spi_transfer *xfer; +	struct spi_device *spi = msg->spi; +	int ret = 0; + +	as = spi_master_get_devdata(master); + +	dev_dbg(&spi->dev, "new message %p submitted for %s\n", +					msg, dev_name(&spi->dev)); + +	atmel_spi_lock(as); +	cs_activate(as, spi); + +	as->cs_active = true; +	as->keep_cs = false; + +	msg->status = 0; +	msg->actual_length = 0; +  	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		dev_dbg(controller, -			"  xfer %p: len %u tx %p/%08x rx %p/%08x\n", +		ret = atmel_spi_one_transfer(master, msg, xfer); +		if (ret) +			goto msg_done; +	} + +	if (as->use_pdc) +		atmel_spi_disable_pdc_transfer(as); + +	list_for_each_entry(xfer, &msg->transfers, transfer_list) { +		dev_dbg(&spi->dev, +			"  xfer %p: len %u tx %p/%pad rx %p/%pad\n",  			xfer, xfer->len, -			xfer->tx_buf, xfer->tx_dma, -			xfer->rx_buf, xfer->rx_dma); +			xfer->tx_buf, &xfer->tx_dma, +			xfer->rx_buf, &xfer->rx_dma);  	} -#endif -	msg->status = -EINPROGRESS; -	msg->actual_length = 0; +msg_done: +	if (!as->keep_cs) +		cs_deactivate(as, msg->spi); -	atmel_spi_lock(as); -	list_add_tail(&msg->queue, &as->queue); -	if (!as->current_transfer) -		atmel_spi_next_message(spi->master);  	atmel_spi_unlock(as); -	return 0; +	msg->status = as->done_status; +	spi_finalize_current_message(spi->master); + +	return ret;  }  static void atmel_spi_cleanup(struct spi_device *spi)  { -	struct atmel_spi	*as = spi_master_get_devdata(spi->master);  	struct atmel_spi_device	*asd = spi->controller_state;  	unsigned		gpio = (unsigned) spi->controller_data;  	if (!asd)  		return; -	atmel_spi_lock(as); -	if (as->stay == spi) { -		as->stay = NULL; -		cs_deactivate(as, spi); -	} -	atmel_spi_unlock(as); -  	spi->controller_state = NULL;  	gpio_free(gpio);  	kfree(asd); @@ -1502,6 +1291,9 @@ static int atmel_spi_probe(struct platform_device *pdev)  	struct spi_master	*master;  	struct atmel_spi	*as; +	/* Select default pin state */ +	pinctrl_pm_select_default_state(&pdev->dev); +  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!regs)  		return -ENXIO; @@ -1510,13 +1302,13 @@ static int atmel_spi_probe(struct platform_device *pdev)  	if (irq < 0)  		return irq; -	clk = clk_get(&pdev->dev, "spi_clk"); +	clk = devm_clk_get(&pdev->dev, "spi_clk");  	if (IS_ERR(clk))  		return PTR_ERR(clk);  	/* setup spi core then atmel-specific driver state */  	ret = -ENOMEM; -	master = spi_alloc_master(&pdev->dev, sizeof *as); +	master = spi_alloc_master(&pdev->dev, sizeof(*as));  	if (!master)  		goto out_free; @@ -1527,7 +1319,7 @@ static int atmel_spi_probe(struct platform_device *pdev)  	master->bus_num = pdev->id;  	master->num_chipselect = master->dev.of_node ? 0 : 4;  	master->setup = atmel_spi_setup; -	master->transfer = atmel_spi_transfer; +	master->transfer_one_message = atmel_spi_transfer_one_message;  	master->cleanup = atmel_spi_cleanup;  	platform_set_drvdata(pdev, master); @@ -1543,16 +1335,19 @@ static int atmel_spi_probe(struct platform_device *pdev)  		goto out_free;  	spin_lock_init(&as->lock); -	INIT_LIST_HEAD(&as->queue);  	as->pdev = pdev; -	as->regs = ioremap(regs->start, resource_size(regs)); -	if (!as->regs) +	as->regs = devm_ioremap_resource(&pdev->dev, regs); +	if (IS_ERR(as->regs)) { +		ret = PTR_ERR(as->regs);  		goto out_free_buffer; +	}  	as->phybase = regs->start;  	as->irq = irq;  	as->clk = clk; +	init_completion(&as->xfer_completion); +  	atmel_get_caps(as);  	as->use_dma = false; @@ -1568,14 +1363,11 @@ static int atmel_spi_probe(struct platform_device *pdev)  		dev_info(&pdev->dev, "Atmel SPI Controller using PIO only\n");  	if (as->use_pdc) { -		ret = request_irq(irq, atmel_spi_pdc_interrupt, 0, -					dev_name(&pdev->dev), master); +		ret = devm_request_irq(&pdev->dev, irq, atmel_spi_pdc_interrupt, +					0, dev_name(&pdev->dev), master);  	} else { -		tasklet_init(&as->tasklet, atmel_spi_tasklet_func, -					(unsigned long)master); - -		ret = request_irq(irq, atmel_spi_pio_interrupt, 0, -					dev_name(&pdev->dev), master); +		ret = devm_request_irq(&pdev->dev, irq, atmel_spi_pio_interrupt, +					0, dev_name(&pdev->dev), master);  	}  	if (ret)  		goto out_unmap_regs; @@ -1583,7 +1375,7 @@ static int atmel_spi_probe(struct platform_device *pdev)  	/* Initialize the hardware */  	ret = clk_prepare_enable(clk);  	if (ret) -		goto out_unmap_regs; +		goto out_free_irq;  	spi_writel(as, CR, SPI_BIT(SWRST));  	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */  	if (as->caps.has_wdrbt) { @@ -1601,7 +1393,7 @@ static int atmel_spi_probe(struct platform_device *pdev)  	dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n",  			(unsigned long)regs->start, irq); -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret)  		goto out_free_dma; @@ -1614,16 +1406,12 @@ out_free_dma:  	spi_writel(as, CR, SPI_BIT(SWRST));  	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */  	clk_disable_unprepare(clk); -	free_irq(irq, master); +out_free_irq:  out_unmap_regs: -	iounmap(as->regs);  out_free_buffer: -	if (!as->use_pdc) -		tasklet_kill(&as->tasklet);  	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,  			as->buffer_dma);  out_free: -	clk_put(clk);  	spi_master_put(master);  	return ret;  } @@ -1632,12 +1420,9 @@ static int atmel_spi_remove(struct platform_device *pdev)  {  	struct spi_master	*master = platform_get_drvdata(pdev);  	struct atmel_spi	*as = spi_master_get_devdata(master); -	struct spi_message	*msg; -	struct spi_transfer	*xfer;  	/* reset the hardware and block queue progress */  	spin_lock_irq(&as->lock); -	as->stopping = 1;  	if (as->use_dma) {  		atmel_spi_stop_dma(as);  		atmel_spi_release_dma(as); @@ -1648,56 +1433,58 @@ static int atmel_spi_remove(struct platform_device *pdev)  	spi_readl(as, SR);  	spin_unlock_irq(&as->lock); -	/* Terminate remaining queued transfers */ -	list_for_each_entry(msg, &as->queue, queue) { -		list_for_each_entry(xfer, &msg->transfers, transfer_list) { -			if (!msg->is_dma_mapped -				&& (atmel_spi_use_dma(as, xfer) -					|| as->use_pdc)) -				atmel_spi_dma_unmap_xfer(master, xfer); -		} -		msg->status = -ESHUTDOWN; -		msg->complete(msg->context); -	} - -	if (!as->use_pdc) -		tasklet_kill(&as->tasklet);  	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,  			as->buffer_dma);  	clk_disable_unprepare(as->clk); -	clk_put(as->clk); -	free_irq(as->irq, master); -	iounmap(as->regs); - -	spi_unregister_master(master);  	return 0;  } -#ifdef	CONFIG_PM - -static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg) +#ifdef CONFIG_PM_SLEEP +static int atmel_spi_suspend(struct device *dev)  { -	struct spi_master	*master = platform_get_drvdata(pdev); +	struct spi_master	*master = dev_get_drvdata(dev);  	struct atmel_spi	*as = spi_master_get_devdata(master); +	int ret; + +	/* Stop the queue running */ +	ret = spi_master_suspend(master); +	if (ret) { +		dev_warn(dev, "cannot suspend master\n"); +		return ret; +	}  	clk_disable_unprepare(as->clk); + +	pinctrl_pm_select_sleep_state(dev); +  	return 0;  } -static int atmel_spi_resume(struct platform_device *pdev) +static int atmel_spi_resume(struct device *dev)  { -	struct spi_master	*master = platform_get_drvdata(pdev); +	struct spi_master	*master = dev_get_drvdata(dev);  	struct atmel_spi	*as = spi_master_get_devdata(master); +	int ret; -	return clk_prepare_enable(as->clk); -	return 0; +	pinctrl_pm_select_default_state(dev); + +	clk_prepare_enable(as->clk); + +	/* Start the queue running */ +	ret = spi_master_resume(master); +	if (ret) +		dev_err(dev, "problem starting queue (%d)\n", ret); + +	return ret;  } +static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume); + +#define ATMEL_SPI_PM_OPS	(&atmel_spi_pm_ops)  #else -#define	atmel_spi_suspend	NULL -#define	atmel_spi_resume	NULL +#define ATMEL_SPI_PM_OPS	NULL  #endif  #if defined(CONFIG_OF) @@ -1713,10 +1500,9 @@ static struct platform_driver atmel_spi_driver = {  	.driver		= {  		.name	= "atmel_spi",  		.owner	= THIS_MODULE, +		.pm	= ATMEL_SPI_PM_OPS,  		.of_match_table	= of_match_ptr(atmel_spi_dt_ids),  	}, -	.suspend	= atmel_spi_suspend, -	.resume		= atmel_spi_resume,  	.probe		= atmel_spi_probe,  	.remove		= atmel_spi_remove,  }; diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index 1d00d9b397d..67375a11d4b 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -55,8 +55,6 @@ struct au1550_spi {  	volatile psc_spi_t __iomem *regs;  	int irq; -	unsigned freq_max; -	unsigned freq_min;  	unsigned len;  	unsigned tx_count; @@ -248,11 +246,8 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)  			hz = t->speed_hz;  	} -	if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) { -		dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n", -			hz); +	if (!hz)  		return -EINVAL; -	}  	au1550_spi_bits_handlers_set(hw, spi->bits_per_word); @@ -287,23 +282,6 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)  	return 0;  } -static int au1550_spi_setup(struct spi_device *spi) -{ -	struct au1550_spi *hw = spi_master_get_devdata(spi->master); - -	if (spi->max_speed_hz == 0) -		spi->max_speed_hz = hw->freq_max; -	if (spi->max_speed_hz > hw->freq_max -			|| spi->max_speed_hz < hw->freq_min) -		return -EINVAL; -	/* -	 * NOTE: cannot change speed and other hw settings immediately, -	 *       otherwise sharing of spi bus is not possible, -	 *       so do not call setupxfer(spi, NULL) here -	 */ -	return 0; -} -  /*   * for dma spi transfers, we have to setup rx channel, otherwise there is   * no reliable way how to recognize that spi transfer is done @@ -775,7 +753,7 @@ static int au1550_spi_probe(struct platform_device *pdev)  	hw = spi_master_get_devdata(master); -	hw->master = spi_master_get(master); +	hw->master = master;  	hw->pdata = dev_get_platdata(&pdev->dev);  	hw->dev = &pdev->dev; @@ -838,7 +816,6 @@ static int au1550_spi_probe(struct platform_device *pdev)  	hw->bitbang.master = hw->master;  	hw->bitbang.setup_transfer = au1550_spi_setupxfer;  	hw->bitbang.chipselect = au1550_spi_chipsel; -	hw->bitbang.master->setup = au1550_spi_setup;  	hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;  	if (hw->usedma) { @@ -909,8 +886,9 @@ static int au1550_spi_probe(struct platform_device *pdev)  	{  		int min_div = (2 << 0) * (2 * (4 + 1));  		int max_div = (2 << 3) * (2 * (63 + 1)); -		hw->freq_max = hw->pdata->mainclk_hz / min_div; -		hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1; +		master->max_speed_hz = hw->pdata->mainclk_hz / min_div; +		master->min_speed_hz = +				hw->pdata->mainclk_hz / (max_div + 1) + 1;  	}  	au1550_spi_setup_psc_as_spi(hw); @@ -985,6 +963,7 @@ static int au1550_spi_remove(struct platform_device *pdev)  MODULE_ALIAS("platform:au1550-spi");  static struct platform_driver au1550_spi_drv = { +	.probe = au1550_spi_probe,  	.remove = au1550_spi_remove,  	.driver = {  		.name = "au1550-spi", @@ -998,13 +977,22 @@ static int __init au1550_spi_init(void)  	 * create memory device with 8 bits dev_devwidth  	 * needed for proper byte ordering to spi fifo  	 */ +	switch (alchemy_get_cputype()) { +	case ALCHEMY_CPU_AU1550: +	case ALCHEMY_CPU_AU1200: +	case ALCHEMY_CPU_AU1300: +		break; +	default: +		return -ENODEV; +	} +  	if (usedma) {  		ddma_memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev);  		if (!ddma_memid)  			printk(KERN_ERR "au1550-spi: cannot add memory"  					"dbdma device\n");  	} -	return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); +	return platform_driver_register(&au1550_spi_drv);  }  module_init(au1550_spi_init); diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 52c81481c5c..69167456ec1 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -217,7 +217,7 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi,  		cs |= spi->chip_select;  	} -	INIT_COMPLETION(bs->done); +	reinit_completion(&bs->done);  	bs->tx_buf = tfr->tx_buf;  	bs->rx_buf = tfr->rx_buf;  	bs->len = tfr->len; @@ -315,7 +315,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev)  	master->mode_bits = BCM2835_SPI_MODE_BITS;  	master->bits_per_word_mask = SPI_BPW_MASK(8); -	master->bus_num = -1;  	master->num_chipselect = 3;  	master->transfer_one_message = bcm2835_spi_transfer_one;  	master->dev.of_node = pdev->dev.of_node; @@ -347,8 +346,8 @@ static int bcm2835_spi_probe(struct platform_device *pdev)  	clk_prepare_enable(bs->clk); -	err = request_irq(bs->irq, bcm2835_spi_interrupt, 0, -			dev_name(&pdev->dev), master); +	err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, +				dev_name(&pdev->dev), master);  	if (err) {  		dev_err(&pdev->dev, "could not request IRQ: %d\n", err);  		goto out_clk_disable; @@ -358,16 +357,14 @@ static int bcm2835_spi_probe(struct platform_device *pdev)  	bcm2835_wr(bs, BCM2835_SPI_CS,  		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); -	err = spi_register_master(master); +	err = devm_spi_register_master(&pdev->dev, master);  	if (err) {  		dev_err(&pdev->dev, "could not register SPI master: %d\n", err); -		goto out_free_irq; +		goto out_clk_disable;  	}  	return 0; -out_free_irq: -	free_irq(bs->irq, master);  out_clk_disable:  	clk_disable_unprepare(bs->clk);  out_master_put: @@ -377,18 +374,14 @@ out_master_put:  static int bcm2835_spi_remove(struct platform_device *pdev)  { -	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); +	struct spi_master *master = platform_get_drvdata(pdev);  	struct bcm2835_spi *bs = spi_master_get_devdata(master); -	free_irq(bs->irq, master); -	spi_unregister_master(master); -  	/* Clear FIFOs, and disable the HW block */  	bcm2835_wr(bs, BCM2835_SPI_CS,  		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);  	clk_disable_unprepare(bs->clk); -	spi_master_put(master);  	return 0;  } diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c new file mode 100644 index 00000000000..86f5a98aa7a --- /dev/null +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -0,0 +1,474 @@ +/* + * Broadcom BCM63XX High Speed SPI Controller driver + * + * Copyright 2000-2010 Broadcom Corporation + * Copyright 2012-2013 Jonas Gorski <jogo@openwrt.org> + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/spi/spi.h> +#include <linux/mutex.h> + +#define HSSPI_GLOBAL_CTRL_REG			0x0 +#define GLOBAL_CTRL_CS_POLARITY_SHIFT		0 +#define GLOBAL_CTRL_CS_POLARITY_MASK		0x000000ff +#define GLOBAL_CTRL_PLL_CLK_CTRL_SHIFT		8 +#define GLOBAL_CTRL_PLL_CLK_CTRL_MASK		0x0000ff00 +#define GLOBAL_CTRL_CLK_GATE_SSOFF		BIT(16) +#define GLOBAL_CTRL_CLK_POLARITY		BIT(17) +#define GLOBAL_CTRL_MOSI_IDLE			BIT(18) + +#define HSSPI_GLOBAL_EXT_TRIGGER_REG		0x4 + +#define HSSPI_INT_STATUS_REG			0x8 +#define HSSPI_INT_STATUS_MASKED_REG		0xc +#define HSSPI_INT_MASK_REG			0x10 + +#define HSSPI_PINGx_CMD_DONE(i)			BIT((i * 8) + 0) +#define HSSPI_PINGx_RX_OVER(i)			BIT((i * 8) + 1) +#define HSSPI_PINGx_TX_UNDER(i)			BIT((i * 8) + 2) +#define HSSPI_PINGx_POLL_TIMEOUT(i)		BIT((i * 8) + 3) +#define HSSPI_PINGx_CTRL_INVAL(i)		BIT((i * 8) + 4) + +#define HSSPI_INT_CLEAR_ALL			0xff001f1f + +#define HSSPI_PINGPONG_COMMAND_REG(x)		(0x80 + (x) * 0x40) +#define PINGPONG_CMD_COMMAND_MASK		0xf +#define PINGPONG_COMMAND_NOOP			0 +#define PINGPONG_COMMAND_START_NOW		1 +#define PINGPONG_COMMAND_START_TRIGGER		2 +#define PINGPONG_COMMAND_HALT			3 +#define PINGPONG_COMMAND_FLUSH			4 +#define PINGPONG_CMD_PROFILE_SHIFT		8 +#define PINGPONG_CMD_SS_SHIFT			12 + +#define HSSPI_PINGPONG_STATUS_REG(x)		(0x84 + (x) * 0x40) + +#define HSSPI_PROFILE_CLK_CTRL_REG(x)		(0x100 + (x) * 0x20) +#define CLK_CTRL_FREQ_CTRL_MASK			0x0000ffff +#define CLK_CTRL_SPI_CLK_2X_SEL			BIT(14) +#define CLK_CTRL_ACCUM_RST_ON_LOOP		BIT(15) + +#define HSSPI_PROFILE_SIGNAL_CTRL_REG(x)	(0x104 + (x) * 0x20) +#define SIGNAL_CTRL_LATCH_RISING		BIT(12) +#define SIGNAL_CTRL_LAUNCH_RISING		BIT(13) +#define SIGNAL_CTRL_ASYNC_INPUT_PATH		BIT(16) + +#define HSSPI_PROFILE_MODE_CTRL_REG(x)		(0x108 + (x) * 0x20) +#define MODE_CTRL_MULTIDATA_RD_STRT_SHIFT	8 +#define MODE_CTRL_MULTIDATA_WR_STRT_SHIFT	12 +#define MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT	16 +#define MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT	18 +#define MODE_CTRL_MODE_3WIRE			BIT(20) +#define MODE_CTRL_PREPENDBYTE_CNT_SHIFT		24 + +#define HSSPI_FIFO_REG(x)			(0x200 + (x) * 0x200) + + +#define HSSPI_OP_CODE_SHIFT			13 +#define HSSPI_OP_SLEEP				(0 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_READ_WRITE			(1 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_WRITE				(2 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_READ				(3 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_SETIRQ				(4 << HSSPI_OP_CODE_SHIFT) + +#define HSSPI_BUFFER_LEN			512 +#define HSSPI_OPCODE_LEN			2 + +#define HSSPI_MAX_PREPEND_LEN			15 + +#define HSSPI_MAX_SYNC_CLOCK			30000000 + +#define HSSPI_BUS_NUM				1 /* 0 is legacy SPI */ + +struct bcm63xx_hsspi { +	struct completion done; +	struct mutex bus_mutex; + +	struct platform_device *pdev; +	struct clk *clk; +	void __iomem *regs; +	u8 __iomem *fifo; + +	u32 speed_hz; +	u8 cs_polarity; +}; + +static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned cs, +				 bool active) +{ +	u32 reg; + +	mutex_lock(&bs->bus_mutex); +	reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); + +	reg &= ~BIT(cs); +	if (active == !(bs->cs_polarity & BIT(cs))) +		reg |= BIT(cs); + +	__raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); +	mutex_unlock(&bs->bus_mutex); +} + +static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs, +				  struct spi_device *spi, int hz) +{ +	unsigned profile = spi->chip_select; +	u32 reg; + +	reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz)); +	__raw_writel(CLK_CTRL_ACCUM_RST_ON_LOOP | reg, +		     bs->regs + HSSPI_PROFILE_CLK_CTRL_REG(profile)); + +	reg = __raw_readl(bs->regs + HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); +	if (hz > HSSPI_MAX_SYNC_CLOCK) +		reg |= SIGNAL_CTRL_ASYNC_INPUT_PATH; +	else +		reg &= ~SIGNAL_CTRL_ASYNC_INPUT_PATH; +	__raw_writel(reg, bs->regs + HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); + +	mutex_lock(&bs->bus_mutex); +	/* setup clock polarity */ +	reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); +	reg &= ~GLOBAL_CTRL_CLK_POLARITY; +	if (spi->mode & SPI_CPOL) +		reg |= GLOBAL_CTRL_CLK_POLARITY; +	__raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); +	mutex_unlock(&bs->bus_mutex); +} + +static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) +{ +	struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); +	unsigned chip_select = spi->chip_select; +	u16 opcode = 0; +	int pending = t->len; +	int step_size = HSSPI_BUFFER_LEN; +	const u8 *tx = t->tx_buf; +	u8 *rx = t->rx_buf; + +	bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); +	bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); + +	if (tx && rx) +		opcode = HSSPI_OP_READ_WRITE; +	else if (tx) +		opcode = HSSPI_OP_WRITE; +	else if (rx) +		opcode = HSSPI_OP_READ; + +	if (opcode != HSSPI_OP_READ) +		step_size -= HSSPI_OPCODE_LEN; + +	__raw_writel(0 << MODE_CTRL_PREPENDBYTE_CNT_SHIFT | +		     2 << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT | +		     2 << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT | 0xff, +		     bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); + +	while (pending > 0) { +		int curr_step = min_t(int, step_size, pending); + +		reinit_completion(&bs->done); +		if (tx) { +			memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN, tx, curr_step); +			tx += curr_step; +		} + +		__raw_writew(opcode | curr_step, bs->fifo); + +		/* enable interrupt */ +		__raw_writel(HSSPI_PINGx_CMD_DONE(0), +			     bs->regs + HSSPI_INT_MASK_REG); + +		/* start the transfer */ +		__raw_writel(!chip_select << PINGPONG_CMD_SS_SHIFT | +			     chip_select << PINGPONG_CMD_PROFILE_SHIFT | +			     PINGPONG_COMMAND_START_NOW, +			     bs->regs + HSSPI_PINGPONG_COMMAND_REG(0)); + +		if (wait_for_completion_timeout(&bs->done, HZ) == 0) { +			dev_err(&bs->pdev->dev, "transfer timed out!\n"); +			return -ETIMEDOUT; +		} + +		if (rx) { +			memcpy_fromio(rx, bs->fifo, curr_step); +			rx += curr_step; +		} + +		pending -= curr_step; +	} + +	return 0; +} + +static int bcm63xx_hsspi_setup(struct spi_device *spi) +{ +	struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); +	u32 reg; + +	reg = __raw_readl(bs->regs + +			  HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); +	reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING); +	if (spi->mode & SPI_CPHA) +		reg |= SIGNAL_CTRL_LAUNCH_RISING; +	else +		reg |= SIGNAL_CTRL_LATCH_RISING; +	__raw_writel(reg, bs->regs + +		     HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); + +	mutex_lock(&bs->bus_mutex); +	reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); + +	/* only change actual polarities if there is no transfer */ +	if ((reg & GLOBAL_CTRL_CS_POLARITY_MASK) == bs->cs_polarity) { +		if (spi->mode & SPI_CS_HIGH) +			reg |= BIT(spi->chip_select); +		else +			reg &= ~BIT(spi->chip_select); +		__raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); +	} + +	if (spi->mode & SPI_CS_HIGH) +		bs->cs_polarity |= BIT(spi->chip_select); +	else +		bs->cs_polarity &= ~BIT(spi->chip_select); + +	mutex_unlock(&bs->bus_mutex); + +	return 0; +} + +static int bcm63xx_hsspi_transfer_one(struct spi_master *master, +				      struct spi_message *msg) +{ +	struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); +	struct spi_transfer *t; +	struct spi_device *spi = msg->spi; +	int status = -EINVAL; +	int dummy_cs; +	u32 reg; + +	/* This controller does not support keeping CS active during idle. +	 * To work around this, we use the following ugly hack: +	 * +	 * a. Invert the target chip select's polarity so it will be active. +	 * b. Select a "dummy" chip select to use as the hardware target. +	 * c. Invert the dummy chip select's polarity so it will be inactive +	 *    during the actual transfers. +	 * d. Tell the hardware to send to the dummy chip select. Thanks to +	 *    the multiplexed nature of SPI the actual target will receive +	 *    the transfer and we see its response. +	 * +	 * e. At the end restore the polarities again to their default values. +	 */ + +	dummy_cs = !spi->chip_select; +	bcm63xx_hsspi_set_cs(bs, dummy_cs, true); + +	list_for_each_entry(t, &msg->transfers, transfer_list) { +		status = bcm63xx_hsspi_do_txrx(spi, t); +		if (status) +			break; + +		msg->actual_length += t->len; + +		if (t->delay_usecs) +			udelay(t->delay_usecs); + +		if (t->cs_change) +			bcm63xx_hsspi_set_cs(bs, spi->chip_select, false); +	} + +	mutex_lock(&bs->bus_mutex); +	reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); +	reg &= ~GLOBAL_CTRL_CS_POLARITY_MASK; +	reg |= bs->cs_polarity; +	__raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); +	mutex_unlock(&bs->bus_mutex); + +	msg->status = status; +	spi_finalize_current_message(master); + +	return 0; +} + +static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id) +{ +	struct bcm63xx_hsspi *bs = (struct bcm63xx_hsspi *)dev_id; + +	if (__raw_readl(bs->regs + HSSPI_INT_STATUS_MASKED_REG) == 0) +		return IRQ_NONE; + +	__raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG); +	__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); + +	complete(&bs->done); + +	return IRQ_HANDLED; +} + +static int bcm63xx_hsspi_probe(struct platform_device *pdev) +{ +	struct spi_master *master; +	struct bcm63xx_hsspi *bs; +	struct resource *res_mem; +	void __iomem *regs; +	struct device *dev = &pdev->dev; +	struct clk *clk; +	int irq, ret; +	u32 reg, rate; + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(dev, "no irq\n"); +		return -ENXIO; +	} + +	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	regs = devm_ioremap_resource(dev, res_mem); +	if (IS_ERR(regs)) +		return PTR_ERR(regs); + +	clk = devm_clk_get(dev, "hsspi"); + +	if (IS_ERR(clk)) +		return PTR_ERR(clk); + +	rate = clk_get_rate(clk); +	if (!rate) +		return -EINVAL; + +	ret = clk_prepare_enable(clk); +	if (ret) +		return ret; + +	master = spi_alloc_master(&pdev->dev, sizeof(*bs)); +	if (!master) { +		ret = -ENOMEM; +		goto out_disable_clk; +	} + +	bs = spi_master_get_devdata(master); +	bs->pdev = pdev; +	bs->clk = clk; +	bs->regs = regs; +	bs->speed_hz = rate; +	bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); + +	mutex_init(&bs->bus_mutex); +	init_completion(&bs->done); + +	master->bus_num = HSSPI_BUS_NUM; +	master->num_chipselect = 8; +	master->setup = bcm63xx_hsspi_setup; +	master->transfer_one_message = bcm63xx_hsspi_transfer_one; +	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; +	master->bits_per_word_mask = SPI_BPW_MASK(8); +	master->auto_runtime_pm = true; + +	platform_set_drvdata(pdev, master); + +	/* Initialize the hardware */ +	__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); + +	/* clean up any pending interrupts */ +	__raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG); + +	/* read out default CS polarities */ +	reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); +	bs->cs_polarity = reg & GLOBAL_CTRL_CS_POLARITY_MASK; +	__raw_writel(reg | GLOBAL_CTRL_CLK_GATE_SSOFF, +		     bs->regs + HSSPI_GLOBAL_CTRL_REG); + +	ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED, +			       pdev->name, bs); + +	if (ret) +		goto out_put_master; + +	/* register and we are done */ +	ret = devm_spi_register_master(dev, master); +	if (ret) +		goto out_put_master; + +	return 0; + +out_put_master: +	spi_master_put(master); +out_disable_clk: +	clk_disable_unprepare(clk); +	return ret; +} + + +static int bcm63xx_hsspi_remove(struct platform_device *pdev) +{ +	struct spi_master *master = platform_get_drvdata(pdev); +	struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); + +	/* reset the hardware and block queue progress */ +	__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); +	clk_disable_unprepare(bs->clk); + +	return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int bcm63xx_hsspi_suspend(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); + +	spi_master_suspend(master); +	clk_disable_unprepare(bs->clk); + +	return 0; +} + +static int bcm63xx_hsspi_resume(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); +	int ret; + +	ret = clk_prepare_enable(bs->clk); +	if (ret) +		return ret; + +	spi_master_resume(master); + +	return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend, +			 bcm63xx_hsspi_resume); + +static struct platform_driver bcm63xx_hsspi_driver = { +	.driver = { +		.name	= "bcm63xx-hsspi", +		.owner	= THIS_MODULE, +		.pm	= &bcm63xx_hsspi_pm_ops, +	}, +	.probe		= bcm63xx_hsspi_probe, +	.remove		= bcm63xx_hsspi_remove, +}; + +module_platform_driver(bcm63xx_hsspi_driver); + +MODULE_ALIAS("platform:bcm63xx_hsspi"); +MODULE_DESCRIPTION("Broadcom BCM63xx High Speed SPI Controller driver"); +MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 536b0e36382..8510400e786 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -20,7 +20,6 @@   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/clk.h>  #include <linux/io.h>  #include <linux/module.h> @@ -30,13 +29,10 @@  #include <linux/spi/spi.h>  #include <linux/completion.h>  #include <linux/err.h> -#include <linux/workqueue.h>  #include <linux/pm_runtime.h>  #include <bcm63xx_dev_spi.h> -#define PFX		KBUILD_MODNAME -  #define BCM63XX_SPI_MAX_PREPEND		15  struct bcm63xx_spi { @@ -169,9 +165,7 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,  			       transfer_list);  	} -	len -= prepend_len; - -	init_completion(&bs->done); +	reinit_completion(&bs->done);  	/* Fill in the Message control register */  	msg_ctl = (len << SPI_BYTE_CNT_SHIFT); @@ -205,13 +199,7 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,  	if (!timeout)  		return -ETIMEDOUT; -	/* read out all data */ -	rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); - -	if (do_rx && rx_tail != len) -		return -EIO; - -	if (!rx_tail) +	if (!do_rx)  		return 0;  	len = 0; @@ -345,25 +333,23 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) {  		dev_err(dev, "no irq\n"); -		ret = -ENXIO; -		goto out; +		return -ENXIO;  	} -	clk = clk_get(dev, "spi"); +	clk = devm_clk_get(dev, "spi");  	if (IS_ERR(clk)) {  		dev_err(dev, "no clock for device\n"); -		ret = PTR_ERR(clk); -		goto out; +		return PTR_ERR(clk);  	}  	master = spi_alloc_master(dev, sizeof(*bs));  	if (!master) {  		dev_err(dev, "out of memory\n"); -		ret = -ENOMEM; -		goto out_clk; +		return -ENOMEM;  	}  	bs = spi_master_get_devdata(master); +	init_completion(&bs->done);  	platform_set_drvdata(pdev, master);  	bs->pdev = pdev; @@ -408,11 +394,14 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)  	}  	/* Initialize hardware */ -	clk_prepare_enable(bs->clk); +	ret = clk_prepare_enable(bs->clk); +	if (ret) +		goto out_err; +  	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);  	/* register and we are done */ -	ret = spi_register_master(master); +	ret = devm_spi_register_master(dev, master);  	if (ret) {  		dev_err(dev, "spi register failed\n");  		goto out_clk_disable; @@ -427,32 +416,24 @@ out_clk_disable:  	clk_disable_unprepare(clk);  out_err:  	spi_master_put(master); -out_clk: -	clk_put(clk); -out:  	return ret;  }  static int bcm63xx_spi_remove(struct platform_device *pdev)  { -	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); +	struct spi_master *master = platform_get_drvdata(pdev);  	struct bcm63xx_spi *bs = spi_master_get_devdata(master); -	spi_unregister_master(master); -  	/* reset spi block */  	bcm_spi_writeb(bs, 0, SPI_INT_MASK);  	/* HW shutdown */  	clk_disable_unprepare(bs->clk); -	clk_put(bs->clk); - -	spi_master_put(master);  	return 0;  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int bcm63xx_spi_suspend(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev); @@ -469,29 +450,27 @@ static int bcm63xx_spi_resume(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev);  	struct bcm63xx_spi *bs = spi_master_get_devdata(master); +	int ret; -	clk_prepare_enable(bs->clk); +	ret = clk_prepare_enable(bs->clk); +	if (ret) +		return ret;  	spi_master_resume(master);  	return 0;  } +#endif  static const struct dev_pm_ops bcm63xx_spi_pm_ops = { -	.suspend	= bcm63xx_spi_suspend, -	.resume		= bcm63xx_spi_resume, +	SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_spi_suspend, bcm63xx_spi_resume)  }; -#define BCM63XX_SPI_PM_OPS	(&bcm63xx_spi_pm_ops) -#else -#define BCM63XX_SPI_PM_OPS	NULL -#endif -  static struct platform_driver bcm63xx_spi_driver = {  	.driver = {  		.name	= "bcm63xx-spi",  		.owner	= THIS_MODULE, -		.pm	= BCM63XX_SPI_PM_OPS, +		.pm	= &bcm63xx_spi_pm_ops,  	},  	.probe		= bcm63xx_spi_probe,  	.remove		= bcm63xx_spi_remove, diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index 91921b5f581..f515c5e9db5 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -8,7 +8,6 @@   * Licensed under the GPL-2 or later.   */ -#include <linux/init.h>  #include <linux/module.h>  #include <linux/delay.h>  #include <linux/device.h> @@ -592,7 +591,7 @@ bfin_sport_spi_setup(struct spi_device *spi)  			 */  			if (chip_info->ctl_reg || chip_info->enable_dma) {  				ret = -EINVAL; -				dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields"); +				dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields\n");  				goto error;  			}  			chip->cs_chg_udelay = chip_info->cs_chg_udelay; @@ -879,11 +878,10 @@ static int bfin_sport_spi_remove(struct platform_device *pdev)  	return 0;  } -#ifdef CONFIG_PM -static int -bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int bfin_sport_spi_suspend(struct device *dev)  { -	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); +	struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);  	int status;  	status = bfin_sport_spi_stop_queue(drv_data); @@ -896,10 +894,9 @@ bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)  	return status;  } -static int -bfin_sport_spi_resume(struct platform_device *pdev) +static int bfin_sport_spi_resume(struct device *dev)  { -	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); +	struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);  	int status;  	/* Enable the SPI interface */ @@ -912,19 +909,22 @@ bfin_sport_spi_resume(struct platform_device *pdev)  	return status;  } + +static SIMPLE_DEV_PM_OPS(bfin_sport_spi_pm_ops, bfin_sport_spi_suspend, +			bfin_sport_spi_resume); + +#define BFIN_SPORT_SPI_PM_OPS		(&bfin_sport_spi_pm_ops)  #else -# define bfin_sport_spi_suspend NULL -# define bfin_sport_spi_resume  NULL +#define BFIN_SPORT_SPI_PM_OPS		NULL  #endif  static struct platform_driver bfin_sport_spi_driver = {  	.driver	= { -		.name = DRV_NAME, -		.owner = THIS_MODULE, +		.name	= DRV_NAME, +		.owner	= THIS_MODULE, +		.pm	= BFIN_SPORT_SPI_PM_OPS,  	},  	.probe   = bfin_sport_spi_probe,  	.remove  = bfin_sport_spi_remove, -	.suspend = bfin_sport_spi_suspend, -	.resume  = bfin_sport_spi_resume,  };  module_platform_driver(bfin_sport_spi_driver); diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index 45bdf73d686..ebf720b88a2 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -12,6 +12,7 @@  #include <linux/module.h>  #include <linux/delay.h>  #include <linux/device.h> +#include <linux/gpio.h>  #include <linux/slab.h>  #include <linux/io.h>  #include <linux/ioport.h> @@ -350,7 +351,6 @@ static void *bfin_spi_next_transfer(struct bfin_spi_master_data *drv_data)  static void bfin_spi_giveback(struct bfin_spi_master_data *drv_data)  {  	struct bfin_spi_slave_data *chip = drv_data->cur_chip; -	struct spi_transfer *last_transfer;  	unsigned long flags;  	struct spi_message *msg; @@ -362,9 +362,6 @@ static void bfin_spi_giveback(struct bfin_spi_master_data *drv_data)  	queue_work(drv_data->workqueue, &drv_data->pump_messages);  	spin_unlock_irqrestore(&drv_data->lock, flags); -	last_transfer = list_entry(msg->transfers.prev, -				   struct spi_transfer, transfer_list); -  	msg->state = NULL;  	if (!drv_data->cs_change) @@ -524,7 +521,7 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id)  	timeout = jiffies + HZ;  	while (!(bfin_read(&drv_data->regs->stat) & BIT_STAT_SPIF))  		if (!time_before(jiffies, timeout)) { -			dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF"); +			dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF\n");  			break;  		} else  			cpu_relax(); @@ -913,8 +910,9 @@ static void bfin_spi_pump_messages(struct work_struct *work)  	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,  					    struct spi_transfer, transfer_list); -	dev_dbg(&drv_data->pdev->dev, "got a message to pump, " -		"state is set to: baud %d, flag 0x%x, ctl 0x%x\n", +	dev_dbg(&drv_data->pdev->dev, +		"got a message to pump, state is set to: baud " +		"%d, flag 0x%x, ctl 0x%x\n",  		drv_data->cur_chip->baud, drv_data->cur_chip->flag,  		drv_data->cur_chip->ctl_reg); @@ -1013,8 +1011,8 @@ static int bfin_spi_setup(struct spi_device *spi)  		 * but let's assume (for now) they do.  		 */  		if (chip_info->ctl_reg & ~bfin_ctl_reg) { -			dev_err(&spi->dev, "do not set bits in ctl_reg " -				"that the SPI framework manages\n"); +			dev_err(&spi->dev, +				"do not set bits in ctl_reg that the SPI framework manages\n");  			goto error;  		}  		chip->enable_dma = chip_info->enable_dma != 0 @@ -1029,10 +1027,6 @@ static int bfin_spi_setup(struct spi_device *spi)  	}  	/* translate common spi framework into our register */ -	if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) { -		dev_err(&spi->dev, "unsupported spi modes detected\n"); -		goto error; -	}  	if (spi->mode & SPI_CPOL)  		chip->ctl_reg |= BIT_CTL_CPOL;  	if (spi->mode & SPI_CPHA) @@ -1050,17 +1044,17 @@ static int bfin_spi_setup(struct spi_device *spi)  	chip->chip_select_num = spi->chip_select;  	if (chip->chip_select_num < MAX_CTRL_CS) {  		if (!(spi->mode & SPI_CPHA)) -			dev_warn(&spi->dev, "Warning: SPI CPHA not set:" -				" Slave Select not under software control!\n" -				" See Documentation/blackfin/bfin-spi-notes.txt"); +			dev_warn(&spi->dev, +				"Warning: SPI CPHA not set: Slave Select not under software control!\n" +				"See Documentation/blackfin/bfin-spi-notes.txt\n");  		chip->flag = (1 << spi->chip_select) << 8;  	} else  		chip->cs_gpio = chip->chip_select_num - MAX_CTRL_CS;  	if (chip->enable_dma && chip->pio_interrupt) { -		dev_err(&spi->dev, "enable_dma is set, " -				"do not set pio_interrupt\n"); +		dev_err(&spi->dev, +			"enable_dma is set, do not set pio_interrupt\n");  		goto error;  	}  	/* @@ -1410,10 +1404,10 @@ static int bfin_spi_remove(struct platform_device *pdev)  	return 0;  } -#ifdef CONFIG_PM -static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int bfin_spi_suspend(struct device *dev)  { -	struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev); +	struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev);  	int status = 0;  	status = bfin_spi_stop_queue(drv_data); @@ -1432,9 +1426,9 @@ static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state)  	return 0;  } -static int bfin_spi_resume(struct platform_device *pdev) +static int bfin_spi_resume(struct device *dev)  { -	struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev); +	struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev);  	int status = 0;  	bfin_write(&drv_data->regs->ctl, drv_data->ctrl_reg); @@ -1443,31 +1437,34 @@ static int bfin_spi_resume(struct platform_device *pdev)  	/* Start the queue running */  	status = bfin_spi_start_queue(drv_data);  	if (status != 0) { -		dev_err(&pdev->dev, "problem starting queue (%d)\n", status); +		dev_err(dev, "problem starting queue (%d)\n", status);  		return status;  	}  	return 0;  } + +static SIMPLE_DEV_PM_OPS(bfin_spi_pm_ops, bfin_spi_suspend, bfin_spi_resume); + +#define BFIN_SPI_PM_OPS		(&bfin_spi_pm_ops)  #else -#define bfin_spi_suspend NULL -#define bfin_spi_resume NULL -#endif				/* CONFIG_PM */ +#define BFIN_SPI_PM_OPS		NULL +#endif  MODULE_ALIAS("platform:bfin-spi");  static struct platform_driver bfin_spi_driver = {  	.driver	= {  		.name	= DRV_NAME,  		.owner	= THIS_MODULE, +		.pm	= BFIN_SPI_PM_OPS,  	}, -	.suspend	= bfin_spi_suspend, -	.resume		= bfin_spi_resume, +	.probe		= bfin_spi_probe,  	.remove		= bfin_spi_remove,  };  static int __init bfin_spi_init(void)  { -	return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe); +	return platform_driver_register(&bfin_spi_driver);  }  subsys_initcall(bfin_spi_init); diff --git a/drivers/spi/spi-bitbang-txrx.h b/drivers/spi/spi-bitbang-txrx.h index c16bf853c3e..c616e41521b 100644 --- a/drivers/spi/spi-bitbang-txrx.h +++ b/drivers/spi/spi-bitbang-txrx.h @@ -38,7 +38,7 @@   *   * Since this is software, the timings may not be exactly what your board's   * chips need ... there may be several reasons you'd need to tweak timings - * in these routines, not just make to make it faster or slower to match a + * in these routines, not just to make it faster or slower to match a   * particular CPU clock rate.   */ diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 8c11355dec2..dc7d2c2d643 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -16,7 +16,6 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */ -#include <linux/init.h>  #include <linux/spinlock.h>  #include <linux/workqueue.h>  #include <linux/interrupt.h> @@ -191,7 +190,7 @@ int spi_bitbang_setup(struct spi_device *spi)  	bitbang = spi_master_get_devdata(spi->master);  	if (!cs) { -		cs = kzalloc(sizeof *cs, GFP_KERNEL); +		cs = kzalloc(sizeof(*cs), GFP_KERNEL);  		if (!cs)  			return -ENOMEM;  		spi->controller_state = cs; @@ -258,7 +257,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)  static int spi_bitbang_prepare_hardware(struct spi_master *spi)  { -	struct spi_bitbang 	*bitbang; +	struct spi_bitbang	*bitbang;  	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi); @@ -273,7 +272,7 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi)  static int spi_bitbang_transfer_one(struct spi_master *master,  				    struct spi_message *m)  { -	struct spi_bitbang 	*bitbang; +	struct spi_bitbang	*bitbang;  	unsigned		nsecs;  	struct spi_transfer	*t = NULL;  	unsigned		cs_change; @@ -292,7 +291,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  	cs_change = 1;  	status = 0; -	list_for_each_entry (t, &m->transfers, transfer_list) { +	list_for_each_entry(t, &m->transfers, transfer_list) {  		/* override speed or wordsize? */  		if (t->speed_hz || t->bits_per_word) @@ -349,7 +348,8 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  		if (t->delay_usecs)  			udelay(t->delay_usecs); -		if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { +		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  			 */ @@ -378,7 +378,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  static int spi_bitbang_unprepare_hardware(struct spi_master *spi)  { -	struct spi_bitbang 	*bitbang; +	struct spi_bitbang	*bitbang;  	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi); @@ -414,10 +414,16 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi)   * This routine registers the spi_master, which will process requests in a   * dedicated task, keeping IRQs unblocked most of the time.  To stop   * processing those requests, call spi_bitbang_stop(). + * + * On success, this routine will take a reference to master. The caller is + * responsible for calling spi_bitbang_stop() to decrement the reference and + * spi_master_put() as counterpart of spi_alloc_master() to prevent a memory + * leak.   */  int spi_bitbang_start(struct spi_bitbang *bitbang)  {  	struct spi_master *master = bitbang->master; +	int ret;  	if (!master || !bitbang->chipselect)  		return -EINVAL; @@ -449,18 +455,20 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)  	/* driver may get busy before register() returns, especially  	 * if someone registered boardinfo for devices  	 */ -	return spi_register_master(master); +	ret = spi_register_master(spi_master_get(master)); +	if (ret) +		spi_master_put(master); + +	return 0;  }  EXPORT_SYMBOL_GPL(spi_bitbang_start);  /**   * spi_bitbang_stop - stops the task providing spi communication   */ -int spi_bitbang_stop(struct spi_bitbang *bitbang) +void spi_bitbang_stop(struct spi_bitbang *bitbang)  {  	spi_unregister_master(bitbang->master); - -	return 0;  }  EXPORT_SYMBOL_GPL(spi_bitbang_stop); diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 5ed08e53743..ee4f91ccd8f 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c @@ -147,8 +147,8 @@ static void butterfly_chipselect(struct spi_device *spi, int value)  /* we only needed to implement one mode here, and choose SPI_MODE_0 */ -#define	spidelay(X)	do{}while(0) -//#define	spidelay	ndelay +#define spidelay(X)	do { } while (0) +/* #define spidelay	ndelay */  #include "spi-bitbang-txrx.h" @@ -171,15 +171,15 @@ static struct mtd_partition partitions[] = { {  	/* sector 0 = 8 pages * 264 bytes/page (1 block)  	 * sector 1 = 248 pages * 264 bytes/page  	 */ -	.name		= "bookkeeping",	// 66 KB +	.name		= "bookkeeping",	/* 66 KB */  	.offset		= 0,  	.size		= (8 + 248) * 264, -//	.mask_flags	= MTD_WRITEABLE, +	/* .mask_flags	= MTD_WRITEABLE, */  }, {  	/* sector 2 = 256 pages * 264 bytes/page  	 * sectors 3-5 = 512 pages * 264 bytes/page  	 */ -	.name		= "filesystem",		// 462 KB +	.name		= "filesystem",		/* 462 KB */  	.offset		= MTDPART_OFS_APPEND,  	.size		= MTDPART_SIZ_FULL,  } }; @@ -209,7 +209,7 @@ static void butterfly_attach(struct parport *p)  	 * and no way to be selective about what it binds to.  	 */ -	master = spi_alloc_master(dev, sizeof *pp); +	master = spi_alloc_master(dev, sizeof(*pp));  	if (!master) {  		status = -ENOMEM;  		goto done; @@ -225,7 +225,7 @@ static void butterfly_attach(struct parport *p)  	master->bus_num = 42;  	master->num_chipselect = 2; -	pp->bitbang.master = spi_master_get(master); +	pp->bitbang.master = master;  	pp->bitbang.chipselect = butterfly_chipselect;  	pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0; @@ -289,7 +289,6 @@ static void butterfly_attach(struct parport *p)  		pr_debug("%s: dataflash at %s\n", p->name,  				dev_name(&pp->dataflash->dev)); -	// dev_info(_what?_, ...)  	pr_info("%s: AVR Butterfly\n", p->name);  	butterfly = pp;  	return; @@ -310,7 +309,6 @@ done:  static void butterfly_detach(struct parport *p)  {  	struct butterfly	*pp; -	int			status;  	/* FIXME this global is ugly ... but, how to quickly get from  	 * the parport to the "struct butterfly" associated with it? @@ -322,7 +320,7 @@ static void butterfly_detach(struct parport *p)  	butterfly = NULL;  	/* stop() unregisters child devices too */ -	status = spi_bitbang_stop(&pp->bitbang); +	spi_bitbang_stop(&pp->bitbang);  	/* turn off VCC */  	parport_write_data(pp->port, 0); diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c new file mode 100644 index 00000000000..bb758978465 --- /dev/null +++ b/drivers/spi/spi-cadence.c @@ -0,0 +1,673 @@ +/* + * Cadence SPI controller driver (master mode only) + * + * Copyright (C) 2008 - 2014 Xilinx, Inc. + * + * based on Blackfin On-Chip SPI Driver (spi_bfin5xx.c) + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> + +/* Name of this driver */ +#define CDNS_SPI_NAME		"cdns-spi" + +/* Register offset definitions */ +#define CDNS_SPI_CR_OFFSET	0x00 /* Configuration  Register, RW */ +#define CDNS_SPI_ISR_OFFSET	0x04 /* Interrupt Status Register, RO */ +#define CDNS_SPI_IER_OFFSET	0x08 /* Interrupt Enable Register, WO */ +#define CDNS_SPI_IDR_OFFSET	0x0c /* Interrupt Disable Register, WO */ +#define CDNS_SPI_IMR_OFFSET	0x10 /* Interrupt Enabled Mask Register, RO */ +#define CDNS_SPI_ER_OFFSET	0x14 /* Enable/Disable Register, RW */ +#define CDNS_SPI_DR_OFFSET	0x18 /* Delay Register, RW */ +#define CDNS_SPI_TXD_OFFSET	0x1C /* Data Transmit Register, WO */ +#define CDNS_SPI_RXD_OFFSET	0x20 /* Data Receive Register, RO */ +#define CDNS_SPI_SICR_OFFSET	0x24 /* Slave Idle Count Register, RW */ +#define CDNS_SPI_THLD_OFFSET	0x28 /* Transmit FIFO Watermark Register,RW */ + +/* + * SPI Configuration Register bit Masks + * + * This register contains various control bits that affect the operation + * of the SPI controller + */ +#define CDNS_SPI_CR_MANSTRT_MASK	0x00010000 /* Manual TX Start */ +#define CDNS_SPI_CR_CPHA_MASK		0x00000004 /* Clock Phase Control */ +#define CDNS_SPI_CR_CPOL_MASK		0x00000002 /* Clock Polarity Control */ +#define CDNS_SPI_CR_SSCTRL_MASK		0x00003C00 /* Slave Select Mask */ +#define CDNS_SPI_CR_BAUD_DIV_MASK	0x00000038 /* Baud Rate Divisor Mask */ +#define CDNS_SPI_CR_MSTREN_MASK		0x00000001 /* Master Enable Mask */ +#define CDNS_SPI_CR_MANSTRTEN_MASK	0x00008000 /* Manual TX Enable Mask */ +#define CDNS_SPI_CR_SSFORCE_MASK	0x00004000 /* Manual SS Enable Mask */ +#define CDNS_SPI_CR_BAUD_DIV_4_MASK	0x00000008 /* Default Baud Div Mask */ +#define CDNS_SPI_CR_DEFAULT_MASK	(CDNS_SPI_CR_MSTREN_MASK | \ +					CDNS_SPI_CR_SSCTRL_MASK | \ +					CDNS_SPI_CR_SSFORCE_MASK | \ +					CDNS_SPI_CR_BAUD_DIV_4_MASK) + +/* + * SPI Configuration Register - Baud rate and slave select + * + * These are the values used in the calculation of baud rate divisor and + * setting the slave select. + */ + +#define CDNS_SPI_BAUD_DIV_MAX		7 /* Baud rate divisor maximum */ +#define CDNS_SPI_BAUD_DIV_MIN		1 /* Baud rate divisor minimum */ +#define CDNS_SPI_BAUD_DIV_SHIFT		3 /* Baud rate divisor shift in CR */ +#define CDNS_SPI_SS_SHIFT		10 /* Slave Select field shift in CR */ +#define CDNS_SPI_SS0			0x1 /* Slave Select zero */ + +/* + * SPI Interrupt Registers bit Masks + * + * All the four interrupt registers (Status/Mask/Enable/Disable) have the same + * bit definitions. + */ +#define CDNS_SPI_IXR_TXOW_MASK	0x00000004 /* SPI TX FIFO Overwater */ +#define CDNS_SPI_IXR_MODF_MASK	0x00000002 /* SPI Mode Fault */ +#define CDNS_SPI_IXR_RXNEMTY_MASK 0x00000010 /* SPI RX FIFO Not Empty */ +#define CDNS_SPI_IXR_DEFAULT_MASK	(CDNS_SPI_IXR_TXOW_MASK | \ +					CDNS_SPI_IXR_MODF_MASK) +#define CDNS_SPI_IXR_TXFULL_MASK	0x00000008 /* SPI TX Full */ +#define CDNS_SPI_IXR_ALL_MASK	0x0000007F /* SPI all interrupts */ + +/* + * SPI Enable Register bit Masks + * + * This register is used to enable or disable the SPI controller + */ +#define CDNS_SPI_ER_ENABLE_MASK	0x00000001 /* SPI Enable Bit Mask */ +#define CDNS_SPI_ER_DISABLE_MASK	0x0 /* SPI Disable Bit Mask */ + +/* SPI FIFO depth in bytes */ +#define CDNS_SPI_FIFO_DEPTH	128 + +/* Default number of chip select lines */ +#define CDNS_SPI_DEFAULT_NUM_CS		4 + +/** + * struct cdns_spi - This definition defines spi driver instance + * @regs:		Virtual address of the SPI controller registers + * @ref_clk:		Pointer to the peripheral clock + * @pclk:		Pointer to the APB clock + * @speed_hz:		Current SPI bus clock speed in Hz + * @txbuf:		Pointer	to the TX buffer + * @rxbuf:		Pointer to the RX buffer + * @tx_bytes:		Number of bytes left to transfer + * @rx_bytes:		Number of bytes requested + * @dev_busy:		Device busy flag + * @is_decoded_cs:	Flag for decoder property set or not + */ +struct cdns_spi { +	void __iomem *regs; +	struct clk *ref_clk; +	struct clk *pclk; +	u32 speed_hz; +	const u8 *txbuf; +	u8 *rxbuf; +	int tx_bytes; +	int rx_bytes; +	u8 dev_busy; +	u32 is_decoded_cs; +}; + +/* Macros for the SPI controller read/write */ +static inline u32 cdns_spi_read(struct cdns_spi *xspi, u32 offset) +{ +	return readl_relaxed(xspi->regs + offset); +} + +static inline void cdns_spi_write(struct cdns_spi *xspi, u32 offset, u32 val) +{ +	writel_relaxed(val, xspi->regs + offset); +} + +/** + * cdns_spi_init_hw - Initialize the hardware and configure the SPI controller + * @xspi:	Pointer to the cdns_spi structure + * + * On reset the SPI controller is configured to be in master mode, baud rate + * divisor is set to 4, threshold value for TX FIFO not full interrupt is set + * to 1 and size of the word to be transferred as 8 bit. + * This function initializes the SPI controller to disable and clear all the + * interrupts, enable manual slave select and manual start, deselect all the + * chip select lines, and enable the SPI controller. + */ +static void cdns_spi_init_hw(struct cdns_spi *xspi) +{ +	cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, +		       CDNS_SPI_ER_DISABLE_MASK); +	cdns_spi_write(xspi, CDNS_SPI_IDR_OFFSET, +		       CDNS_SPI_IXR_ALL_MASK); + +	/* Clear the RX FIFO */ +	while (cdns_spi_read(xspi, CDNS_SPI_ISR_OFFSET) & +	       CDNS_SPI_IXR_RXNEMTY_MASK) +		cdns_spi_read(xspi, CDNS_SPI_RXD_OFFSET); + +	cdns_spi_write(xspi, CDNS_SPI_ISR_OFFSET, +		       CDNS_SPI_IXR_ALL_MASK); +	cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, +		       CDNS_SPI_CR_DEFAULT_MASK); +	cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, +		       CDNS_SPI_ER_ENABLE_MASK); +} + +/** + * cdns_spi_chipselect - Select or deselect the chip select line + * @spi:	Pointer to the spi_device structure + * @is_on:	Select(0) or deselect (1) the chip select line + */ +static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(spi->master); +	u32 ctrl_reg; + +	ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); + +	if (is_high) { +		/* Deselect the slave */ +		ctrl_reg |= CDNS_SPI_CR_SSCTRL_MASK; +	} else { +		/* Select the slave */ +		ctrl_reg &= ~CDNS_SPI_CR_SSCTRL_MASK; +		if (!(xspi->is_decoded_cs)) +			ctrl_reg |= ((~(CDNS_SPI_SS0 << spi->chip_select)) << +				     CDNS_SPI_SS_SHIFT) & +				     CDNS_SPI_CR_SSCTRL_MASK; +		else +			ctrl_reg |= (spi->chip_select << CDNS_SPI_SS_SHIFT) & +				     CDNS_SPI_CR_SSCTRL_MASK; +	} + +	cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg); +} + +/** + * cdns_spi_config_clock_mode - Sets clock polarity and phase + * @spi:	Pointer to the spi_device structure + * + * Sets the requested clock polarity and phase. + */ +static void cdns_spi_config_clock_mode(struct spi_device *spi) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(spi->master); +	u32 ctrl_reg; + +	ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); + +	/* Set the SPI clock phase and clock polarity */ +	ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK); +	if (spi->mode & SPI_CPHA) +		ctrl_reg |= CDNS_SPI_CR_CPHA_MASK; +	if (spi->mode & SPI_CPOL) +		ctrl_reg |= CDNS_SPI_CR_CPOL_MASK; + +	cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg); +} + +/** + * cdns_spi_config_clock_freq - Sets clock frequency + * @spi:	Pointer to the spi_device structure + * @transfer:	Pointer to the spi_transfer structure which provides + *		information about next transfer setup parameters + * + * Sets the requested clock frequency. + * Note: If the requested frequency is not an exact match with what can be + * obtained using the prescalar value the driver sets the clock frequency which + * is lower than the requested frequency (maximum lower) for the transfer. If + * the requested frequency is higher or lower than that is supported by the SPI + * controller the driver will set the highest or lowest frequency supported by + * controller. + */ +static void cdns_spi_config_clock_freq(struct spi_device *spi, +				  struct spi_transfer *transfer) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(spi->master); +	u32 ctrl_reg, baud_rate_val; +	unsigned long frequency; + +	frequency = clk_get_rate(xspi->ref_clk); + +	ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); + +	/* Set the clock frequency */ +	if (xspi->speed_hz != transfer->speed_hz) { +		/* first valid value is 1 */ +		baud_rate_val = CDNS_SPI_BAUD_DIV_MIN; +		while ((baud_rate_val < CDNS_SPI_BAUD_DIV_MAX) && +		       (frequency / (2 << baud_rate_val)) > transfer->speed_hz) +			baud_rate_val++; + +		ctrl_reg &= ~CDNS_SPI_CR_BAUD_DIV_MASK; +		ctrl_reg |= baud_rate_val << CDNS_SPI_BAUD_DIV_SHIFT; + +		xspi->speed_hz = frequency / (2 << baud_rate_val); +	} +	cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg); +} + +/** + * cdns_spi_setup_transfer - Configure SPI controller for specified transfer + * @spi:	Pointer to the spi_device structure + * @transfer:	Pointer to the spi_transfer structure which provides + *		information about next transfer setup parameters + * + * Sets the operational mode of SPI controller for the next SPI transfer and + * sets the requested clock frequency. + * + * Return:	Always 0 + */ +static int cdns_spi_setup_transfer(struct spi_device *spi, +				   struct spi_transfer *transfer) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(spi->master); + +	cdns_spi_config_clock_freq(spi, transfer); + +	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u clock speed\n", +		__func__, spi->mode, spi->bits_per_word, +		xspi->speed_hz); + +	return 0; +} + +/** + * cdns_spi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible + * @xspi:	Pointer to the cdns_spi structure + */ +static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi) +{ +	unsigned long trans_cnt = 0; + +	while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) && +	       (xspi->tx_bytes > 0)) { +		if (xspi->txbuf) +			cdns_spi_write(xspi, CDNS_SPI_TXD_OFFSET, +				       *xspi->txbuf++); +		else +			cdns_spi_write(xspi, CDNS_SPI_TXD_OFFSET, 0); + +		xspi->tx_bytes--; +		trans_cnt++; +	} +} + +/** + * cdns_spi_irq - Interrupt service routine of the SPI controller + * @irq:	IRQ number + * @dev_id:	Pointer to the xspi structure + * + * This function handles TX empty and Mode Fault interrupts only. + * On TX empty interrupt this function reads the received data from RX FIFO and + * fills the TX FIFO if there is any data remaining to be transferred. + * On Mode Fault interrupt this function indicates that transfer is completed, + * the SPI subsystem will identify the error as the remaining bytes to be + * transferred is non-zero. + * + * Return:	IRQ_HANDLED when handled; IRQ_NONE otherwise. + */ +static irqreturn_t cdns_spi_irq(int irq, void *dev_id) +{ +	struct spi_master *master = dev_id; +	struct cdns_spi *xspi = spi_master_get_devdata(master); +	u32 intr_status, status; + +	status = IRQ_NONE; +	intr_status = cdns_spi_read(xspi, CDNS_SPI_ISR_OFFSET); +	cdns_spi_write(xspi, CDNS_SPI_ISR_OFFSET, intr_status); + +	if (intr_status & CDNS_SPI_IXR_MODF_MASK) { +		/* Indicate that transfer is completed, the SPI subsystem will +		 * identify the error as the remaining bytes to be +		 * transferred is non-zero +		 */ +		cdns_spi_write(xspi, CDNS_SPI_IDR_OFFSET, +			       CDNS_SPI_IXR_DEFAULT_MASK); +		spi_finalize_current_transfer(master); +		status = IRQ_HANDLED; +	} else if (intr_status & CDNS_SPI_IXR_TXOW_MASK) { +		unsigned long trans_cnt; + +		trans_cnt = xspi->rx_bytes - xspi->tx_bytes; + +		/* Read out the data from the RX FIFO */ +		while (trans_cnt) { +			u8 data; + +			data = cdns_spi_read(xspi, CDNS_SPI_RXD_OFFSET); +			if (xspi->rxbuf) +				*xspi->rxbuf++ = data; + +			xspi->rx_bytes--; +			trans_cnt--; +		} + +		if (xspi->tx_bytes) { +			/* There is more data to send */ +			cdns_spi_fill_tx_fifo(xspi); +		} else { +			/* Transfer is completed */ +			cdns_spi_write(xspi, CDNS_SPI_IDR_OFFSET, +				       CDNS_SPI_IXR_DEFAULT_MASK); +			spi_finalize_current_transfer(master); +		} +		status = IRQ_HANDLED; +	} + +	return status; +} + +/** + * cdns_transfer_one - Initiates the SPI transfer + * @master:	Pointer to spi_master structure + * @spi:	Pointer to the spi_device structure + * @transfer:	Pointer to the spi_transfer structure which provides + *		information about next transfer parameters + * + * This function fills the TX FIFO, starts the SPI transfer and + * returns a positive transfer count so that core will wait for completion. + * + * Return:	Number of bytes transferred in the last transfer + */ +static int cdns_transfer_one(struct spi_master *master, +			     struct spi_device *spi, +			     struct spi_transfer *transfer) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(master); + +	xspi->txbuf = transfer->tx_buf; +	xspi->rxbuf = transfer->rx_buf; +	xspi->tx_bytes = transfer->len; +	xspi->rx_bytes = transfer->len; + +	cdns_spi_setup_transfer(spi, transfer); + +	cdns_spi_fill_tx_fifo(xspi); + +	cdns_spi_write(xspi, CDNS_SPI_IER_OFFSET, +		       CDNS_SPI_IXR_DEFAULT_MASK); +	return transfer->len; +} + +/** + * cdns_prepare_transfer_hardware - Prepares hardware for transfer. + * @master:	Pointer to the spi_master structure which provides + *		information about the controller. + * + * This function enables SPI master controller. + * + * Return:	0 always + */ +static int cdns_prepare_transfer_hardware(struct spi_master *master) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(master); + +	cdns_spi_config_clock_mode(master->cur_msg->spi); + +	cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, +		       CDNS_SPI_ER_ENABLE_MASK); + +	return 0; +} + +/** + * cdns_unprepare_transfer_hardware - Relaxes hardware after transfer + * @master:	Pointer to the spi_master structure which provides + *		information about the controller. + * + * This function disables the SPI master controller. + * + * Return:	0 always + */ +static int cdns_unprepare_transfer_hardware(struct spi_master *master) +{ +	struct cdns_spi *xspi = spi_master_get_devdata(master); + +	cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, +		       CDNS_SPI_ER_DISABLE_MASK); + +	return 0; +} + +/** + * cdns_spi_probe - Probe method for the SPI driver + * @pdev:	Pointer to the platform_device structure + * + * This function initializes the driver data structures and the hardware. + * + * Return:	0 on success and error value on error + */ +static int cdns_spi_probe(struct platform_device *pdev) +{ +	int ret = 0, irq; +	struct spi_master *master; +	struct cdns_spi *xspi; +	struct resource *res; +	u32 num_cs; + +	master = spi_alloc_master(&pdev->dev, sizeof(*xspi)); +	if (master == NULL) +		return -ENOMEM; + +	xspi = spi_master_get_devdata(master); +	master->dev.of_node = pdev->dev.of_node; +	platform_set_drvdata(pdev, master); + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	xspi->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(xspi->regs)) { +		ret = PTR_ERR(xspi->regs); +		goto remove_master; +	} + +	xspi->pclk = devm_clk_get(&pdev->dev, "pclk"); +	if (IS_ERR(xspi->pclk)) { +		dev_err(&pdev->dev, "pclk clock not found.\n"); +		ret = PTR_ERR(xspi->pclk); +		goto remove_master; +	} + +	xspi->ref_clk = devm_clk_get(&pdev->dev, "ref_clk"); +	if (IS_ERR(xspi->ref_clk)) { +		dev_err(&pdev->dev, "ref_clk clock not found.\n"); +		ret = PTR_ERR(xspi->ref_clk); +		goto remove_master; +	} + +	ret = clk_prepare_enable(xspi->pclk); +	if (ret) { +		dev_err(&pdev->dev, "Unable to enable APB clock.\n"); +		goto remove_master; +	} + +	ret = clk_prepare_enable(xspi->ref_clk); +	if (ret) { +		dev_err(&pdev->dev, "Unable to enable device clock.\n"); +		goto clk_dis_apb; +	} + +	/* SPI controller initializations */ +	cdns_spi_init_hw(xspi); + +	irq = platform_get_irq(pdev, 0); +	if (irq <= 0) { +		ret = -ENXIO; +		dev_err(&pdev->dev, "irq number is invalid\n"); +		goto remove_master; +	} + +	ret = devm_request_irq(&pdev->dev, irq, cdns_spi_irq, +			       0, pdev->name, master); +	if (ret != 0) { +		ret = -ENXIO; +		dev_err(&pdev->dev, "request_irq failed\n"); +		goto remove_master; +	} + +	ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); + +	if (ret < 0) +		master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; +	else +		master->num_chipselect = num_cs; + +	ret = of_property_read_u32(pdev->dev.of_node, "is-decoded-cs", +				   &xspi->is_decoded_cs); + +	if (ret < 0) +		xspi->is_decoded_cs = 0; + +	master->prepare_transfer_hardware = cdns_prepare_transfer_hardware; +	master->transfer_one = cdns_transfer_one; +	master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; +	master->set_cs = cdns_spi_chipselect; +	master->mode_bits = SPI_CPOL | SPI_CPHA; + +	/* Set to default valid value */ +	master->max_speed_hz = clk_get_rate(xspi->ref_clk) / 4; +	xspi->speed_hz = master->max_speed_hz; + +	master->bits_per_word_mask = SPI_BPW_MASK(8); + +	ret = spi_register_master(master); +	if (ret) { +		dev_err(&pdev->dev, "spi_register_master failed\n"); +		goto clk_dis_all; +	} + +	return ret; + +clk_dis_all: +	clk_disable_unprepare(xspi->ref_clk); +clk_dis_apb: +	clk_disable_unprepare(xspi->pclk); +remove_master: +	spi_master_put(master); +	return ret; +} + +/** + * cdns_spi_remove - Remove method for the SPI driver + * @pdev:	Pointer to the platform_device structure + * + * This function is called if a device is physically removed from the system or + * if the driver module is being unloaded. It frees all resources allocated to + * the device. + * + * Return:	0 on success and error value on error + */ +static int cdns_spi_remove(struct platform_device *pdev) +{ +	struct spi_master *master = platform_get_drvdata(pdev); +	struct cdns_spi *xspi = spi_master_get_devdata(master); + +	cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, +		       CDNS_SPI_ER_DISABLE_MASK); + +	clk_disable_unprepare(xspi->ref_clk); +	clk_disable_unprepare(xspi->pclk); + +	spi_unregister_master(master); + +	return 0; +} + +/** + * cdns_spi_suspend - Suspend method for the SPI driver + * @dev:	Address of the platform_device structure + * + * This function disables the SPI controller and + * changes the driver state to "suspend" + * + * Return:	Always 0 + */ +static int __maybe_unused cdns_spi_suspend(struct device *dev) +{ +	struct platform_device *pdev = container_of(dev, +			struct platform_device, dev); +	struct spi_master *master = platform_get_drvdata(pdev); +	struct cdns_spi *xspi = spi_master_get_devdata(master); + +	spi_master_suspend(master); + +	clk_disable_unprepare(xspi->ref_clk); + +	clk_disable_unprepare(xspi->pclk); + +	return 0; +} + +/** + * cdns_spi_resume - Resume method for the SPI driver + * @dev:	Address of the platform_device structure + * + * This function changes the driver state to "ready" + * + * Return:	0 on success and error value on error + */ +static int __maybe_unused cdns_spi_resume(struct device *dev) +{ +	struct platform_device *pdev = container_of(dev, +			struct platform_device, dev); +	struct spi_master *master = platform_get_drvdata(pdev); +	struct cdns_spi *xspi = spi_master_get_devdata(master); +	int ret = 0; + +	ret = clk_prepare_enable(xspi->pclk); +	if (ret) { +		dev_err(dev, "Cannot enable APB clock.\n"); +		return ret; +	} + +	ret = clk_prepare_enable(xspi->ref_clk); +	if (ret) { +		dev_err(dev, "Cannot enable device clock.\n"); +		clk_disable(xspi->pclk); +		return ret; +	} +	spi_master_resume(master); + +	return 0; +} + +static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend, +			 cdns_spi_resume); + +static struct of_device_id cdns_spi_of_match[] = { +	{ .compatible = "xlnx,zynq-spi-r1p6" }, +	{ .compatible = "cdns,spi-r1p6" }, +	{ /* end of table */ } +}; +MODULE_DEVICE_TABLE(of, cdns_spi_of_match); + +/* cdns_spi_driver - This structure defines the SPI subsystem platform driver */ +static struct platform_driver cdns_spi_driver = { +	.probe	= cdns_spi_probe, +	.remove	= cdns_spi_remove, +	.driver = { +		.name = CDNS_SPI_NAME, +		.owner = THIS_MODULE, +		.of_match_table = cdns_spi_of_match, +		.pm = &cdns_spi_dev_pm_ops, +	}, +}; + +module_platform_driver(cdns_spi_driver); + +MODULE_AUTHOR("Xilinx, Inc."); +MODULE_DESCRIPTION("Cadence SPI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 5655acf55bf..4cd62f63654 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -1,7 +1,7 @@  /*   *  CLPS711X SPI bus driver   * - *  Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + *  Copyright (C) 2012-2014 Alexander Shiyan <shc_work@mail.ru>   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -11,158 +11,125 @@  #include <linux/io.h>  #include <linux/clk.h> -#include <linux/init.h>  #include <linux/gpio.h>  #include <linux/delay.h>  #include <linux/module.h>  #include <linux/interrupt.h>  #include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/clps711x.h>  #include <linux/spi/spi.h>  #include <linux/platform_data/spi-clps711x.h> -#include <mach/hardware.h> -  #define DRIVER_NAME	"spi-clps711x" -struct spi_clps711x_data { -	struct completion	done; +#define SYNCIO_FRMLEN(x)	((x) << 8) +#define SYNCIO_TXFRMEN		(1 << 14) +struct spi_clps711x_data { +	void __iomem		*syncio; +	struct regmap		*syscon; +	struct regmap		*syscon1;  	struct clk		*spi_clk; -	u32			max_speed_hz;  	u8			*tx_buf;  	u8			*rx_buf; -	int			count; +	unsigned int		bpw;  	int			len; - -	int			chipselect[0];  };  static int spi_clps711x_setup(struct spi_device *spi)  { -	struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); -  	/* We are expect that SPI-device is not selected */ -	gpio_direction_output(hw->chipselect[spi->chip_select], -			      !(spi->mode & SPI_CS_HIGH)); +	gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));  	return 0;  } -static void spi_clps711x_setup_mode(struct spi_device *spi) +static void spi_clps711x_setup_xfer(struct spi_device *spi, +				    struct spi_transfer *xfer)  { -	/* Setup edge for transfer */ -	if (spi->mode & SPI_CPHA) -		clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3); -	else -		clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); -} - -static int spi_clps711x_setup_xfer(struct spi_device *spi, -				   struct spi_transfer *xfer) -{ -	u32 speed = xfer->speed_hz ? : spi->max_speed_hz; -	u8 bpw = xfer->bits_per_word; -	struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); - -	if (bpw != 8) { -		dev_err(&spi->dev, "Unsupported master bus width %i\n", bpw); -		return -EINVAL; -	} +	struct spi_master *master = spi->master; +	struct spi_clps711x_data *hw = spi_master_get_devdata(master);  	/* Setup SPI frequency divider */ -	if (!speed || (speed >= hw->max_speed_hz)) -		clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | -			    SYSCON1_ADCKSEL(3), SYSCON1); -	else if (speed >= (hw->max_speed_hz / 2)) -		clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | -			    SYSCON1_ADCKSEL(2), SYSCON1); -	else if (speed >= (hw->max_speed_hz / 8)) -		clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | -			    SYSCON1_ADCKSEL(1), SYSCON1); +	if (xfer->speed_hz >= master->max_speed_hz) +		regmap_update_bits(hw->syscon1, SYSCON_OFFSET, +				   SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(3)); +	else if (xfer->speed_hz >= (master->max_speed_hz / 2)) +		regmap_update_bits(hw->syscon1, SYSCON_OFFSET, +				   SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(2)); +	else if (xfer->speed_hz >= (master->max_speed_hz / 8)) +		regmap_update_bits(hw->syscon1, SYSCON_OFFSET, +				   SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(1));  	else -		clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | -			    SYSCON1_ADCKSEL(0), SYSCON1); - -	return 0; +		regmap_update_bits(hw->syscon1, SYSCON_OFFSET, +				   SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(0));  } -static int spi_clps711x_transfer_one_message(struct spi_master *master, -					     struct spi_message *msg) +static int spi_clps711x_prepare_message(struct spi_master *master, +					struct spi_message *msg)  {  	struct spi_clps711x_data *hw = spi_master_get_devdata(master); -	struct spi_transfer *xfer; -	int status = 0, cs = hw->chipselect[msg->spi->chip_select]; -	u32 data; +	struct spi_device *spi = msg->spi; -	spi_clps711x_setup_mode(msg->spi); - -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		if (spi_clps711x_setup_xfer(msg->spi, xfer)) { -			status = -EINVAL; -			goto out_xfr; -		} - -		gpio_set_value(cs, !!(msg->spi->mode & SPI_CS_HIGH)); - -		INIT_COMPLETION(hw->done); - -		hw->count = 0; -		hw->len = xfer->len; -		hw->tx_buf = (u8 *)xfer->tx_buf; -		hw->rx_buf = (u8 *)xfer->rx_buf; - -		/* Initiate transfer */ -		data = hw->tx_buf ? hw->tx_buf[hw->count] : 0; -		clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); - -		wait_for_completion(&hw->done); +	/* Setup mode for transfer */ +	return regmap_update_bits(hw->syscon, SYSCON_OFFSET, SYSCON3_ADCCKNSEN, +				  (spi->mode & SPI_CPHA) ? +				  SYSCON3_ADCCKNSEN : 0); +} -		if (xfer->delay_usecs) -			udelay(xfer->delay_usecs); +static int spi_clps711x_transfer_one(struct spi_master *master, +				     struct spi_device *spi, +				     struct spi_transfer *xfer) +{ +	struct spi_clps711x_data *hw = spi_master_get_devdata(master); +	u8 data; -		if (xfer->cs_change || -		    list_is_last(&xfer->transfer_list, &msg->transfers)) -			gpio_set_value(cs, !(msg->spi->mode & SPI_CS_HIGH)); +	spi_clps711x_setup_xfer(spi, xfer); -		msg->actual_length += xfer->len; -	} +	hw->len = xfer->len; +	hw->bpw = xfer->bits_per_word; +	hw->tx_buf = (u8 *)xfer->tx_buf; +	hw->rx_buf = (u8 *)xfer->rx_buf; -out_xfr: -	msg->status = status; -	spi_finalize_current_message(master); +	/* Initiate transfer */ +	data = hw->tx_buf ? *hw->tx_buf++ : 0; +	writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, hw->syncio); -	return 0; +	return 1;  }  static irqreturn_t spi_clps711x_isr(int irq, void *dev_id)  { -	struct spi_clps711x_data *hw = (struct spi_clps711x_data *)dev_id; -	u32 data; +	struct spi_master *master = dev_id; +	struct spi_clps711x_data *hw = spi_master_get_devdata(master); +	u8 data;  	/* Handle RX */ -	data = clps_readb(SYNCIO); +	data = readb(hw->syncio);  	if (hw->rx_buf) -		hw->rx_buf[hw->count] = (u8)data; - -	hw->count++; +		*hw->rx_buf++ = data;  	/* Handle TX */ -	if (hw->count < hw->len) { -		data = hw->tx_buf ? hw->tx_buf[hw->count] : 0; -		clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); +	if (--hw->len > 0) { +		data = hw->tx_buf ? *hw->tx_buf++ : 0; +		writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, +		       hw->syncio);  	} else -		complete(&hw->done); +		spi_finalize_current_transfer(master);  	return IRQ_HANDLED;  }  static int spi_clps711x_probe(struct platform_device *pdev)  { -	int i, ret; -	struct spi_master *master;  	struct spi_clps711x_data *hw;  	struct spi_clps711x_pdata *pdata = dev_get_platdata(&pdev->dev); +	struct spi_master *master; +	struct resource *res; +	int i, irq, ret;  	if (!pdata) {  		dev_err(&pdev->dev, "No platform data supplied\n"); @@ -174,33 +141,37 @@ static int spi_clps711x_probe(struct platform_device *pdev)  		return -EINVAL;  	} -	master = spi_alloc_master(&pdev->dev, -				  sizeof(struct spi_clps711x_data) + -				  sizeof(int) * pdata->num_chipselect); -	if (!master) { -		dev_err(&pdev->dev, "SPI allocating memory error\n"); +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) +		return irq; + +	master = spi_alloc_master(&pdev->dev, sizeof(*hw)); +	if (!master)  		return -ENOMEM; + +	master->cs_gpios = devm_kzalloc(&pdev->dev, sizeof(int) * +					pdata->num_chipselect, GFP_KERNEL); +	if (!master->cs_gpios) { +		ret = -ENOMEM; +		goto err_out;  	}  	master->bus_num = pdev->id;  	master->mode_bits = SPI_CPHA | SPI_CS_HIGH; -	master->bits_per_word_mask = SPI_BPW_MASK(8); +	master->bits_per_word_mask =  SPI_BPW_RANGE_MASK(1, 8);  	master->num_chipselect = pdata->num_chipselect;  	master->setup = spi_clps711x_setup; -	master->transfer_one_message = spi_clps711x_transfer_one_message; +	master->prepare_message = spi_clps711x_prepare_message; +	master->transfer_one = spi_clps711x_transfer_one;  	hw = spi_master_get_devdata(master);  	for (i = 0; i < master->num_chipselect; i++) { -		hw->chipselect[i] = pdata->chipselect[i]; -		if (!gpio_is_valid(hw->chipselect[i])) { -			dev_err(&pdev->dev, "Invalid CS GPIO %i\n", i); -			ret = -EINVAL; -			goto err_out; -		} -		if (gpio_request(hw->chipselect[i], DRIVER_NAME)) { +		master->cs_gpios[i] = pdata->chipselect[i]; +		ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], +					DRIVER_NAME); +		if (ret) {  			dev_err(&pdev->dev, "Can't get CS GPIO %i\n", i); -			ret = -EINVAL;  			goto err_out;  		}  	} @@ -211,73 +182,66 @@ static int spi_clps711x_probe(struct platform_device *pdev)  		ret = PTR_ERR(hw->spi_clk);  		goto err_out;  	} -	hw->max_speed_hz = clk_get_rate(hw->spi_clk); +	master->max_speed_hz = clk_get_rate(hw->spi_clk); -	init_completion(&hw->done);  	platform_set_drvdata(pdev, master); +	hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3"); +	if (IS_ERR(hw->syscon)) { +		ret = PTR_ERR(hw->syscon); +		goto err_out; +	} + +	hw->syscon1 = syscon_regmap_lookup_by_pdevname("syscon.1"); +	if (IS_ERR(hw->syscon1)) { +		ret = PTR_ERR(hw->syscon1); +		goto err_out; +	} + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	hw->syncio = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hw->syncio)) { +		ret = PTR_ERR(hw->syncio); +		goto err_out; +	} +  	/* Disable extended mode due hardware problems */ -	clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCON, SYSCON3); +	regmap_update_bits(hw->syscon, SYSCON_OFFSET, SYSCON3_ADCCON, 0);  	/* Clear possible pending interrupt */ -	clps_readl(SYNCIO); - -	ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0, -			       dev_name(&pdev->dev), hw); -	if (ret) { -		dev_err(&pdev->dev, "Can't request IRQ\n"); -		clk_put(hw->spi_clk); -		goto clk_out; -	} +	readl(hw->syncio); -	ret = spi_register_master(master); +	ret = devm_request_irq(&pdev->dev, irq, spi_clps711x_isr, 0, +			       dev_name(&pdev->dev), master); +	if (ret) +		goto err_out; + +	ret = devm_spi_register_master(&pdev->dev, master);  	if (!ret) {  		dev_info(&pdev->dev,  			 "SPI bus driver initialized. Master clock %u Hz\n", -			 hw->max_speed_hz); +			 master->max_speed_hz);  		return 0;  	}  	dev_err(&pdev->dev, "Failed to register master\n"); -clk_out:  err_out: -	while (--i >= 0) -		if (gpio_is_valid(hw->chipselect[i])) -			gpio_free(hw->chipselect[i]); -  	spi_master_put(master); -	kfree(master);  	return ret;  } -static int spi_clps711x_remove(struct platform_device *pdev) -{ -	int i; -	struct spi_master *master = platform_get_drvdata(pdev); -	struct spi_clps711x_data *hw = spi_master_get_devdata(master); - -	for (i = 0; i < master->num_chipselect; i++) -		if (gpio_is_valid(hw->chipselect[i])) -			gpio_free(hw->chipselect[i]); - -	spi_unregister_master(master); -	kfree(master); - -	return 0; -} -  static struct platform_driver clps711x_spi_driver = {  	.driver	= {  		.name	= DRIVER_NAME,  		.owner	= THIS_MODULE,  	},  	.probe	= spi_clps711x_probe, -	.remove	= spi_clps711x_remove,  };  module_platform_driver(clps711x_spi_driver);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");  MODULE_DESCRIPTION("CLPS711X SPI bus driver"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index cc5b75d10c3..e2fa628e55e 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -77,8 +77,6 @@ struct mcfqspi {  	struct mcfqspi_cs_control *cs_control;  	wait_queue_head_t waitq; - -	struct device *dev;  };  static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) @@ -135,13 +133,13 @@ static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select,  static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi)  { -	return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ? +	return (mcfqspi->cs_control->setup) ?  		mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0;  }  static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)  { -	if (mcfqspi->cs_control && mcfqspi->cs_control->teardown) +	if (mcfqspi->cs_control->teardown)  		mcfqspi->cs_control->teardown(mcfqspi->cs_control);  } @@ -300,68 +298,45 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,  	}  } -static int mcfqspi_transfer_one_message(struct spi_master *master, -					 struct spi_message *msg) +static void mcfqspi_set_cs(struct spi_device *spi, bool enable)  { -	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); -	struct spi_device *spi = msg->spi; -	struct spi_transfer *t; -	int status = 0; - -	list_for_each_entry(t, &msg->transfers, transfer_list) { -		bool cs_high = spi->mode & SPI_CS_HIGH; -		u16 qmr = MCFQSPI_QMR_MSTR; - -		qmr |= t->bits_per_word << 10; -		if (spi->mode & SPI_CPHA) -			qmr |= MCFQSPI_QMR_CPHA; -		if (spi->mode & SPI_CPOL) -			qmr |= MCFQSPI_QMR_CPOL; -		if (t->speed_hz) -			qmr |= mcfqspi_qmr_baud(t->speed_hz); -		else -			qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); -		mcfqspi_wr_qmr(mcfqspi, qmr); +	struct mcfqspi *mcfqspi = spi_master_get_devdata(spi->master); +	bool cs_high = spi->mode & SPI_CS_HIGH; +	if (enable)  		mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); +	else +		mcfqspi_cs_deselect(mcfqspi, spi->chip_select, cs_high); +} -		mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); -		if (t->bits_per_word == 8) -			mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, -					t->rx_buf); -		else -			mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, -					t->rx_buf); -		mcfqspi_wr_qir(mcfqspi, 0); - -		if (t->delay_usecs) -			udelay(t->delay_usecs); -		if (t->cs_change) { -			if (!list_is_last(&t->transfer_list, &msg->transfers)) -				mcfqspi_cs_deselect(mcfqspi, spi->chip_select, -						cs_high); -		} else { -			if (list_is_last(&t->transfer_list, &msg->transfers)) -				mcfqspi_cs_deselect(mcfqspi, spi->chip_select, -						cs_high); -		} -		msg->actual_length += t->len; -	} -	msg->status = status; -	spi_finalize_current_message(master); - -	return status; +static int mcfqspi_transfer_one(struct spi_master *master, +				struct spi_device *spi, +				struct spi_transfer *t) +{ +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); +	u16 qmr = MCFQSPI_QMR_MSTR; + +	qmr |= t->bits_per_word << 10; +	if (spi->mode & SPI_CPHA) +		qmr |= MCFQSPI_QMR_CPHA; +	if (spi->mode & SPI_CPOL) +		qmr |= MCFQSPI_QMR_CPOL; +	qmr |= mcfqspi_qmr_baud(t->speed_hz); +	mcfqspi_wr_qmr(mcfqspi, qmr); + +	mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); +	if (t->bits_per_word == 8) +		mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, t->rx_buf); +	else +		mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, +				       t->rx_buf); +	mcfqspi_wr_qir(mcfqspi, 0); +	return 0;  }  static int mcfqspi_setup(struct spi_device *spi)  { -	if (spi->chip_select >= spi->master->num_chipselect) { -		dev_dbg(&spi->dev, "%d chip select is out of range\n", -			spi->chip_select); -		return -EINVAL; -	} -  	mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),  			    spi->chip_select, spi->mode & SPI_CS_HIGH); @@ -388,6 +363,11 @@ static int mcfqspi_probe(struct platform_device *pdev)  		return -ENOENT;  	} +	if (!pdata->cs_control) { +		dev_dbg(&pdev->dev, "pdata->cs_control is NULL\n"); +		return -EINVAL; +	} +  	master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));  	if (master == NULL) {  		dev_dbg(&pdev->dev, "spi_alloc_master failed\n"); @@ -397,44 +377,31 @@ static int mcfqspi_probe(struct platform_device *pdev)  	mcfqspi = spi_master_get_devdata(master);  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_dbg(&pdev->dev, "platform_get_resource failed\n"); -		status = -ENXIO; -		goto fail0; -	} - -	if (!request_mem_region(res->start, resource_size(res), pdev->name)) { -		dev_dbg(&pdev->dev, "request_mem_region failed\n"); -		status = -EBUSY; +	mcfqspi->iobase = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(mcfqspi->iobase)) { +		status = PTR_ERR(mcfqspi->iobase);  		goto fail0;  	} -	mcfqspi->iobase = ioremap(res->start, resource_size(res)); -	if (!mcfqspi->iobase) { -		dev_dbg(&pdev->dev, "ioremap failed\n"); -		status = -ENOMEM; -		goto fail1; -	} -  	mcfqspi->irq = platform_get_irq(pdev, 0);  	if (mcfqspi->irq < 0) {  		dev_dbg(&pdev->dev, "platform_get_irq failed\n");  		status = -ENXIO; -		goto fail2; +		goto fail0;  	} -	status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, 0, -			     pdev->name, mcfqspi); +	status = devm_request_irq(&pdev->dev, mcfqspi->irq, mcfqspi_irq_handler, +				0, pdev->name, mcfqspi);  	if (status) {  		dev_dbg(&pdev->dev, "request_irq failed\n"); -		goto fail2; +		goto fail0;  	} -	mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk"); +	mcfqspi->clk = devm_clk_get(&pdev->dev, "qspi_clk");  	if (IS_ERR(mcfqspi->clk)) {  		dev_dbg(&pdev->dev, "clk_get failed\n");  		status = PTR_ERR(mcfqspi->clk); -		goto fail3; +		goto fail0;  	}  	clk_enable(mcfqspi->clk); @@ -445,42 +412,35 @@ static int mcfqspi_probe(struct platform_device *pdev)  	status = mcfqspi_cs_setup(mcfqspi);  	if (status) {  		dev_dbg(&pdev->dev, "error initializing cs_control\n"); -		goto fail4; +		goto fail1;  	}  	init_waitqueue_head(&mcfqspi->waitq); -	mcfqspi->dev = &pdev->dev;  	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;  	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);  	master->setup = mcfqspi_setup; -	master->transfer_one_message = mcfqspi_transfer_one_message; +	master->set_cs = mcfqspi_set_cs; +	master->transfer_one = mcfqspi_transfer_one;  	master->auto_runtime_pm = true;  	platform_set_drvdata(pdev, master); -	status = spi_register_master(master); +	status = devm_spi_register_master(&pdev->dev, master);  	if (status) {  		dev_dbg(&pdev->dev, "spi_register_master failed\n"); -		goto fail5; +		goto fail2;  	} -	pm_runtime_enable(mcfqspi->dev); +	pm_runtime_enable(&pdev->dev);  	dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");  	return 0; -fail5: -	mcfqspi_cs_teardown(mcfqspi); -fail4: -	clk_disable(mcfqspi->clk); -	clk_put(mcfqspi->clk); -fail3: -	free_irq(mcfqspi->irq, mcfqspi);  fail2: -	iounmap(mcfqspi->iobase); +	mcfqspi_cs_teardown(mcfqspi);  fail1: -	release_mem_region(res->start, resource_size(res)); +	clk_disable(mcfqspi->clk);  fail0:  	spi_master_put(master); @@ -493,19 +453,13 @@ static int mcfqspi_remove(struct platform_device *pdev)  {  	struct spi_master *master = platform_get_drvdata(pdev);  	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); -	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	pm_runtime_disable(mcfqspi->dev); +	pm_runtime_disable(&pdev->dev);  	/* disable the hardware (set the baud rate to 0) */  	mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);  	mcfqspi_cs_teardown(mcfqspi);  	clk_disable(mcfqspi->clk); -	clk_put(mcfqspi->clk); -	free_irq(mcfqspi->irq, mcfqspi); -	iounmap(mcfqspi->iobase); -	release_mem_region(res->start, resource_size(res)); -	spi_unregister_master(master);  	return 0;  } @@ -515,8 +469,11 @@ static int mcfqspi_suspend(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev);  	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); +	int ret; -	spi_master_suspend(master); +	ret = spi_master_suspend(master); +	if (ret) +		return ret;  	clk_disable(mcfqspi->clk); @@ -528,18 +485,17 @@ static int mcfqspi_resume(struct device *dev)  	struct spi_master *master = dev_get_drvdata(dev);  	struct mcfqspi *mcfqspi = spi_master_get_devdata(master); -	spi_master_resume(master); -  	clk_enable(mcfqspi->clk); -	return 0; +	return spi_master_resume(master);  }  #endif  #ifdef CONFIG_PM_RUNTIME  static int mcfqspi_runtime_suspend(struct device *dev)  { -	struct mcfqspi *mcfqspi = dev_get_drvdata(dev); +	struct spi_master *master = dev_get_drvdata(dev); +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);  	clk_disable(mcfqspi->clk); @@ -548,7 +504,8 @@ static int mcfqspi_runtime_suspend(struct device *dev)  static int mcfqspi_runtime_resume(struct device *dev)  { -	struct mcfqspi *mcfqspi = dev_get_drvdata(dev); +	struct spi_master *master = dev_get_drvdata(dev); +	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);  	clk_enable(mcfqspi->clk); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 8fbfe2483ff..50f75098925 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -279,7 +279,8 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,  	struct davinci_spi *dspi;  	struct davinci_spi_config *spicfg;  	u8 bits_per_word = 0; -	u32 hz = 0, spifmt = 0, prescale = 0; +	u32 hz = 0, spifmt = 0; +	int prescale;  	dspi = spi_master_get_devdata(spi->master);  	spicfg = (struct davinci_spi_config *)spi->controller_data; @@ -395,10 +396,6 @@ static int davinci_spi_setup(struct spi_device *spi)  	dspi = spi_master_get_devdata(spi->master);  	pdata = &dspi->pdata; -	/* if bits per word length is zero then set it default 8 */ -	if (!spi->bits_per_word) -		spi->bits_per_word = 8; -  	if (!(spi->mode & SPI_NO_CS)) {  		if ((pdata->chip_sel == NULL) ||  		    (pdata->chip_sel[spi->chip_select] == SPI_INTERN_CS)) @@ -553,7 +550,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)  	clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_POWERDOWN_MASK);  	set_io_bits(dspi->base + SPIGCR1, SPIGCR1_SPIENA_MASK); -	INIT_COMPLETION(dspi->done); +	reinit_completion(&dspi->done);  	if (spicfg->io_type == SPI_IO_TYPE_INTR)  		set_io_bits(dspi->base + SPIINT, SPIINT_MASKINT); @@ -805,8 +802,7 @@ static int spi_davinci_get_pdata(struct platform_device *pdev,  	pdata = &dspi->pdata;  	pdata->version = SPI_VERSION_1; -	match = of_match_device(of_match_ptr(davinci_spi_of_match), -				&pdev->dev); +	match = of_match_device(davinci_spi_of_match, &pdev->dev);  	if (!match)  		return -ENODEV; @@ -827,7 +823,6 @@ static int spi_davinci_get_pdata(struct platform_device *pdev,  	return 0;  }  #else -#define davinci_spi_of_match NULL  static struct davinci_spi_platform_data  	*spi_davinci_get_pdata(struct platform_device *pdev,  		struct davinci_spi *dspi) @@ -852,7 +847,7 @@ static int davinci_spi_probe(struct platform_device *pdev)  	struct spi_master *master;  	struct davinci_spi *dspi;  	struct davinci_spi_platform_data *pdata; -	struct resource *r, *mem; +	struct resource *r;  	resource_size_t dma_rx_chan = SPI_NO_RESOURCE;  	resource_size_t	dma_tx_chan = SPI_NO_RESOURCE;  	int i = 0, ret = 0; @@ -867,10 +862,6 @@ static int davinci_spi_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, master);  	dspi = spi_master_get_devdata(master); -	if (dspi == NULL) { -		ret = -ENOENT; -		goto free_master; -	}  	if (dev_get_platdata(&pdev->dev)) {  		pdata = dev_get_platdata(&pdev->dev); @@ -893,39 +884,29 @@ static int davinci_spi_probe(struct platform_device *pdev)  	dspi->pbase = r->start; -	mem = request_mem_region(r->start, resource_size(r), pdev->name); -	if (mem == NULL) { -		ret = -EBUSY; +	dspi->base = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(dspi->base)) { +		ret = PTR_ERR(dspi->base);  		goto free_master;  	} -	dspi->base = ioremap(r->start, resource_size(r)); -	if (dspi->base == NULL) { -		ret = -ENOMEM; -		goto release_region; -	} -  	dspi->irq = platform_get_irq(pdev, 0);  	if (dspi->irq <= 0) {  		ret = -EINVAL; -		goto unmap_io; +		goto free_master;  	} -	ret = request_threaded_irq(dspi->irq, davinci_spi_irq, dummy_thread_fn, -				 0, dev_name(&pdev->dev), dspi); +	ret = devm_request_threaded_irq(&pdev->dev, dspi->irq, davinci_spi_irq, +				dummy_thread_fn, 0, dev_name(&pdev->dev), dspi);  	if (ret) -		goto unmap_io; +		goto free_master; -	dspi->bitbang.master = spi_master_get(master); -	if (dspi->bitbang.master == NULL) { -		ret = -ENODEV; -		goto irq_free; -	} +	dspi->bitbang.master = master; -	dspi->clk = clk_get(&pdev->dev, NULL); +	dspi->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(dspi->clk)) {  		ret = -ENODEV; -		goto put_master; +		goto free_master;  	}  	clk_prepare_enable(dspi->clk); @@ -962,8 +943,8 @@ static int davinci_spi_probe(struct platform_device *pdev)  			goto free_clk;  		dev_info(&pdev->dev, "DMA: supported\n"); -		dev_info(&pdev->dev, "DMA: RX channel: %d, TX channel: %d, " -				"event queue: %d\n", dma_rx_chan, dma_tx_chan, +		dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, " +				"event queue: %d\n", &dma_rx_chan, &dma_tx_chan,  				pdata->dma_event_q);  	} @@ -1014,17 +995,8 @@ free_dma:  	dma_release_channel(dspi->dma_tx);  free_clk:  	clk_disable_unprepare(dspi->clk); -	clk_put(dspi->clk); -put_master: -	spi_master_put(master); -irq_free: -	free_irq(dspi->irq, dspi); -unmap_io: -	iounmap(dspi->base); -release_region: -	release_mem_region(dspi->pbase, resource_size(r));  free_master: -	kfree(master); +	spi_master_put(master);  err:  	return ret;  } @@ -1042,7 +1014,6 @@ static int davinci_spi_remove(struct platform_device *pdev)  {  	struct davinci_spi *dspi;  	struct spi_master *master; -	struct resource *r;  	master = platform_get_drvdata(pdev);  	dspi = spi_master_get_devdata(master); @@ -1050,12 +1021,7 @@ static int davinci_spi_remove(struct platform_device *pdev)  	spi_bitbang_stop(&dspi->bitbang);  	clk_disable_unprepare(dspi->clk); -	clk_put(dspi->clk);  	spi_master_put(master); -	free_irq(dspi->irq, dspi); -	iounmap(dspi->base); -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(dspi->pbase, resource_size(r));  	return 0;  } @@ -1064,7 +1030,7 @@ static struct platform_driver davinci_spi_driver = {  	.driver = {  		.name = "spi_davinci",  		.owner = THIS_MODULE, -		.of_match_table = davinci_spi_of_match, +		.of_match_table = of_match_ptr(davinci_spi_of_match),  	},  	.probe = davinci_spi_probe,  	.remove = davinci_spi_remove, diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index b9f0192758d..6d207afec8c 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -150,7 +150,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)  				&dws->tx_sgl,  				1,  				DMA_MEM_TO_DEV, -				DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP); +				DMA_PREP_INTERRUPT);  	txdesc->callback = dw_spi_dma_done;  	txdesc->callback_param = dws; @@ -173,7 +173,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)  				&dws->rx_sgl,  				1,  				DMA_DEV_TO_MEM, -				DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP); +				DMA_PREP_INTERRUPT);  	rxdesc->callback = dw_spi_dma_done;  	rxdesc->callback_param = dws; diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 4aa8be865cc..a5cba14ac3d 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -16,6 +16,7 @@  #include <linux/spi/spi.h>  #include <linux/scatterlist.h>  #include <linux/module.h> +#include <linux/of_gpio.h>  #include "spi-dw.h" @@ -30,14 +31,13 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)  {  	struct dw_spi_mmio *dwsmmio;  	struct dw_spi *dws; -	struct resource *mem, *ioarea; +	struct resource *mem;  	int ret; -	dwsmmio = kzalloc(sizeof(struct dw_spi_mmio), GFP_KERNEL); -	if (!dwsmmio) { -		ret = -ENOMEM; -		goto err_end; -	} +	dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio), +			GFP_KERNEL); +	if (!dwsmmio) +		return -ENOMEM;  	dws = &dwsmmio->dws; @@ -45,83 +45,72 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!mem) {  		dev_err(&pdev->dev, "no mem resource?\n"); -		ret = -EINVAL; -		goto err_kfree; -	} - -	ioarea = request_mem_region(mem->start, resource_size(mem), -			pdev->name); -	if (!ioarea) { -		dev_err(&pdev->dev, "SPI region already claimed\n"); -		ret = -EBUSY; -		goto err_kfree; +		return -EINVAL;  	} -	dws->regs = ioremap_nocache(mem->start, resource_size(mem)); -	if (!dws->regs) { -		dev_err(&pdev->dev, "SPI region already mapped\n"); -		ret = -ENOMEM; -		goto err_release_reg; +	dws->regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(dws->regs)) { +		dev_err(&pdev->dev, "SPI region map failed\n"); +		return PTR_ERR(dws->regs);  	}  	dws->irq = platform_get_irq(pdev, 0);  	if (dws->irq < 0) {  		dev_err(&pdev->dev, "no irq resource?\n"); -		ret = dws->irq; /* -ENXIO */ -		goto err_unmap; +		return dws->irq; /* -ENXIO */  	} -	dwsmmio->clk = clk_get(&pdev->dev, NULL); -	if (IS_ERR(dwsmmio->clk)) { -		ret = PTR_ERR(dwsmmio->clk); -		goto err_irq; -	} -	clk_enable(dwsmmio->clk); +	dwsmmio->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(dwsmmio->clk)) +		return PTR_ERR(dwsmmio->clk); +	ret = clk_prepare_enable(dwsmmio->clk); +	if (ret) +		return ret; -	dws->parent_dev = &pdev->dev; -	dws->bus_num = 0; +	dws->bus_num = pdev->id;  	dws->num_cs = 4;  	dws->max_freq = clk_get_rate(dwsmmio->clk); -	ret = dw_spi_add_host(dws); +	if (pdev->dev.of_node) { +		int i; + +		for (i = 0; i < dws->num_cs; i++) { +			int cs_gpio = of_get_named_gpio(pdev->dev.of_node, +					"cs-gpios", i); + +			if (cs_gpio == -EPROBE_DEFER) { +				ret = cs_gpio; +				goto out; +			} + +			if (gpio_is_valid(cs_gpio)) { +				ret = devm_gpio_request(&pdev->dev, cs_gpio, +						dev_name(&pdev->dev)); +				if (ret) +					goto out; +			} +		} +	} + +	ret = dw_spi_add_host(&pdev->dev, dws);  	if (ret) -		goto err_clk; +		goto out;  	platform_set_drvdata(pdev, dwsmmio);  	return 0; -err_clk: -	clk_disable(dwsmmio->clk); -	clk_put(dwsmmio->clk); -	dwsmmio->clk = NULL; -err_irq: -	free_irq(dws->irq, dws); -err_unmap: -	iounmap(dws->regs); -err_release_reg: -	release_mem_region(mem->start, resource_size(mem)); -err_kfree: -	kfree(dwsmmio); -err_end: +out: +	clk_disable_unprepare(dwsmmio->clk);  	return ret;  }  static int dw_spi_mmio_remove(struct platform_device *pdev)  {  	struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev); -	struct resource *mem; -	clk_disable(dwsmmio->clk); -	clk_put(dwsmmio->clk); -	dwsmmio->clk = NULL; - -	free_irq(dwsmmio->dws.irq, &dwsmmio->dws); +	clk_disable_unprepare(dwsmmio->clk);  	dw_spi_remove_host(&dwsmmio->dws); -	iounmap(dwsmmio->dws.regs); -	kfree(dwsmmio); -	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, resource_size(mem));  	return 0;  } diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 6055c8d9fdd..3f3dc1226ed 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -40,38 +40,28 @@ static int spi_pci_probe(struct pci_dev *pdev,  	int pci_bar = 0;  	int ret; -	printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n", +	dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",  		pdev->vendor, pdev->device); -	ret = pci_enable_device(pdev); +	ret = pcim_enable_device(pdev);  	if (ret)  		return ret; -	dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL); -	if (!dwpci) { -		ret = -ENOMEM; -		goto err_disable; -	} +	dwpci = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_pci), +			GFP_KERNEL); +	if (!dwpci) +		return -ENOMEM;  	dwpci->pdev = pdev;  	dws = &dwpci->dws;  	/* Get basic io resource and map it */  	dws->paddr = pci_resource_start(pdev, pci_bar); -	dws->iolen = pci_resource_len(pdev, pci_bar); -	ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); +	ret = pcim_iomap_regions(pdev, 1, dev_name(&pdev->dev));  	if (ret) -		goto err_kfree; - -	dws->regs = ioremap_nocache((unsigned long)dws->paddr, -				pci_resource_len(pdev, pci_bar)); -	if (!dws->regs) { -		ret = -ENOMEM; -		goto err_release_reg; -	} +		return ret; -	dws->parent_dev = &pdev->dev;  	dws->bus_num = 0;  	dws->num_cs = 4;  	dws->irq = pdev->irq; @@ -83,38 +73,24 @@ static int spi_pci_probe(struct pci_dev *pdev,  	if (pdev->device == 0x0800) {  		ret = dw_spi_mid_init(dws);  		if (ret) -			goto err_unmap; +			return ret;  	} -	ret = dw_spi_add_host(dws); +	ret = dw_spi_add_host(&pdev->dev, dws);  	if (ret) -		goto err_unmap; +		return ret;  	/* PCI hook and SPI hook use the same drv data */  	pci_set_drvdata(pdev, dwpci); -	return 0; -err_unmap: -	iounmap(dws->regs); -err_release_reg: -	pci_release_region(pdev, pci_bar); -err_kfree: -	kfree(dwpci); -err_disable: -	pci_disable_device(pdev); -	return ret; +	return 0;  }  static void spi_pci_remove(struct pci_dev *pdev)  {  	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); -	pci_set_drvdata(pdev, NULL);  	dw_spi_remove_host(&dwpci->dws); -	iounmap(dwpci->dws.regs); -	pci_release_region(pdev, 0); -	kfree(dwpci); -	pci_disable_device(pdev);  }  #ifdef CONFIG_PM @@ -149,7 +125,7 @@ static int spi_resume(struct pci_dev *pdev)  #define spi_resume	NULL  #endif -static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { +static const struct pci_device_id pci_ids[] = {  	/* Intel MID platform SPI controller 0 */  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) },  	{}, diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 79c958e49f6..29f33143b79 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -24,6 +24,7 @@  #include <linux/delay.h>  #include <linux/slab.h>  #include <linux/spi/spi.h> +#include <linux/gpio.h>  #include "spi-dw.h" @@ -36,12 +37,6 @@  #define DONE_STATE	((void *)2)  #define ERROR_STATE	((void *)-1) -#define QUEUE_RUNNING	0 -#define QUEUE_STOPPED	1 - -#define MRST_SPI_DEASSERT	0 -#define MRST_SPI_ASSERT		1 -  /* Slave spi_dev related */  struct chip_data {  	u16 cr0; @@ -263,29 +258,22 @@ static int map_dma_buffers(struct dw_spi *dws)  static void giveback(struct dw_spi *dws)  {  	struct spi_transfer *last_transfer; -	unsigned long flags;  	struct spi_message *msg; -	spin_lock_irqsave(&dws->lock, flags);  	msg = dws->cur_msg;  	dws->cur_msg = NULL;  	dws->cur_transfer = NULL;  	dws->prev_chip = dws->cur_chip;  	dws->cur_chip = NULL;  	dws->dma_mapped = 0; -	queue_work(dws->workqueue, &dws->pump_messages); -	spin_unlock_irqrestore(&dws->lock, flags); -	last_transfer = list_entry(msg->transfers.prev, -					struct spi_transfer, +	last_transfer = list_last_entry(&msg->transfers, struct spi_transfer,  					transfer_list); -	if (!last_transfer->cs_change && dws->cs_control) -		dws->cs_control(MRST_SPI_DEASSERT); +	if (!last_transfer->cs_change) +		spi_chip_sel(dws, dws->cur_msg->spi, 0); -	msg->state = NULL; -	if (msg->complete) -		msg->complete(msg->context); +	spi_finalize_current_message(dws->master);  }  static void int_error_stop(struct dw_spi *dws, const char *msg) @@ -427,7 +415,6 @@ static void pump_transfers(unsigned long data)  	dws->tx_end = dws->tx + transfer->len;  	dws->rx = transfer->rx_buf;  	dws->rx_end = dws->rx + transfer->len; -	dws->cs_change = transfer->cs_change;  	dws->len = dws->cur_transfer->len;  	if (chip != dws->prev_chip)  		cs_change = 1; @@ -440,12 +427,6 @@ static void pump_transfers(unsigned long data)  		if (transfer->speed_hz != speed) {  			speed = transfer->speed_hz; -			if (speed > dws->max_freq) { -				printk(KERN_ERR "MRST SPI0: unsupported" -					"freq: %dHz\n", speed); -				message->status = -EIO; -				goto early_exit; -			}  			/* clk_div doesn't support odd number */  			clk_div = dws->max_freq / speed; @@ -510,7 +491,7 @@ static void pump_transfers(unsigned long data)  			dw_writew(dws, DW_SPI_CTRL0, cr0);  		spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); -		spi_chip_sel(dws, spi->chip_select); +		spi_chip_sel(dws, spi, 1);  		/* Set the interrupt mask, for poll mode just disable all int */  		spi_mask_intr(dws, 0xff); @@ -537,30 +518,12 @@ early_exit:  	return;  } -static void pump_messages(struct work_struct *work) +static int dw_spi_transfer_one_message(struct spi_master *master, +		struct spi_message *msg)  { -	struct dw_spi *dws = -		container_of(work, struct dw_spi, pump_messages); -	unsigned long flags; - -	/* Lock queue and check for queue work */ -	spin_lock_irqsave(&dws->lock, flags); -	if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) { -		dws->busy = 0; -		spin_unlock_irqrestore(&dws->lock, flags); -		return; -	} - -	/* Make sure we are not already running a message */ -	if (dws->cur_msg) { -		spin_unlock_irqrestore(&dws->lock, flags); -		return; -	} - -	/* Extract head of queue */ -	dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue); -	list_del_init(&dws->cur_msg->queue); +	struct dw_spi *dws = spi_master_get_devdata(master); +	dws->cur_msg = msg;  	/* Initial message state*/  	dws->cur_msg->state = START_STATE;  	dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, @@ -568,46 +531,9 @@ static void pump_messages(struct work_struct *work)  						transfer_list);  	dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); -	/* Mark as busy and launch transfers */ +	/* Launch transfers */  	tasklet_schedule(&dws->pump_transfers); -	dws->busy = 1; -	spin_unlock_irqrestore(&dws->lock, flags); -} - -/* spi_device use this to queue in their spi_msg */ -static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg) -{ -	struct dw_spi *dws = spi_master_get_devdata(spi->master); -	unsigned long flags; - -	spin_lock_irqsave(&dws->lock, flags); - -	if (dws->run == QUEUE_STOPPED) { -		spin_unlock_irqrestore(&dws->lock, flags); -		return -ESHUTDOWN; -	} - -	msg->actual_length = 0; -	msg->status = -EINPROGRESS; -	msg->state = START_STATE; - -	list_add_tail(&msg->queue, &dws->queue); - -	if (dws->run == QUEUE_RUNNING && !dws->busy) { - -		if (dws->cur_transfer || dws->cur_msg) -			queue_work(dws->workqueue, -					&dws->pump_messages); -		else { -			/* If no other data transaction in air, just go */ -			spin_unlock_irqrestore(&dws->lock, flags); -			pump_messages(&dws->pump_messages); -			return 0; -		} -	} - -	spin_unlock_irqrestore(&dws->lock, flags);  	return 0;  } @@ -616,13 +542,16 @@ static int dw_spi_setup(struct spi_device *spi)  {  	struct dw_spi_chip *chip_info = NULL;  	struct chip_data *chip; +	int ret;  	/* Only alloc on first setup */  	chip = spi_get_ctldata(spi);  	if (!chip) { -		chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); +		chip = devm_kzalloc(&spi->dev, sizeof(struct chip_data), +				GFP_KERNEL);  		if (!chip)  			return -ENOMEM; +		spi_set_ctldata(spi, chip);  	}  	/* @@ -667,88 +596,13 @@ static int dw_spi_setup(struct spi_device *spi)  			| (spi->mode  << SPI_MODE_OFFSET)  			| (chip->tmode << SPI_TMOD_OFFSET); -	spi_set_ctldata(spi, chip); -	return 0; -} - -static void dw_spi_cleanup(struct spi_device *spi) -{ -	struct chip_data *chip = spi_get_ctldata(spi); -	kfree(chip); -} - -static int init_queue(struct dw_spi *dws) -{ -	INIT_LIST_HEAD(&dws->queue); -	spin_lock_init(&dws->lock); - -	dws->run = QUEUE_STOPPED; -	dws->busy = 0; - -	tasklet_init(&dws->pump_transfers, -			pump_transfers,	(unsigned long)dws); - -	INIT_WORK(&dws->pump_messages, pump_messages); -	dws->workqueue = create_singlethread_workqueue( -					dev_name(dws->master->dev.parent)); -	if (dws->workqueue == NULL) -		return -EBUSY; - -	return 0; -} - -static int start_queue(struct dw_spi *dws) -{ -	unsigned long flags; - -	spin_lock_irqsave(&dws->lock, flags); - -	if (dws->run == QUEUE_RUNNING || dws->busy) { -		spin_unlock_irqrestore(&dws->lock, flags); -		return -EBUSY; +	if (gpio_is_valid(spi->cs_gpio)) { +		ret = gpio_direction_output(spi->cs_gpio, +				!(spi->mode & SPI_CS_HIGH)); +		if (ret) +			return ret;  	} -	dws->run = QUEUE_RUNNING; -	dws->cur_msg = NULL; -	dws->cur_transfer = NULL; -	dws->cur_chip = NULL; -	dws->prev_chip = NULL; -	spin_unlock_irqrestore(&dws->lock, flags); - -	queue_work(dws->workqueue, &dws->pump_messages); - -	return 0; -} - -static int stop_queue(struct dw_spi *dws) -{ -	unsigned long flags; -	unsigned limit = 50; -	int status = 0; - -	spin_lock_irqsave(&dws->lock, flags); -	dws->run = QUEUE_STOPPED; -	while ((!list_empty(&dws->queue) || dws->busy) && limit--) { -		spin_unlock_irqrestore(&dws->lock, flags); -		msleep(10); -		spin_lock_irqsave(&dws->lock, flags); -	} - -	if (!list_empty(&dws->queue) || dws->busy) -		status = -EBUSY; -	spin_unlock_irqrestore(&dws->lock, flags); - -	return status; -} - -static int destroy_queue(struct dw_spi *dws) -{ -	int status; - -	status = stop_queue(dws); -	if (status != 0) -		return status; -	destroy_workqueue(dws->workqueue);  	return 0;  } @@ -776,18 +630,16 @@ static void spi_hw_init(struct dw_spi *dws)  	}  } -int dw_spi_add_host(struct dw_spi *dws) +int dw_spi_add_host(struct device *dev, struct dw_spi *dws)  {  	struct spi_master *master;  	int ret;  	BUG_ON(dws == NULL); -	master = spi_alloc_master(dws->parent_dev, 0); -	if (!master) { -		ret = -ENOMEM; -		goto exit; -	} +	master = spi_alloc_master(dev, 0); +	if (!master) +		return -ENOMEM;  	dws->master = master;  	dws->type = SSI_MOTO_SPI; @@ -797,7 +649,7 @@ int dw_spi_add_host(struct dw_spi *dws)  	snprintf(dws->name, sizeof(dws->name), "dw_spi%d",  			dws->bus_num); -	ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, +	ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED,  			dws->name, dws);  	if (ret < 0) {  		dev_err(&master->dev, "can not get IRQ\n"); @@ -808,9 +660,9 @@ int dw_spi_add_host(struct dw_spi *dws)  	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);  	master->bus_num = dws->bus_num;  	master->num_chipselect = dws->num_cs; -	master->cleanup = dw_spi_cleanup;  	master->setup = dw_spi_setup; -	master->transfer = dw_spi_transfer; +	master->transfer_one_message = dw_spi_transfer_one_message; +	master->max_speed_hz = dws->max_freq;  	/* Basic HW init */  	spi_hw_init(dws); @@ -823,65 +675,39 @@ int dw_spi_add_host(struct dw_spi *dws)  		}  	} -	/* Initial and start queue */ -	ret = init_queue(dws); -	if (ret) { -		dev_err(&master->dev, "problem initializing queue\n"); -		goto err_diable_hw; -	} -	ret = start_queue(dws); -	if (ret) { -		dev_err(&master->dev, "problem starting queue\n"); -		goto err_diable_hw; -	} +	tasklet_init(&dws->pump_transfers, pump_transfers, (unsigned long)dws);  	spi_master_set_devdata(master, dws); -	ret = spi_register_master(master); +	ret = devm_spi_register_master(dev, master);  	if (ret) {  		dev_err(&master->dev, "problem registering spi master\n"); -		goto err_queue_alloc; +		goto err_dma_exit;  	}  	mrst_spi_debugfs_init(dws);  	return 0; -err_queue_alloc: -	destroy_queue(dws); +err_dma_exit:  	if (dws->dma_ops && dws->dma_ops->dma_exit)  		dws->dma_ops->dma_exit(dws); -err_diable_hw:  	spi_enable_chip(dws, 0); -	free_irq(dws->irq, dws);  err_free_master:  	spi_master_put(master); -exit:  	return ret;  }  EXPORT_SYMBOL_GPL(dw_spi_add_host);  void dw_spi_remove_host(struct dw_spi *dws)  { -	int status = 0; -  	if (!dws)  		return;  	mrst_spi_debugfs_remove(dws); -	/* Remove the queue */ -	status = destroy_queue(dws); -	if (status != 0) -		dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " -			"complete, message memory not freed\n"); -  	if (dws->dma_ops && dws->dma_ops->dma_exit)  		dws->dma_ops->dma_exit(dws);  	spi_enable_chip(dws, 0);  	/* Disable clk */  	spi_set_clk(dws, 0); -	free_irq(dws->irq, dws); - -	/* Disconnect from the SPI framework */ -	spi_unregister_master(dws->master);  }  EXPORT_SYMBOL_GPL(dw_spi_remove_host); @@ -889,7 +715,7 @@ int dw_spi_suspend_host(struct dw_spi *dws)  {  	int ret = 0; -	ret = stop_queue(dws); +	ret = spi_master_suspend(dws->master);  	if (ret)  		return ret;  	spi_enable_chip(dws, 0); @@ -903,7 +729,7 @@ int dw_spi_resume_host(struct dw_spi *dws)  	int ret;  	spi_hw_init(dws); -	ret = start_queue(dws); +	ret = spi_master_resume(dws->master);  	if (ret)  		dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);  	return ret; diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 9c57c078031..6d2acad34f6 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -3,6 +3,7 @@  #include <linux/io.h>  #include <linux/scatterlist.h> +#include <linux/gpio.h>  /* Register offsets */  #define DW_SPI_CTRL0			0x00 @@ -92,13 +93,11 @@ struct dw_spi_dma_ops {  struct dw_spi {  	struct spi_master	*master;  	struct spi_device	*cur_dev; -	struct device		*parent_dev;  	enum dw_ssi_type	type;  	char			name[16];  	void __iomem		*regs;  	unsigned long		paddr; -	u32			iolen;  	int			irq;  	u32			fifo_len;	/* depth of the FIFO buffer */  	u32			max_freq;	/* max bus freq supported */ @@ -106,14 +105,6 @@ struct dw_spi {  	u16			bus_num;  	u16			num_cs;		/* supported slave numbers */ -	/* Driver message queue */ -	struct workqueue_struct	*workqueue; -	struct work_struct	pump_messages; -	spinlock_t		lock; -	struct list_head	queue; -	int			busy; -	int			run; -  	/* Message Transfer pump */  	struct tasklet_struct	pump_transfers; @@ -135,7 +126,6 @@ struct dw_spi {  	u8			n_bytes;	/* current is a 1/2 bytes op */  	u8			max_bits_per_word;	/* maxim is 16b */  	u32			dma_width; -	int			cs_change;  	irqreturn_t		(*transfer_handler)(struct dw_spi *dws);  	void			(*cs_control)(u32 command); @@ -189,15 +179,20 @@ static inline void spi_set_clk(struct dw_spi *dws, u16 div)  	dw_writel(dws, DW_SPI_BAUDR, div);  } -static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) +static inline void spi_chip_sel(struct dw_spi *dws, struct spi_device *spi, +		int active)  { -	if (cs > dws->num_cs) -		return; +	u16 cs = spi->chip_select; +	int gpio_val = active ? (spi->mode & SPI_CS_HIGH) : +		!(spi->mode & SPI_CS_HIGH);  	if (dws->cs_control) -		dws->cs_control(1); +		dws->cs_control(active); +	if (gpio_is_valid(spi->cs_gpio)) +		gpio_set_value(spi->cs_gpio, gpio_val); -	dw_writel(dws, DW_SPI_SER, 1 << cs); +	if (active) +		dw_writel(dws, DW_SPI_SER, 1 << cs);  }  /* Disable IRQ bits */ @@ -231,7 +226,7 @@ struct dw_spi_chip {  	void (*cs_control)(u32 command);  }; -extern int dw_spi_add_host(struct dw_spi *dws); +extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws);  extern void dw_spi_remove_host(struct dw_spi *dws);  extern int dw_spi_suspend_host(struct dw_spi *dws);  extern int dw_spi_resume_host(struct dw_spi *dws); diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index 7d84418a01d..be44a3eeb5e 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -198,7 +198,7 @@ static int efm32_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  	efm32_spi_filltx(ddata); -	init_completion(&ddata->done); +	reinit_completion(&ddata->done);  	efm32_spi_write32(ddata, REG_IF_TXBL | REG_IF_RXDATAV, REG_IEN); @@ -280,10 +280,6 @@ static irqreturn_t efm32_spi_txirq(int irq, void *data)  	return IRQ_HANDLED;  } -static const struct efm32_spi_pdata efm32_spi_pdata_default = { -	.location = 1, -}; -  static u32 efm32_spi_get_configured_location(struct efm32_spi_ddata *ddata)  {  	u32 reg = efm32_spi_read32(ddata, REG_ROUTE); @@ -291,17 +287,17 @@ static u32 efm32_spi_get_configured_location(struct efm32_spi_ddata *ddata)  	return (reg & REG_ROUTE_LOCATION__MASK) >> __ffs(REG_ROUTE_LOCATION__MASK);  } -static int efm32_spi_probe_dt(struct platform_device *pdev, +static void efm32_spi_probe_dt(struct platform_device *pdev,  		struct spi_master *master, struct efm32_spi_ddata *ddata)  {  	struct device_node *np = pdev->dev.of_node;  	u32 location;  	int ret; -	if (!np) -		return 1; - -	ret = of_property_read_u32(np, "location", &location); +	ret = of_property_read_u32(np, "efm32,location", &location); +	if (ret) +		/* fall back to old and (wrongly) generic property "location" */ +		ret = of_property_read_u32(np, "location", &location);  	if (!ret) {  		dev_dbg(&pdev->dev, "using location %u\n", location);  	} else { @@ -312,11 +308,6 @@ static int efm32_spi_probe_dt(struct platform_device *pdev,  	}  	ddata->pdata.location = location; - -	/* spi core takes care about the bus number using an alias */ -	master->bus_num = -1; - -	return 0;  }  static int efm32_spi_probe(struct platform_device *pdev) @@ -326,9 +317,14 @@ static int efm32_spi_probe(struct platform_device *pdev)  	int ret;  	struct spi_master *master;  	struct device_node *np = pdev->dev.of_node; -	unsigned int num_cs, i; +	int num_cs, i; + +	if (!np) +		return -EINVAL;  	num_cs = of_gpio_named_count(np, "cs-gpios"); +	if (num_cs < 0) +		return num_cs;  	master = spi_alloc_master(&pdev->dev,  			sizeof(*ddata) + num_cs * sizeof(unsigned)); @@ -347,12 +343,13 @@ static int efm32_spi_probe(struct platform_device *pdev)  	ddata = spi_master_get_devdata(master); -	ddata->bitbang.master = spi_master_get(master); +	ddata->bitbang.master = master;  	ddata->bitbang.chipselect = efm32_spi_chipselect;  	ddata->bitbang.setup_transfer = efm32_spi_setup_transfer;  	ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;  	spin_lock_init(&ddata->lock); +	init_completion(&ddata->done);  	ddata->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(ddata->clk)) { @@ -387,7 +384,7 @@ static int efm32_spi_probe(struct platform_device *pdev)  		goto err;  	} -	if (resource_size(res) < 60) { +	if (resource_size(res) < 0x60) {  		ret = -EINVAL;  		dev_err(&pdev->dev, "memory resource too small\n");  		goto err; @@ -419,23 +416,7 @@ static int efm32_spi_probe(struct platform_device *pdev)  		goto err;  	} -	ret = efm32_spi_probe_dt(pdev, master, ddata); -	if (ret > 0) { -		/* not created by device tree */ -		const struct efm32_spi_pdata *pdata = -			dev_get_platdata(&pdev->dev); - -		if (pdata) -			ddata->pdata = *pdata; -		else -			ddata->pdata.location = -				efm32_spi_get_configured_location(ddata); - -		master->bus_num = pdev->id; - -	} else if (ret < 0) { -		goto err_disable_clk; -	} +	efm32_spi_probe_dt(pdev, master, ddata);  	efm32_spi_write32(ddata, 0, REG_IEN);  	efm32_spi_write32(ddata, REG_ROUTE_TXPEN | REG_ROUTE_RXPEN | @@ -467,7 +448,6 @@ err_disable_clk:  		clk_disable_unprepare(ddata->clk);  err:  		spi_master_put(master); -		kfree(master);  	}  	return ret; @@ -478,19 +458,23 @@ static int efm32_spi_remove(struct platform_device *pdev)  	struct spi_master *master = platform_get_drvdata(pdev);  	struct efm32_spi_ddata *ddata = spi_master_get_devdata(master); +	spi_bitbang_stop(&ddata->bitbang); +  	efm32_spi_write32(ddata, 0, REG_IEN);  	free_irq(ddata->txirq, ddata);  	free_irq(ddata->rxirq, ddata);  	clk_disable_unprepare(ddata->clk);  	spi_master_put(master); -	kfree(master);  	return 0;  }  static const struct of_device_id efm32_spi_dt_ids[] = {  	{ +		.compatible = "energymicro,efm32-spi", +	}, { +		/* doesn't follow the "vendor,device" scheme, don't use */  		.compatible = "efm32,spi",  	}, {  		/* sentinel */ diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index d22c00a227b..2f675d32df0 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -73,8 +73,6 @@   * @clk: clock for the controller   * @regs_base: pointer to ioremap()'d registers   * @sspdr_phys: physical address of the SSPDR register - * @min_rate: minimum clock rate (in Hz) supported by the controller - * @max_rate: maximum clock rate (in Hz) supported by the controller   * @wait: wait here until given transfer is completed   * @current_msg: message that is currently processed (or %NULL if none)   * @tx: current byte in transfer to transmit @@ -95,8 +93,6 @@ struct ep93xx_spi {  	struct clk			*clk;  	void __iomem			*regs_base;  	unsigned long			sspdr_phys; -	unsigned long			min_rate; -	unsigned long			max_rate;  	struct completion		wait;  	struct spi_message		*current_msg;  	size_t				tx; @@ -199,9 +195,9 @@ static void ep93xx_spi_disable_interrupts(const struct ep93xx_spi *espi)   * @div_scr: pointer to return the scr divider   */  static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, -				    unsigned long rate, -				    u8 *div_cpsr, u8 *div_scr) +				    u32 rate, u8 *div_cpsr, u8 *div_scr)  { +	struct spi_master *master = platform_get_drvdata(espi->pdev);  	unsigned long spi_clk_rate = clk_get_rate(espi->clk);  	int cpsr, scr; @@ -210,7 +206,7 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi,  	 * controller. Note that minimum value is already checked in  	 * ep93xx_spi_transfer_one_message().  	 */ -	rate = clamp(rate, espi->min_rate, espi->max_rate); +	rate = clamp(rate, master->min_speed_hz, master->max_speed_hz);  	/*  	 * Calculate divisors so that we can get speed according the @@ -330,7 +326,7 @@ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi,  	dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",  		chip->spi->mode, div_cpsr, div_scr, dss); -	dev_dbg(&espi->pdev->dev, "setup: cr0 %#x", cr0); +	dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0);  	ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr);  	ep93xx_spi_write_u16(espi, SSPCR0, cr0); @@ -509,7 +505,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir)  	}  	if (WARN_ON(len)) { -		dev_warn(&espi->pdev->dev, "len = %zu expected 0!", len); +		dev_warn(&espi->pdev->dev, "len = %zu expected 0!\n", len);  		return ERR_PTR(-EINVAL);  	} @@ -735,13 +731,6 @@ static int ep93xx_spi_transfer_one_message(struct spi_master *master,  					   struct spi_message *msg)  {  	struct ep93xx_spi *espi = spi_master_get_devdata(master); -	struct spi_transfer *t; - -	/* first validate each transfer */ -	list_for_each_entry(t, &msg->transfers, transfer_list) { -		if (t->speed_hz < espi->min_rate) -			return -EINVAL; -	}  	msg->state = NULL;  	msg->status = 0; @@ -917,8 +906,8 @@ static int ep93xx_spi_probe(struct platform_device *pdev)  	 * Calculate maximum and minimum supported clock rates  	 * for the controller.  	 */ -	espi->max_rate = clk_get_rate(espi->clk) / 2; -	espi->min_rate = clk_get_rate(espi->clk) / (254 * 256); +	master->max_speed_hz = clk_get_rate(espi->clk) / 2; +	master->min_speed_hz = clk_get_rate(espi->clk) / (254 * 256);  	espi->pdev = pdev;  	espi->sspdr_phys = res->start + SSPDR; @@ -942,7 +931,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)  	/* make sure that the hardware is disabled */  	ep93xx_spi_write_u8(espi, SSPCR1, 0); -	error = spi_register_master(master); +	error = devm_spi_register_master(&pdev->dev, master);  	if (error) {  		dev_err(&pdev->dev, "failed to register SPI master\n");  		goto fail_free_dma; @@ -968,7 +957,6 @@ static int ep93xx_spi_remove(struct platform_device *pdev)  	ep93xx_spi_release_dma(espi); -	spi_unregister_master(master);  	return 0;  } diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index c7a74f0ef89..ba441ad9a00 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -11,7 +11,6 @@  #include <linux/platform_device.h>  #include <linux/spi/spi.h>  #include <linux/delay.h> -#include <linux/workqueue.h>  #include <linux/of.h>  #include <linux/of_platform.h> @@ -312,9 +311,6 @@ static int falcon_sflash_setup(struct spi_device *spi)  	unsigned int i;  	unsigned long flags; -	if (spi->chip_select > 0) -		return -ENODEV; -  	spin_lock_irqsave(&ebu_lock, flags);  	if (spi->max_speed_hz >= CLOCK_100M) { @@ -422,9 +418,7 @@ static int falcon_sflash_probe(struct platform_device *pdev)  	priv->master = master;  	master->mode_bits = SPI_MODE_3; -	master->num_chipselect = 1;  	master->flags = SPI_MASTER_HALF_DUPLEX; -	master->bus_num = -1;  	master->setup = falcon_sflash_setup;  	master->prepare_transfer_hardware = falcon_sflash_prepare_xfer;  	master->transfer_one_message = falcon_sflash_xfer_one; @@ -433,21 +427,12 @@ static int falcon_sflash_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, priv); -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret)  		spi_master_put(master);  	return ret;  } -static int falcon_sflash_remove(struct platform_device *pdev) -{ -	struct falcon_sflash *priv = platform_get_drvdata(pdev); - -	spi_unregister_master(priv->master); - -	return 0; -} -  static const struct of_device_id falcon_sflash_match[] = {  	{ .compatible = "lantiq,sflash-falcon" },  	{}, @@ -456,7 +441,6 @@ MODULE_DEVICE_TABLE(of, falcon_sflash_match);  static struct platform_driver falcon_sflash_driver = {  	.probe	= falcon_sflash_probe, -	.remove	= falcon_sflash_remove,  	.driver = {  		.name	= DRV_NAME,  		.owner	= THIS_MODULE, diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 07971e3fe58..54b06376f03 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -20,6 +20,7 @@  #include <linux/spi/spi.h>  #include <linux/fsl_devices.h>  #include <linux/dma-mapping.h> +#include <linux/of_address.h>  #include <asm/cpm.h>  #include <asm/qe.h> @@ -299,7 +300,7 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)  		switch (mspi->subblock) {  		default: -			dev_warn(dev, "cell-index unspecified, assuming SPI1"); +			dev_warn(dev, "cell-index unspecified, assuming SPI1\n");  			/* fall through */  		case 0:  			mspi->subblock = QE_CR_SUBBLOCK_SPI1; diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 6cd07d13eca..5021ddf03f6 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -18,6 +18,7 @@  #include <linux/interrupt.h>  #include <linux/errno.h>  #include <linux/platform_device.h> +#include <linux/regmap.h>  #include <linux/sched.h>  #include <linux/delay.h>  #include <linux/io.h> @@ -108,11 +109,11 @@ struct fsl_dspi {  	struct spi_bitbang	bitbang;  	struct platform_device	*pdev; -	void			*base; +	struct regmap		*regmap;  	int			irq; -	struct clk 		*clk; +	struct clk		*clk; -	struct spi_transfer 	*cur_transfer; +	struct spi_transfer	*cur_transfer;  	struct chip_data	*cur_chip;  	size_t			len;  	void			*tx; @@ -123,24 +124,17 @@ struct fsl_dspi {  	u8			cs;  	u16			void_write_data; -	wait_queue_head_t 	waitq; -	u32 			waitflags; +	wait_queue_head_t	waitq; +	u32			waitflags;  };  static inline int is_double_byte_mode(struct fsl_dspi *dspi)  { -	return ((readl(dspi->base + SPI_CTAR(dspi->cs)) & SPI_FRAME_BITS_MASK) -			== SPI_FRAME_BITS(8)) ? 0 : 1; -} +	unsigned int val; -static void set_bit_mode(struct fsl_dspi *dspi, unsigned char bits) -{ -	u32 temp; +	regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), &val); -	temp = readl(dspi->base + SPI_CTAR(dspi->cs)); -	temp &= ~SPI_FRAME_BITS_MASK; -	temp |= SPI_FRAME_BITS(bits); -	writel(temp, dspi->base + SPI_CTAR(dspi->cs)); +	return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;  }  static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, @@ -165,7 +159,7 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,  			}  		} -	pr_warn("Can not find valid buad rate,speed_hz is %d,clkrate is %ld\ +	pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld\  		,we use the max prescaler value.\n", speed_hz, clkrate);  	*pbr = ARRAY_SIZE(pbr_tbl) - 1;  	*br =  ARRAY_SIZE(brs) - 1; @@ -188,7 +182,8 @@ static int dspi_transfer_write(struct fsl_dspi *dspi)  	 */  	if (tx_word && (dspi->len == 1)) {  		dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; -		set_bit_mode(dspi, 8); +		regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), +				SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));  		tx_word = 0;  	} @@ -238,7 +233,8 @@ static int dspi_transfer_write(struct fsl_dspi *dspi)  			dspi_pushr |= SPI_PUSHR_CTCNT; /* clear counter */  		} -		writel(dspi_pushr, dspi->base + SPI_PUSHR); +		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr); +  		tx_count++;  	} @@ -253,17 +249,23 @@ static int dspi_transfer_read(struct fsl_dspi *dspi)  	while ((dspi->rx < dspi->rx_end)  			&& (rx_count < DSPI_FIFO_SIZE)) {  		if (rx_word) { +			unsigned int val; +  			if ((dspi->rx_end - dspi->rx) == 1)  				break; -			d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR)); +			regmap_read(dspi->regmap, SPI_POPR, &val); +			d = SPI_POPR_RXDATA(val);  			if (!(dspi->dataflags & TRAN_STATE_RX_VOID))  				*(u16 *)dspi->rx = d;  			dspi->rx += 2;  		} else { -			d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR)); +			unsigned int val; + +			regmap_read(dspi->regmap, SPI_POPR, &val); +			d = SPI_POPR_RXDATA(val);  			if (!(dspi->dataflags & TRAN_STATE_RX_VOID))  				*(u8 *)dspi->rx = d;  			dspi->rx++; @@ -295,13 +297,13 @@ static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t)  	if (!dspi->tx)  		dspi->dataflags |= TRAN_STATE_TX_VOID; -	writel(dspi->cur_chip->mcr_val, dspi->base + SPI_MCR); -	writel(dspi->cur_chip->ctar_val, dspi->base + SPI_CTAR(dspi->cs)); -	writel(SPI_RSER_EOQFE, dspi->base + SPI_RSER); +	regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val); +	regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val); +	regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE);  	if (t->speed_hz) -		writel(dspi->cur_chip->ctar_val, -				dspi->base + SPI_CTAR(dspi->cs)); +		regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), +				dspi->cur_chip->ctar_val);  	dspi_transfer_write(dspi); @@ -315,16 +317,20 @@ static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t)  static void dspi_chipselect(struct spi_device *spi, int value)  {  	struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); -	u32 pushr = readl(dspi->base + SPI_PUSHR); +	unsigned int pushr; + +	regmap_read(dspi->regmap, SPI_PUSHR, &pushr);  	switch (value) {  	case BITBANG_CS_ACTIVE:  		pushr |= SPI_PUSHR_CONT; +		break;  	case BITBANG_CS_INACTIVE:  		pushr &= ~SPI_PUSHR_CONT; +		break;  	} -	writel(pushr, dspi->base + SPI_PUSHR); +	regmap_write(dspi->regmap, SPI_PUSHR, pushr);  }  static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) @@ -336,7 +342,8 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  	/* Only alloc on first setup */  	chip = spi_get_ctldata(spi);  	if (chip == NULL) { -		chip = kcalloc(1, sizeof(struct chip_data), GFP_KERNEL); +		chip = devm_kzalloc(&spi->dev, sizeof(struct chip_data), +				    GFP_KERNEL);  		if (!chip)  			return -ENOMEM;  	} @@ -347,7 +354,6 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  		fmsz = spi->bits_per_word - 1;  	} else {  		pr_err("Invalid wordsize\n"); -		kfree(chip);  		return -ENODEV;  	} @@ -373,9 +379,6 @@ static int dspi_setup(struct spi_device *spi)  	if (!spi->max_speed_hz)  		return -EINVAL; -	if (!spi->bits_per_word) -		spi->bits_per_word = 8; -  	return dspi_setup_transfer(spi, NULL);  } @@ -383,13 +386,15 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)  {  	struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; -	writel(SPI_SR_EOQF, dspi->base + SPI_SR); +	regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF);  	dspi_transfer_read(dspi);  	if (!dspi->len) {  		if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) -			set_bit_mode(dspi, 16); +			regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), +				SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); +  		dspi->waitflags = 1;  		wake_up_interruptible(&dspi->waitq);  	} else { @@ -401,7 +406,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)  	return IRQ_HANDLED;  } -static struct of_device_id fsl_dspi_dt_ids[] = { +static const struct of_device_id fsl_dspi_dt_ids[] = {  	{ .compatible = "fsl,vf610-dspi", .data = NULL, },  	{ /* sentinel */ }  }; @@ -421,7 +426,6 @@ static int dspi_suspend(struct device *dev)  static int dspi_resume(struct device *dev)  { -  	struct spi_master *master = dev_get_drvdata(dev);  	struct fsl_dspi *dspi = spi_master_get_devdata(master); @@ -432,8 +436,13 @@ static int dspi_resume(struct device *dev)  }  #endif /* CONFIG_PM_SLEEP */ -static const struct dev_pm_ops dspi_pm = { -	SET_SYSTEM_SLEEP_PM_OPS(dspi_suspend, dspi_resume) +static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); + +static struct regmap_config dspi_regmap_config = { +	.reg_bits = 32, +	.val_bits = 32, +	.reg_stride = 4, +	.max_register = 0x88,  };  static int dspi_probe(struct platform_device *pdev) @@ -442,6 +451,7 @@ static int dspi_probe(struct platform_device *pdev)  	struct spi_master *master;  	struct fsl_dspi *dspi;  	struct resource *res; +	void __iomem *base;  	int ret = 0, cs_num, bus_num;  	master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi)); @@ -450,7 +460,7 @@ static int dspi_probe(struct platform_device *pdev)  	dspi = spi_master_get_devdata(master);  	dspi->pdev = pdev; -	dspi->bitbang.master = spi_master_get(master); +	dspi->bitbang.master = master;  	dspi->bitbang.chipselect = dspi_chipselect;  	dspi->bitbang.setup_transfer = dspi_setup_transfer;  	dspi->bitbang.txrx_bufs = dspi_txrx_transfer; @@ -476,16 +486,22 @@ static int dspi_probe(struct platform_device *pdev)  	master->bus_num = bus_num;  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(&pdev->dev, "can't get platform resource\n"); -		ret = -EINVAL; +	base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(base)) { +		ret = PTR_ERR(base);  		goto out_master_put;  	} -	dspi->base = devm_ioremap_resource(&pdev->dev, res); -	if (!dspi->base) { -		ret = -EINVAL; -		goto out_master_put; +	dspi_regmap_config.lock_arg = dspi; +	dspi_regmap_config.val_format_endian = +		of_property_read_bool(np, "big-endian") +			? REGMAP_ENDIAN_BIG : REGMAP_ENDIAN_DEFAULT; +	dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base, +						&dspi_regmap_config); +	if (IS_ERR(dspi->regmap)) { +		dev_err(&pdev->dev, "failed to init regmap: %ld\n", +				PTR_ERR(dspi->regmap)); +		return PTR_ERR(dspi->regmap);  	}  	dspi->irq = platform_get_irq(pdev, 0); @@ -511,7 +527,7 @@ static int dspi_probe(struct platform_device *pdev)  	clk_prepare_enable(dspi->clk);  	init_waitqueue_head(&dspi->waitq); -	platform_set_drvdata(pdev, dspi); +	platform_set_drvdata(pdev, master);  	ret = spi_bitbang_start(&dspi->bitbang);  	if (ret != 0) { @@ -526,17 +542,18 @@ out_clk_put:  	clk_disable_unprepare(dspi->clk);  out_master_put:  	spi_master_put(master); -	platform_set_drvdata(pdev, NULL);  	return ret;  }  static int dspi_remove(struct platform_device *pdev)  { -	struct fsl_dspi *dspi = platform_get_drvdata(pdev); +	struct spi_master *master = platform_get_drvdata(pdev); +	struct fsl_dspi *dspi = spi_master_get_devdata(master);  	/* Disconnect from the SPI framework */  	spi_bitbang_stop(&dspi->bitbang); +	clk_disable_unprepare(dspi->clk);  	spi_master_put(dspi->bitbang.master);  	return 0; @@ -553,5 +570,5 @@ static struct platform_driver fsl_dspi_driver = {  module_platform_driver(fsl_dspi_driver);  MODULE_DESCRIPTION("Freescale DSPI Controller Driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL");  MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index b8f1103fe28..8ebd724e4c5 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -16,6 +16,8 @@  #include <linux/fsl_devices.h>  #include <linux/mm.h>  #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/interrupt.h>  #include <linux/err.h> @@ -217,20 +219,15 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)  	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);  	struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base;  	unsigned int len = t->len; -	u8 bits_per_word;  	int ret; -	bits_per_word = spi->bits_per_word; -	if (t->bits_per_word) -		bits_per_word = t->bits_per_word; -  	mpc8xxx_spi->len = t->len;  	len = roundup(len, 4) / 4;  	mpc8xxx_spi->tx = t->tx_buf;  	mpc8xxx_spi->rx = t->rx_buf; -	INIT_COMPLETION(mpc8xxx_spi->done); +	reinit_completion(&mpc8xxx_spi->done);  	/* Set SPCOM[CS] and SPCOM[TRANLEN] field */  	if ((t->len - 1) > SPCOM_TRANLEN_MAX) { @@ -289,8 +286,8 @@ static void fsl_espi_do_trans(struct spi_message *m,  		if ((first->bits_per_word != t->bits_per_word) ||  			(first->speed_hz != t->speed_hz)) {  			espi_trans->status = -EINVAL; -			dev_err(mspi->dev, "bits_per_word/speed_hz should be" -					" same for the same SPI transfer\n"); +			dev_err(mspi->dev, +				"bits_per_word/speed_hz should be same for the same SPI transfer\n");  			return;  		} @@ -351,7 +348,7 @@ static void fsl_espi_cmd_trans(struct spi_message *m,  	}  	espi_trans->tx_buf = local_buf; -	espi_trans->rx_buf = local_buf + espi_trans->n_tx; +	espi_trans->rx_buf = local_buf;  	fsl_espi_do_trans(m, espi_trans);  	espi_trans->actual_length = espi_trans->len; @@ -400,7 +397,7 @@ static void fsl_espi_rw_trans(struct spi_message *m,  		espi_trans->n_rx = trans_len;  		espi_trans->len = trans_len + n_tx;  		espi_trans->tx_buf = local_buf; -		espi_trans->rx_buf = local_buf + n_tx; +		espi_trans->rx_buf = local_buf;  		fsl_espi_do_trans(m, espi_trans);  		memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len); @@ -444,7 +441,8 @@ static void fsl_espi_do_one_msg(struct spi_message *m)  	m->actual_length = espi_trans.actual_length;  	m->status = espi_trans.status; -	m->complete(m->context); +	if (m->complete) +		m->complete(m->context);  }  static int fsl_espi_setup(struct spi_device *spi) @@ -460,7 +458,7 @@ static int fsl_espi_setup(struct spi_device *spi)  		return -EINVAL;  	if (!cs) { -		cs = kzalloc(sizeof *cs, GFP_KERNEL); +		cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL);  		if (!cs)  			return -ENOMEM;  		spi->controller_state = cs; @@ -588,8 +586,10 @@ static struct spi_master * fsl_espi_probe(struct device *dev,  	struct spi_master *master;  	struct mpc8xxx_spi *mpc8xxx_spi;  	struct fsl_espi_reg *reg_base; -	u32 regval; -	int i, ret = 0; +	struct device_node *nc; +	const __be32 *prop; +	u32 regval, csmode; +	int i, len, ret = 0;  	master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi));  	if (!master) { @@ -636,8 +636,32 @@ static struct spi_master * fsl_espi_probe(struct device *dev,  	mpc8xxx_spi_write_reg(®_base->event, 0xffffffff);  	/* Init eSPI CS mode register */ -	for (i = 0; i < pdata->max_chipselect; i++) -		mpc8xxx_spi_write_reg(®_base->csmode[i], CSMODE_INIT_VAL); +	for_each_available_child_of_node(master->dev.of_node, nc) { +		/* get chip select */ +		prop = of_get_property(nc, "reg", &len); +		if (!prop || len < sizeof(*prop)) +			continue; +		i = be32_to_cpup(prop); +		if (i < 0 || i >= pdata->max_chipselect) +			continue; + +		csmode = CSMODE_INIT_VAL; +		/* check if CSBEF is set in device tree */ +		prop = of_get_property(nc, "fsl,csbef", &len); +		if (prop && len >= sizeof(*prop)) { +			csmode &= ~(CSMODE_BEF(0xf)); +			csmode |= CSMODE_BEF(be32_to_cpup(prop)); +		} +		/* check if CSAFT is set in device tree */ +		prop = of_get_property(nc, "fsl,csaft", &len); +		if (prop && len >= sizeof(*prop)) { +			csmode &= ~(CSMODE_AFT(0xf)); +			csmode |= CSMODE_AFT(be32_to_cpup(prop)); +		} +		mpc8xxx_spi_write_reg(®_base->csmode[i], csmode); + +		dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode); +	}  	/* Enable SPI interface */  	regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; @@ -687,7 +711,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)  	struct device_node *np = ofdev->dev.of_node;  	struct spi_master *master;  	struct resource mem; -	struct resource irq; +	unsigned int irq;  	int ret = -ENOMEM;  	ret = of_mpc8xxx_spi_probe(ofdev); @@ -702,13 +726,13 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)  	if (ret)  		goto err; -	ret = of_irq_to_resource(np, 0, &irq); -	if (!ret) { +	irq = irq_of_parse_and_map(np, 0); +	if (!irq) {  		ret = -EINVAL;  		goto err;  	} -	master = fsl_espi_probe(dev, &mem, irq.start); +	master = fsl_espi_probe(dev, &mem, irq);  	if (IS_ERR(master)) {  		ret = PTR_ERR(master);  		goto err; @@ -725,6 +749,66 @@ static int of_fsl_espi_remove(struct platform_device *dev)  	return mpc8xxx_spi_remove(&dev->dev);  } +#ifdef CONFIG_PM_SLEEP +static int of_fsl_espi_suspend(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct mpc8xxx_spi *mpc8xxx_spi; +	struct fsl_espi_reg *reg_base; +	u32 regval; +	int ret; + +	mpc8xxx_spi = spi_master_get_devdata(master); +	reg_base = mpc8xxx_spi->reg_base; + +	ret = spi_master_suspend(master); +	if (ret) { +		dev_warn(dev, "cannot suspend master\n"); +		return ret; +	} + +	regval = mpc8xxx_spi_read_reg(®_base->mode); +	regval &= ~SPMODE_ENABLE; +	mpc8xxx_spi_write_reg(®_base->mode, regval); + +	return 0; +} + +static int of_fsl_espi_resume(struct device *dev) +{ +	struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); +	struct spi_master *master = dev_get_drvdata(dev); +	struct mpc8xxx_spi *mpc8xxx_spi; +	struct fsl_espi_reg *reg_base; +	u32 regval; +	int i; + +	mpc8xxx_spi = spi_master_get_devdata(master); +	reg_base = mpc8xxx_spi->reg_base; + +	/* SPI controller initializations */ +	mpc8xxx_spi_write_reg(®_base->mode, 0); +	mpc8xxx_spi_write_reg(®_base->mask, 0); +	mpc8xxx_spi_write_reg(®_base->command, 0); +	mpc8xxx_spi_write_reg(®_base->event, 0xffffffff); + +	/* Init eSPI CS mode register */ +	for (i = 0; i < pdata->max_chipselect; i++) +		mpc8xxx_spi_write_reg(®_base->csmode[i], CSMODE_INIT_VAL); + +	/* Enable SPI interface */ +	regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; + +	mpc8xxx_spi_write_reg(®_base->mode, regval); + +	return spi_master_resume(master); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops espi_pm = { +	SET_SYSTEM_SLEEP_PM_OPS(of_fsl_espi_suspend, of_fsl_espi_resume) +}; +  static const struct of_device_id of_fsl_espi_match[] = {  	{ .compatible = "fsl,mpc8536-espi" },  	{} @@ -736,6 +820,7 @@ static struct platform_driver fsl_espi_driver = {  		.name = "fsl_espi",  		.owner = THIS_MODULE,  		.of_match_table = of_fsl_espi_match, +		.pm = &espi_pm,  	},  	.probe		= of_fsl_espi_probe,  	.remove		= of_fsl_espi_remove, diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c index 0b75f26158a..95212ea96c8 100644 --- a/drivers/spi/spi-fsl-lib.c +++ b/drivers/spi/spi-fsl-lib.c @@ -99,11 +99,6 @@ int mpc8xxx_spi_transfer(struct spi_device *spi,  	return 0;  } -void mpc8xxx_spi_cleanup(struct spi_device *spi) -{ -	kfree(spi->controller_state); -} -  const char *mpc8xxx_spi_strmode(unsigned int flags)  {  	if (flags & SPI_QE_CPU_MODE) { @@ -134,7 +129,6 @@ int mpc8xxx_spi_probe(struct device *dev, struct resource *mem,  			| SPI_LSB_FIRST | SPI_LOOP;  	master->transfer = mpc8xxx_spi_transfer; -	master->cleanup = mpc8xxx_spi_cleanup;  	master->dev.of_node = dev->of_node;  	mpc8xxx_spi = spi_master_get_devdata(master); @@ -200,7 +194,7 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev)  	const void *prop;  	int ret = -ENOMEM; -	pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); +	pinfo = devm_kzalloc(&ofdev->dev, sizeof(*pinfo), GFP_KERNEL);  	if (!pinfo)  		return -ENOMEM; @@ -215,15 +209,13 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev)  	pdata->sysclk = get_brgfreq();  	if (pdata->sysclk == -1) {  		pdata->sysclk = fsl_get_sys_freq(); -		if (pdata->sysclk == -1) { -			ret = -ENODEV; -			goto err; -		} +		if (pdata->sysclk == -1) +			return -ENODEV;  	}  #else  	ret = of_property_read_u32(np, "clock-frequency", &pdata->sysclk);  	if (ret) -		goto err; +		return ret;  #endif  	prop = of_get_property(np, "mode", NULL); @@ -237,8 +229,4 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev)  		pdata->flags = SPI_CPM_MODE | SPI_CPM1;  	return 0; - -err: -	kfree(pinfo); -	return ret;  } diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index 52db6936778..2fcbfd01d10 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -124,7 +124,6 @@ extern struct mpc8xxx_spi_probe_info *to_of_pinfo(  extern int mpc8xxx_spi_bufs(struct mpc8xxx_spi *mspi,  		struct spi_transfer *t, unsigned int len);  extern int mpc8xxx_spi_transfer(struct spi_device *spi, struct spi_message *m); -extern void mpc8xxx_spi_cleanup(struct spi_device *spi);  extern const char *mpc8xxx_spi_strmode(unsigned int flags);  extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem,  		unsigned int irq); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 2129fcd1c31..98ccd231bf0 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -239,12 +239,6 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,  	if (!bits_per_word)  		bits_per_word = spi->bits_per_word; -	/* Make sure its a bit width we support [4..16, 32] */ -	if ((bits_per_word < 4) -	    || ((bits_per_word > 16) && (bits_per_word != 32)) -	    || (bits_per_word > mpc8xxx_spi->max_bits_per_word)) -		return -EINVAL; -  	if (!hz)  		hz = spi->max_speed_hz; @@ -339,7 +333,7 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,  	mpc8xxx_spi->tx = t->tx_buf;  	mpc8xxx_spi->rx = t->rx_buf; -	INIT_COMPLETION(mpc8xxx_spi->done); +	reinit_completion(&mpc8xxx_spi->done);  	if (mpc8xxx_spi->flags & SPI_CPM_MODE)  		ret = fsl_spi_cpm_bufs(mpc8xxx_spi, t, is_dma_mapped); @@ -362,18 +356,28 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,  static void fsl_spi_do_one_msg(struct spi_message *m)  {  	struct spi_device *spi = m->spi; -	struct spi_transfer *t; +	struct spi_transfer *t, *first;  	unsigned int cs_change;  	const int nsecs = 50;  	int status; -	cs_change = 1; -	status = 0; +	/* Don't allow changes if CS is active */ +	first = list_first_entry(&m->transfers, struct spi_transfer, +			transfer_list);  	list_for_each_entry(t, &m->transfers, transfer_list) { -		if (t->bits_per_word || t->speed_hz) { -			/* Don't allow changes if CS is active */ +		if ((first->bits_per_word != t->bits_per_word) || +			(first->speed_hz != t->speed_hz)) {  			status = -EINVAL; +			dev_err(&spi->dev, +				"bits_per_word/speed_hz should be same for the same SPI transfer\n"); +			return; +		} +	} +	cs_change = 1; +	status = -EINVAL; +	list_for_each_entry(t, &m->transfers, transfer_list) { +		if (t->bits_per_word || t->speed_hz) {  			if (cs_change)  				status = fsl_spi_setup_transfer(spi, t);  			if (status < 0) @@ -404,7 +408,8 @@ static void fsl_spi_do_one_msg(struct spi_message *m)  	}  	m->status = status; -	m->complete(m->context); +	if (m->complete) +		m->complete(m->context);  	if (status || !cs_change) {  		ndelay(nsecs); @@ -426,7 +431,7 @@ static int fsl_spi_setup(struct spi_device *spi)  		return -EINVAL;  	if (!cs) { -		cs = kzalloc(sizeof *cs, GFP_KERNEL); +		cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL);  		if (!cs)  			return -ENOMEM;  		spi->controller_state = cs; @@ -641,6 +646,10 @@ static struct spi_master * fsl_spi_probe(struct device *dev,  	if (mpc8xxx_spi->type == TYPE_GRLIB)  		fsl_spi_grlib_probe(dev); +	master->bits_per_word_mask = +		(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) & +		SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word); +  	if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)  		mpc8xxx_spi->set_shifts = fsl_spi_qe_cpu_set_shifts; diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 68b69fec13a..9f595535cf2 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -19,9 +19,9 @@   */  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/platform_device.h>  #include <linux/gpio.h> +#include <linux/of.h>  #include <linux/of_device.h>  #include <linux/of_gpio.h> @@ -114,17 +114,17 @@ spi_to_pdata(const struct spi_device *spi)  static inline void setsck(const struct spi_device *spi, int is_on)  { -	gpio_set_value(SPI_SCK_GPIO, is_on); +	gpio_set_value_cansleep(SPI_SCK_GPIO, is_on);  }  static inline void setmosi(const struct spi_device *spi, int is_on)  { -	gpio_set_value(SPI_MOSI_GPIO, is_on); +	gpio_set_value_cansleep(SPI_MOSI_GPIO, is_on);  }  static inline int getmiso(const struct spi_device *spi)  { -	return !!gpio_get_value(SPI_MISO_GPIO); +	return !!gpio_get_value_cansleep(SPI_MISO_GPIO);  }  #undef pdata @@ -228,7 +228,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)  	if (cs != SPI_GPIO_NO_CHIPSELECT) {  		/* SPI is normally active-low */ -		gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); +		gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);  	}  } @@ -249,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi)  		/*  		 * ... otherwise, take it from spi->controller_data  		 */ -		cs = (unsigned int) spi->controller_data; +		cs = (unsigned int)(uintptr_t) spi->controller_data;  	}  	if (!spi->controller_state) { @@ -340,7 +340,7 @@ done:  }  #ifdef CONFIG_OF -static struct of_device_id spi_gpio_dt_ids[] = { +static const struct of_device_id spi_gpio_dt_ids[] = {  	{ .compatible = "spi-gpio" },  	{}  }; @@ -467,7 +467,7 @@ static int spi_gpio_probe(struct platform_device *pdev)  	}  #endif -	spi_gpio->bitbang.master = spi_master_get(master); +	spi_gpio->bitbang.master = master;  	spi_gpio->bitbang.chipselect = spi_gpio_chipselect;  	if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { @@ -486,7 +486,6 @@ static int spi_gpio_probe(struct platform_device *pdev)  	status = spi_bitbang_start(&spi_gpio->bitbang);  	if (status < 0) { -		spi_master_put(spi_gpio->bitbang.master);  gpio_free:  		if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)  			gpio_free(SPI_MISO_GPIO); @@ -503,22 +502,21 @@ static int spi_gpio_remove(struct platform_device *pdev)  {  	struct spi_gpio			*spi_gpio;  	struct spi_gpio_platform_data	*pdata; -	int				status;  	spi_gpio = platform_get_drvdata(pdev);  	pdata = dev_get_platdata(&pdev->dev);  	/* stop() unregisters child devices too */ -	status = spi_bitbang_stop(&spi_gpio->bitbang); -	spi_master_put(spi_gpio->bitbang.master); +	spi_bitbang_stop(&spi_gpio->bitbang);  	if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)  		gpio_free(SPI_MISO_GPIO);  	if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)  		gpio_free(SPI_MOSI_GPIO);  	gpio_free(SPI_SCK_GPIO); +	spi_master_put(spi_gpio->bitbang.master); -	return status; +	return 0;  }  MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 15323d8bd9c..5daff2054ae 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -23,7 +23,6 @@  #include <linux/delay.h>  #include <linux/err.h>  #include <linux/gpio.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/irq.h> @@ -206,7 +205,8 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin,  #define MX51_ECSPI_STAT_RR		(1 <<  3)  /* MX51 eCSPI */ -static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi) +static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi, +				      unsigned int *fres)  {  	/*  	 * there are two 4-bit dividers, the pre-divider divides by @@ -234,6 +234,10 @@ static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi)  	pr_debug("%s: fin: %u, fspi: %u, post: %u, pre: %u\n",  			__func__, fin, fspi, post, pre); + +	/* Resulting frequency for the SCLK line. */ +	*fres = (fin / (pre + 1)) >> post; +  	return (pre << MX51_ECSPI_CTRL_PREDIV_OFFSET) |  		(post << MX51_ECSPI_CTRL_POSTDIV_OFFSET);  } @@ -264,6 +268,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,  		struct spi_imx_config *config)  {  	u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0; +	u32 clk = config->speed_hz, delay;  	/*  	 * The hardware seems to have a race condition when changing modes. The @@ -275,7 +280,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,  	ctrl |= MX51_ECSPI_CTRL_MODE_MASK;  	/* set clock speed */ -	ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz); +	ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz, &clk);  	/* set chip select to use */  	ctrl |= MX51_ECSPI_CTRL_CS(config->cs); @@ -297,6 +302,23 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,  	writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);  	writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); +	/* +	 * Wait until the changes in the configuration register CONFIGREG +	 * propagate into the hardware. It takes exactly one tick of the +	 * SCLK clock, but we will wait two SCLK clock just to be sure. The +	 * effect of the delay it takes for the hardware to apply changes +	 * is noticable if the SCLK clock run very slow. In such a case, if +	 * the polarity of SCLK should be inverted, the GPIO ChipSelect might +	 * be asserted before the SCLK polarity changes, which would disrupt +	 * the SPI communication as the device on the other end would consider +	 * the change of SCLK polarity as a clock tick already. +	 */ +	delay = (2 * 1000000) / clk; +	if (likely(delay < 10))	/* SCLK is faster than 100 kHz */ +		udelay(delay); +	else			/* SCLK is _very_ slow */ +		usleep_range(delay, delay + 10); +  	return 0;  } @@ -718,7 +740,7 @@ static int spi_imx_transfer(struct spi_device *spi,  	spi_imx->count = transfer->len;  	spi_imx->txfifo = 0; -	init_completion(&spi_imx->xfer_done); +	reinit_completion(&spi_imx->xfer_done);  	spi_imx_push(spi_imx); @@ -749,6 +771,35 @@ static void spi_imx_cleanup(struct spi_device *spi)  {  } +static int +spi_imx_prepare_message(struct spi_master *master, struct spi_message *msg) +{ +	struct spi_imx_data *spi_imx = spi_master_get_devdata(master); +	int ret; + +	ret = clk_enable(spi_imx->clk_per); +	if (ret) +		return ret; + +	ret = clk_enable(spi_imx->clk_ipg); +	if (ret) { +		clk_disable(spi_imx->clk_per); +		return ret; +	} + +	return 0; +} + +static int +spi_imx_unprepare_message(struct spi_master *master, struct spi_message *msg) +{ +	struct spi_imx_data *spi_imx = spi_master_get_devdata(master); + +	clk_disable(spi_imx->clk_ipg); +	clk_disable(spi_imx->clk_per); +	return 0; +} +  static int spi_imx_probe(struct platform_device *pdev)  {  	struct device_node *np = pdev->dev.of_node; @@ -786,7 +837,7 @@ static int spi_imx_probe(struct platform_device *pdev)  	master->num_chipselect = num_cs;  	spi_imx = spi_master_get_devdata(master); -	spi_imx->bitbang.master = spi_master_get(master); +	spi_imx->bitbang.master = master;  	for (i = 0; i < master->num_chipselect; i++) {  		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); @@ -810,6 +861,8 @@ static int spi_imx_probe(struct platform_device *pdev)  	spi_imx->bitbang.txrx_bufs = spi_imx_transfer;  	spi_imx->bitbang.master->setup = spi_imx_setup;  	spi_imx->bitbang.master->cleanup = spi_imx_cleanup; +	spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; +	spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message;  	spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;  	init_completion(&spi_imx->xfer_done); @@ -826,12 +879,12 @@ static int spi_imx_probe(struct platform_device *pdev)  	spi_imx->irq = platform_get_irq(pdev, 0);  	if (spi_imx->irq < 0) { -		ret = -EINVAL; +		ret = spi_imx->irq;  		goto out_master_put;  	}  	ret = devm_request_irq(&pdev->dev, spi_imx->irq, spi_imx_isr, 0, -			       DRIVER_NAME, spi_imx); +			       dev_name(&pdev->dev), spi_imx);  	if (ret) {  		dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);  		goto out_master_put; @@ -872,6 +925,8 @@ static int spi_imx_probe(struct platform_device *pdev)  	dev_info(&pdev->dev, "probed\n"); +	clk_disable(spi_imx->clk_ipg); +	clk_disable(spi_imx->clk_per);  	return ret;  out_clk_put: @@ -892,8 +947,8 @@ static int spi_imx_remove(struct platform_device *pdev)  	spi_bitbang_stop(&spi_imx->bitbang);  	writel(0, spi_imx->base + MXC_CSPICTRL); -	clk_disable_unprepare(spi_imx->clk_ipg); -	clk_disable_unprepare(spi_imx->clk_per); +	clk_unprepare(spi_imx->clk_ipg); +	clk_unprepare(spi_imx->clk_per);  	spi_master_put(master);  	return 0; diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 0759b5db988..41c5765be74 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -222,7 +222,7 @@ static void spi_lm70llp_attach(struct parport *p)  	/*  	 * SPI and bitbang hookup.  	 */ -	pp->bitbang.master = spi_master_get(master); +	pp->bitbang.master = master;  	pp->bitbang.chipselect = lm70_chipselect;  	pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx;  	pp->bitbang.flags = SPI_3WIRE; diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index dbc5e999a1f..577d23a1276 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -16,10 +16,10 @@  #include <linux/module.h>  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/interrupt.h>  #include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/completion.h>  #include <linux/io.h> @@ -39,6 +39,7 @@ struct mpc512x_psc_spi {  	unsigned int irq;  	u8 bits_per_word;  	struct clk *clk_mclk; +	struct clk *clk_ipg;  	u32 mclk_rate;  	struct completion txisrdone; @@ -166,7 +167,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,  			}  			/* have the ISR trigger when the TX FIFO is empty */ -			INIT_COMPLETION(mps->txisrdone); +			reinit_completion(&mps->txisrdone);  			out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);  			out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);  			wait_for_completion(&mps->txisrdone); @@ -299,7 +300,8 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,  	}  	m->status = status; -	m->complete(m->context); +	if (m->complete) +		m->complete(m->context);  	if (status || !cs_change)  		mpc512x_psc_spi_deactivate_cs(spi); @@ -464,18 +466,14 @@ static void mpc512x_spi_cs_control(struct spi_device *spi, bool onoff)  	gpio_set_value(spi->cs_gpio, onoff);  } -/* bus_num is used only for the case dev->platform_data == NULL */  static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, -					      u32 size, unsigned int irq, -					      s16 bus_num) +					      u32 size, unsigned int irq)  {  	struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);  	struct mpc512x_psc_spi *mps;  	struct spi_master *master;  	int ret;  	void *tempp; -	int psc_num; -	char clk_name[16];  	struct clk *clk;  	master = spi_alloc_master(dev, sizeof *mps); @@ -488,7 +486,6 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,  	if (pdata == NULL) {  		mps->cs_control = mpc512x_spi_cs_control; -		master->bus_num = bus_num;  	} else {  		mps->cs_control = pdata->cs_control;  		master->bus_num = pdata->bus_num; @@ -503,7 +500,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,  	master->cleanup = mpc512x_psc_spi_cleanup;  	master->dev.of_node = dev->of_node; -	tempp = ioremap(regaddr, size); +	tempp = devm_ioremap(dev, regaddr, size);  	if (!tempp) {  		dev_err(dev, "could not ioremap I/O port range\n");  		ret = -EFAULT; @@ -512,41 +509,48 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,  	mps->psc = tempp;  	mps->fifo =  		(struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc)); - -	ret = request_irq(mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED, -			  "mpc512x-psc-spi", mps); +	ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED, +				"mpc512x-psc-spi", mps);  	if (ret)  		goto free_master;  	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; +	clk = devm_clk_get(dev, "mclk"); +	if (IS_ERR(clk)) { +		ret = PTR_ERR(clk); +		goto free_master; +	}  	ret = clk_prepare_enable(clk);  	if (ret) -		goto free_irq; +		goto free_master;  	mps->clk_mclk = clk;  	mps->mclk_rate = clk_get_rate(clk); +	clk = devm_clk_get(dev, "ipg"); +	if (IS_ERR(clk)) { +		ret = PTR_ERR(clk); +		goto free_mclk_clock; +	} +	ret = clk_prepare_enable(clk); +	if (ret) +		goto free_mclk_clock; +	mps->clk_ipg = clk; +  	ret = mpc512x_psc_spi_port_config(master, mps);  	if (ret < 0) -		goto free_clock; +		goto free_ipg_clock; -	ret = spi_register_master(master); +	ret = devm_spi_register_master(dev, master);  	if (ret < 0) -		goto free_clock; +		goto free_ipg_clock;  	return ret; -free_clock: +free_ipg_clock: +	clk_disable_unprepare(mps->clk_ipg); +free_mclk_clock:  	clk_disable_unprepare(mps->clk_mclk); -free_irq: -	free_irq(mps->irq, mps);  free_master: -	if (mps->psc) -		iounmap(mps->psc);  	spi_master_put(master);  	return ret; @@ -554,15 +558,11 @@ free_master:  static int mpc512x_psc_spi_do_remove(struct device *dev)  { -	struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); +	struct spi_master *master = dev_get_drvdata(dev);  	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); -	spi_unregister_master(master);  	clk_disable_unprepare(mps->clk_mclk); -	free_irq(mps->irq, mps); -	if (mps->psc) -		iounmap(mps->psc); -	spi_master_put(master); +	clk_disable_unprepare(mps->clk_ipg);  	return 0;  } @@ -571,7 +571,6 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op)  {  	const u32 *regaddr_p;  	u64 regaddr64, size64; -	s16 id = -1;  	regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);  	if (!regaddr_p) { @@ -580,16 +579,8 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op)  	}  	regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); -	/* get PSC id (0..11, used by port_config) */ -	id = of_alias_get_id(op->dev.of_node, "spi"); -	if (id < 0) { -		dev_err(&op->dev, "no alias id for %s\n", -			op->dev.of_node->full_name); -		return id; -	} -  	return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, -				irq_of_parse_and_map(op->dev.of_node, 0), id); +				irq_of_parse_and_map(op->dev.of_node, 0));  }  static int mpc512x_psc_spi_of_remove(struct platform_device *op) diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index 6e925dc3439..de532aa11d3 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c @@ -12,7 +12,6 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/types.h>  #include <linux/errno.h>  #include <linux/interrupt.h> @@ -248,7 +247,8 @@ static void mpc52xx_psc_spi_work(struct work_struct *work)  		}  		m->status = status; -		m->complete(m->context); +		if (m->complete) +			m->complete(m->context);  		if (status || !cs_change)  			mpc52xx_psc_spi_deactivate_cs(spi); @@ -383,8 +383,8 @@ static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,  	mps->irq = irq;  	if (pdata == NULL) { -		dev_warn(dev, "probe called without platform data, no " -				"cs_control function will be called\n"); +		dev_warn(dev, +			 "probe called without platform data, no cs_control function will be called\n");  		mps->cs_control = NULL;  		mps->sysclk = 0;  		master->bus_num = bus_num; diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 7c675fe8310..b07db4b62d8 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -12,7 +12,6 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/of_platform.h>  #include <linux/interrupt.h> @@ -235,7 +234,8 @@ static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms,  		dev_err(&ms->master->dev, "mode fault\n");  		mpc52xx_spi_chipsel(ms, 0);  		ms->message->status = -EIO; -		ms->message->complete(ms->message->context); +		if (ms->message->complete) +			ms->message->complete(ms->message->context);  		ms->state = mpc52xx_spi_fsmstate_idle;  		return FSM_CONTINUE;  	} @@ -289,7 +289,8 @@ mpc52xx_spi_fsmstate_wait(int irq, struct mpc52xx_spi *ms, u8 status, u8 data)  		ms->msg_count++;  		mpc52xx_spi_chipsel(ms, 0);  		ms->message->status = 0; -		ms->message->complete(ms->message->context); +		if (ms->message->complete) +			ms->message->complete(ms->message->context);  		ms->state = mpc52xx_spi_fsmstate_idle;  		return FSM_CONTINUE;  	} @@ -357,20 +358,6 @@ static void mpc52xx_spi_wq(struct work_struct *work)   * spi_master ops   */ -static int mpc52xx_spi_setup(struct spi_device *spi) -{ -	if (spi->bits_per_word % 8) -		return -EINVAL; - -	if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) -		return -EINVAL; - -	if (spi->chip_select >= spi->master->num_chipselect) -		return -EINVAL; - -	return 0; -} -  static int mpc52xx_spi_transfer(struct spi_device *spi, struct spi_message *m)  {  	struct mpc52xx_spi *ms = spi_master_get_devdata(spi->master); @@ -433,9 +420,9 @@ static int mpc52xx_spi_probe(struct platform_device *op)  		goto err_alloc;  	} -	master->setup = mpc52xx_spi_setup;  	master->transfer = mpc52xx_spi_transfer;  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; +	master->bits_per_word_mask = SPI_BPW_MASK(8);  	master->dev.of_node = op->dev.of_node;  	platform_set_drvdata(op, master); diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index de7b1141b90..2884f0c2f5f 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -29,7 +29,6 @@   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/ioport.h>  #include <linux/of.h>  #include <linux/of_device.h> @@ -57,34 +56,53 @@  #define SG_MAXLEN		0xff00 +/* + * Flags for txrx functions.  More efficient that using an argument register for + * each one. + */ +#define TXRX_WRITE		(1<<0)	/* This is a write */ +#define TXRX_DEASSERT_CS	(1<<1)	/* De-assert CS at end of txrx */ +  struct mxs_spi {  	struct mxs_ssp		ssp;  	struct completion	c; +	unsigned int		sck;	/* Rate requested (vs actual) */  };  static int mxs_spi_setup_transfer(struct spi_device *dev, -				struct spi_transfer *t) +				  const struct spi_transfer *t)  {  	struct mxs_spi *spi = spi_master_get_devdata(dev->master);  	struct mxs_ssp *ssp = &spi->ssp; -	uint32_t hz = 0; +	const unsigned int hz = min(dev->max_speed_hz, t->speed_hz); -	hz = dev->max_speed_hz; -	if (t && t->speed_hz) -		hz = min(hz, t->speed_hz);  	if (hz == 0) { -		dev_err(&dev->dev, "Cannot continue with zero clock\n"); +		dev_err(&dev->dev, "SPI clock rate of zero not allowed\n");  		return -EINVAL;  	} -	mxs_ssp_set_clk_rate(ssp, hz); +	if (hz != spi->sck) { +		mxs_ssp_set_clk_rate(ssp, hz); +		/* +		 * Save requested rate, hz, rather than the actual rate, +		 * ssp->clk_rate.  Otherwise we would set the rate every trasfer +		 * when the actual rate is not quite the same as requested rate. +		 */ +		spi->sck = hz; +		/* +		 * Perhaps we should return an error if the actual clock is +		 * nowhere close to what was requested? +		 */ +	} + +	writel(BM_SSP_CTRL0_LOCK_CS, +		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);  	writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) | -		     BF_SSP_CTRL1_WORD_LENGTH -		     (BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | -		     ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | -		     ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), -		     ssp->base + HW_SSP_CTRL1(ssp)); +	       BF_SSP_CTRL1_WORD_LENGTH(BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | +	       ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | +	       ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), +	       ssp->base + HW_SSP_CTRL1(ssp));  	writel(0x0, ssp->base + HW_SSP_CMD0);  	writel(0x0, ssp->base + HW_SSP_CMD1); @@ -92,28 +110,9 @@ static int mxs_spi_setup_transfer(struct spi_device *dev,  	return 0;  } -static int mxs_spi_setup(struct spi_device *dev) +static u32 mxs_spi_cs_to_reg(unsigned cs)  { -	int err = 0; - -	if (!dev->bits_per_word) -		dev->bits_per_word = 8; - -	if (dev->mode & ~(SPI_CPOL | SPI_CPHA)) -		return -EINVAL; - -	err = mxs_spi_setup_transfer(dev, NULL); -	if (err) { -		dev_err(&dev->dev, -			"Failed to setup transfer, error = %d\n", err); -	} - -	return err; -} - -static uint32_t mxs_spi_cs_to_reg(unsigned cs) -{ -	uint32_t select = 0; +	u32 select = 0;  	/*  	 * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0 @@ -131,43 +130,11 @@ static uint32_t mxs_spi_cs_to_reg(unsigned cs)  	return select;  } -static void mxs_spi_set_cs(struct mxs_spi *spi, unsigned cs) -{ -	const uint32_t mask = -		BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ; -	uint32_t select; -	struct mxs_ssp *ssp = &spi->ssp; - -	writel(mask, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); -	select = mxs_spi_cs_to_reg(cs); -	writel(select, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); -} - -static inline void mxs_spi_enable(struct mxs_spi *spi) -{ -	struct mxs_ssp *ssp = &spi->ssp; - -	writel(BM_SSP_CTRL0_LOCK_CS, -		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); -	writel(BM_SSP_CTRL0_IGNORE_CRC, -		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); -} - -static inline void mxs_spi_disable(struct mxs_spi *spi) -{ -	struct mxs_ssp *ssp = &spi->ssp; - -	writel(BM_SSP_CTRL0_LOCK_CS, -		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); -	writel(BM_SSP_CTRL0_IGNORE_CRC, -		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); -} -  static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set)  {  	const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT);  	struct mxs_ssp *ssp = &spi->ssp; -	uint32_t reg; +	u32 reg;  	do {  		reg = readl_relaxed(ssp->base + offset); @@ -200,9 +167,9 @@ static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id)  	return IRQ_HANDLED;  } -static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, +static int mxs_spi_txrx_dma(struct mxs_spi *spi,  			    unsigned char *buf, int len, -			    int *first, int *last, int write) +			    unsigned int flags)  {  	struct mxs_ssp *ssp = &spi->ssp;  	struct dma_async_tx_descriptor *desc = NULL; @@ -211,11 +178,11 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,  	const int sgs = DIV_ROUND_UP(len, desc_len);  	int sg_count;  	int min, ret; -	uint32_t ctrl0; +	u32 ctrl0;  	struct page *vm_page;  	void *sg_buf;  	struct { -		uint32_t		pio[4]; +		u32			pio[4];  		struct scatterlist	sg;  	} *dma_xfer; @@ -226,23 +193,27 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,  	if (!dma_xfer)  		return -ENOMEM; -	INIT_COMPLETION(spi->c); +	reinit_completion(&spi->c); +	/* Chip select was already programmed into CTRL0 */  	ctrl0 = readl(ssp->base + HW_SSP_CTRL0); -	ctrl0 &= ~BM_SSP_CTRL0_XFER_COUNT; -	ctrl0 |= BM_SSP_CTRL0_DATA_XFER | mxs_spi_cs_to_reg(cs); +	ctrl0 &= ~(BM_SSP_CTRL0_XFER_COUNT | BM_SSP_CTRL0_IGNORE_CRC | +		 BM_SSP_CTRL0_READ); +	ctrl0 |= BM_SSP_CTRL0_DATA_XFER; -	if (*first) -		ctrl0 |= BM_SSP_CTRL0_LOCK_CS; -	if (!write) +	if (!(flags & TXRX_WRITE))  		ctrl0 |= BM_SSP_CTRL0_READ;  	/* Queue the DMA data transfer. */  	for (sg_count = 0; sg_count < sgs; sg_count++) { +		/* Prepare the transfer descriptor. */  		min = min(len, desc_len); -		/* Prepare the transfer descriptor. */ -		if ((sg_count + 1 == sgs) && *last) +		/* +		 * De-assert CS on last segment if flag is set (i.e., no more +		 * transfers will follow) +		 */ +		if ((sg_count + 1 == sgs) && (flags & TXRX_DEASSERT_CS))  			ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC;  		if (ssp->devid == IMX23_SSP) { @@ -267,7 +238,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,  		sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min);  		ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, -			write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +			(flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);  		len -= min;  		buf += min; @@ -287,7 +258,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,  		desc = dmaengine_prep_slave_sg(ssp->dmach,  				&dma_xfer[sg_count].sg, 1, -				write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, +				(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,  				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);  		if (!desc) { @@ -324,7 +295,7 @@ err_vmalloc:  	while (--sg_count >= 0) {  err_mapped:  		dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, -			write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +			(flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);  	}  	kfree(dma_xfer); @@ -332,20 +303,19 @@ err_mapped:  	return ret;  } -static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs, +static int mxs_spi_txrx_pio(struct mxs_spi *spi,  			    unsigned char *buf, int len, -			    int *first, int *last, int write) +			    unsigned int flags)  {  	struct mxs_ssp *ssp = &spi->ssp; -	if (*first) -		mxs_spi_enable(spi); - -	mxs_spi_set_cs(spi, cs); +	writel(BM_SSP_CTRL0_IGNORE_CRC, +	       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);  	while (len--) { -		if (*last && len == 0) -			mxs_spi_disable(spi); +		if (len == 0 && (flags & TXRX_DEASSERT_CS)) +			writel(BM_SSP_CTRL0_IGNORE_CRC, +			       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);  		if (ssp->devid == IMX23_SSP) {  			writel(BM_SSP_CTRL0_XFER_COUNT, @@ -356,7 +326,7 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,  			writel(1, ssp->base + HW_SSP_XFER_SIZE);  		} -		if (write) +		if (flags & TXRX_WRITE)  			writel(BM_SSP_CTRL0_READ,  				ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);  		else @@ -369,13 +339,13 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,  		if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1))  			return -ETIMEDOUT; -		if (write) +		if (flags & TXRX_WRITE)  			writel(*buf, ssp->base + HW_SSP_DATA(ssp));  		writel(BM_SSP_CTRL0_DATA_XFER,  			     ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); -		if (!write) { +		if (!(flags & TXRX_WRITE)) {  			if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp),  						BM_SSP_STATUS_FIFO_EMPTY, 0))  				return -ETIMEDOUT; @@ -400,31 +370,25 @@ static int mxs_spi_transfer_one(struct spi_master *master,  {  	struct mxs_spi *spi = spi_master_get_devdata(master);  	struct mxs_ssp *ssp = &spi->ssp; -	int first, last; -	struct spi_transfer *t, *tmp_t; +	struct spi_transfer *t; +	unsigned int flag;  	int status = 0; -	int cs; -	first = last = 0; +	/* Program CS register bits here, it will be used for all transfers. */ +	writel(BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ, +	       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); +	writel(mxs_spi_cs_to_reg(m->spi->chip_select), +	       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); -	cs = m->spi->chip_select; - -	list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) { +	list_for_each_entry(t, &m->transfers, transfer_list) {  		status = mxs_spi_setup_transfer(m->spi, t);  		if (status)  			break; -		if (&t->transfer_list == m->transfers.next) -			first = 1; -		if (&t->transfer_list == m->transfers.prev) -			last = 1; -		if ((t->rx_buf && t->tx_buf) || (t->rx_dma && t->tx_dma)) { -			dev_err(ssp->dev, -				"Cannot send and receive simultaneously\n"); -			status = -EINVAL; -			break; -		} +		/* De-assert on last transfer, inverted by cs_change flag */ +		flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ? +		       TXRX_DEASSERT_CS : 0;  		/*  		 * Small blocks can be transfered via PIO. @@ -441,26 +405,26 @@ static int mxs_spi_transfer_one(struct spi_master *master,  				STMP_OFFSET_REG_CLR);  			if (t->tx_buf) -				status = mxs_spi_txrx_pio(spi, cs, +				status = mxs_spi_txrx_pio(spi,  						(void *)t->tx_buf, -						t->len, &first, &last, 1); +						t->len, flag | TXRX_WRITE);  			if (t->rx_buf) -				status = mxs_spi_txrx_pio(spi, cs, +				status = mxs_spi_txrx_pio(spi,  						t->rx_buf, t->len, -						&first, &last, 0); +						flag);  		} else {  			writel(BM_SSP_CTRL1_DMA_ENABLE,  				ssp->base + HW_SSP_CTRL1(ssp) +  				STMP_OFFSET_REG_SET);  			if (t->tx_buf) -				status = mxs_spi_txrx_dma(spi, cs, +				status = mxs_spi_txrx_dma(spi,  						(void *)t->tx_buf, t->len, -						&first, &last, 1); +						flag | TXRX_WRITE);  			if (t->rx_buf) -				status = mxs_spi_txrx_dma(spi, cs, +				status = mxs_spi_txrx_dma(spi,  						t->rx_buf, t->len, -						&first, &last, 0); +						flag);  		}  		if (status) { @@ -469,7 +433,6 @@ static int mxs_spi_transfer_one(struct spi_master *master,  		}  		m->actual_length += t->len; -		first = last = 0;  	}  	m->status = status; @@ -509,7 +472,7 @@ static int mxs_spi_probe(struct platform_device *pdev)  	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	irq_err = platform_get_irq(pdev, 0);  	if (irq_err < 0) -		return -EINVAL; +		return irq_err;  	base = devm_ioremap_resource(&pdev->dev, iores);  	if (IS_ERR(base)) @@ -530,7 +493,6 @@ static int mxs_spi_probe(struct platform_device *pdev)  		return -ENOMEM;  	master->transfer_one_message = mxs_spi_transfer_one; -	master->setup = mxs_spi_setup;  	master->bits_per_word_mask = SPI_BPW_MASK(8);  	master->mode_bits = SPI_CPOL | SPI_CPHA;  	master->num_chipselect = 3; @@ -563,7 +525,6 @@ static int mxs_spi_probe(struct platform_device *pdev)  		goto out_dma_release;  	clk_set_rate(ssp->clk, clk_freq); -	ssp->clk_rate = clk_get_rate(ssp->clk) / 1000;  	ret = stmp_reset_block(ssp->base);  	if (ret) @@ -571,7 +532,7 @@ static int mxs_spi_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, master); -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret) {  		dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);  		goto out_disable_clk; @@ -594,14 +555,12 @@ static int mxs_spi_remove(struct platform_device *pdev)  	struct mxs_spi *spi;  	struct mxs_ssp *ssp; -	master = spi_master_get(platform_get_drvdata(pdev)); +	master = platform_get_drvdata(pdev);  	spi = spi_master_get_devdata(master);  	ssp = &spi->ssp; -	spi_unregister_master(master);  	clk_disable_unprepare(ssp->clk);  	dma_release_channel(ssp->dmach); -	spi_master_put(master);  	return 0;  } diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 47a68b43bcd..73e91d5a43d 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c @@ -9,9 +9,7 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/spinlock.h> -#include <linux/workqueue.h>  #include <linux/interrupt.h>  #include <linux/delay.h>  #include <linux/errno.h> @@ -38,7 +36,9 @@  /* usi register bit */  #define ENINT		(0x01 << 17)  #define ENFLG		(0x01 << 16) +#define SLEEP		(0x0f << 12)  #define TXNUM		(0x03 << 8) +#define TXBITLEN	(0x1f << 3)  #define TXNEG		(0x01 << 2)  #define RXNEG		(0x01 << 1)  #define LSB		(0x01 << 10) @@ -57,13 +57,9 @@ struct nuc900_spi {  	const unsigned char	*tx;  	unsigned char		*rx;  	struct clk		*clk; -	struct resource		*ioarea;  	struct spi_master	*master; -	struct spi_device	*curdev; -	struct device		*dev;  	struct nuc900_spi_info *pdata;  	spinlock_t		lock; -	struct resource		*res;  };  static inline struct nuc900_spi *to_hw(struct spi_device *sdev) @@ -120,19 +116,16 @@ static void nuc900_spi_chipsel(struct spi_device *spi, int value)  	}  } -static void nuc900_spi_setup_txnum(struct nuc900_spi *hw, -							unsigned int txnum) +static void nuc900_spi_setup_txnum(struct nuc900_spi *hw, unsigned int txnum)  {  	unsigned int val;  	unsigned long flags;  	spin_lock_irqsave(&hw->lock, flags); -	val = __raw_readl(hw->regs + USI_CNT); +	val = __raw_readl(hw->regs + USI_CNT) & ~TXNUM; -	if (!txnum) -		val &= ~TXNUM; -	else +	if (txnum)  		val |= txnum << 0x08;  	__raw_writel(val, hw->regs + USI_CNT); @@ -149,7 +142,7 @@ static void nuc900_spi_setup_txbitlen(struct nuc900_spi *hw,  	spin_lock_irqsave(&hw->lock, flags); -	val = __raw_readl(hw->regs + USI_CNT); +	val = __raw_readl(hw->regs + USI_CNT) & ~TXBITLEN;  	val |= (txbitlen << 0x03); @@ -288,12 +281,11 @@ static void nuc900_set_sleep(struct nuc900_spi *hw, unsigned int sleep)  	spin_lock_irqsave(&hw->lock, flags); -	val = __raw_readl(hw->regs + USI_CNT); +	val = __raw_readl(hw->regs + USI_CNT) & ~SLEEP;  	if (sleep)  		val |= (sleep << 12); -	else -		val &= ~(0x0f << 12); +  	__raw_writel(val, hw->regs + USI_CNT);  	spin_unlock_irqrestore(&hw->lock, flags); @@ -339,19 +331,18 @@ static int nuc900_spi_probe(struct platform_device *pdev)  {  	struct nuc900_spi *hw;  	struct spi_master *master; +	struct resource *res;  	int err = 0;  	master = spi_alloc_master(&pdev->dev, sizeof(struct nuc900_spi));  	if (master == NULL) {  		dev_err(&pdev->dev, "No memory for spi_master\n"); -		err = -ENOMEM; -		goto err_nomem; +		return -ENOMEM;  	}  	hw = spi_master_get_devdata(master); -	hw->master = spi_master_get(master); +	hw->master = master;  	hw->pdata  = dev_get_platdata(&pdev->dev); -	hw->dev = &pdev->dev;  	if (hw->pdata == NULL) {  		dev_err(&pdev->dev, "No platform data supplied\n"); @@ -363,53 +354,40 @@ static int nuc900_spi_probe(struct platform_device *pdev)  	init_completion(&hw->done);  	master->mode_bits          = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; +	if (hw->pdata->lsb) +		master->mode_bits |= SPI_LSB_FIRST;  	master->num_chipselect     = hw->pdata->num_cs;  	master->bus_num            = hw->pdata->bus_num;  	hw->bitbang.master         = hw->master;  	hw->bitbang.chipselect     = nuc900_spi_chipsel;  	hw->bitbang.txrx_bufs      = nuc900_spi_txrx; -	hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (hw->res == NULL) { -		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); -		err = -ENOENT; -		goto err_pdata; -	} - -	hw->ioarea = request_mem_region(hw->res->start, -					resource_size(hw->res), pdev->name); - -	if (hw->ioarea == NULL) { -		dev_err(&pdev->dev, "Cannot reserve region\n"); -		err = -ENXIO; +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	hw->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hw->regs)) { +		err = PTR_ERR(hw->regs);  		goto err_pdata;  	} -	hw->regs = ioremap(hw->res->start, resource_size(hw->res)); -	if (hw->regs == NULL) { -		dev_err(&pdev->dev, "Cannot map IO\n"); -		err = -ENXIO; -		goto err_iomap; -	} -  	hw->irq = platform_get_irq(pdev, 0);  	if (hw->irq < 0) {  		dev_err(&pdev->dev, "No IRQ specified\n");  		err = -ENOENT; -		goto err_irq; +		goto err_pdata;  	} -	err = request_irq(hw->irq, nuc900_spi_irq, 0, pdev->name, hw); +	err = devm_request_irq(&pdev->dev, hw->irq, nuc900_spi_irq, 0, +				pdev->name, hw);  	if (err) {  		dev_err(&pdev->dev, "Cannot claim IRQ\n"); -		goto err_irq; +		goto err_pdata;  	} -	hw->clk = clk_get(&pdev->dev, "spi"); +	hw->clk = devm_clk_get(&pdev->dev, "spi");  	if (IS_ERR(hw->clk)) {  		dev_err(&pdev->dev, "No clock for device\n");  		err = PTR_ERR(hw->clk); -		goto err_clk; +		goto err_pdata;  	}  	mfp_set_groupg(&pdev->dev, NULL); @@ -425,18 +403,8 @@ static int nuc900_spi_probe(struct platform_device *pdev)  err_register:  	clk_disable(hw->clk); -	clk_put(hw->clk); -err_clk: -	free_irq(hw->irq, hw); -err_irq: -	iounmap(hw->regs); -err_iomap: -	release_mem_region(hw->res->start, resource_size(hw->res)); -	kfree(hw->ioarea);  err_pdata:  	spi_master_put(hw->master); - -err_nomem:  	return err;  } @@ -444,18 +412,8 @@ static int nuc900_spi_remove(struct platform_device *dev)  {  	struct nuc900_spi *hw = platform_get_drvdata(dev); -	free_irq(hw->irq, hw); -  	spi_bitbang_stop(&hw->bitbang); -  	clk_disable(hw->clk); -	clk_put(hw->clk); - -	iounmap(hw->regs); - -	release_mem_region(hw->res->start, resource_size(hw->res)); -	kfree(hw->ioarea); -  	spi_master_put(hw->master);  	return 0;  } diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 333cb1badcd..8998d11c723 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -15,7 +15,6 @@   * published by the Free Software Foundation.   */ -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/errno.h>  #include <linux/module.h> @@ -153,62 +152,22 @@ static int tiny_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  		}  		wait_for_completion(&hw->done); -	} else if (txp && rxp) { -		/* we need to tighten the transfer loop */ -		writeb(*txp++, hw->base + TINY_SPI_TXDATA); -		if (t->len > 1) { -			writeb(*txp++, hw->base + TINY_SPI_TXDATA); -			for (i = 2; i < t->len; i++) { -				u8 rx, tx = *txp++; -				tiny_spi_wait_txr(hw); -				rx = readb(hw->base + TINY_SPI_TXDATA); -				writeb(tx, hw->base + TINY_SPI_TXDATA); -				*rxp++ = rx; -			} -			tiny_spi_wait_txr(hw); -			*rxp++ = readb(hw->base + TINY_SPI_TXDATA); -		} -		tiny_spi_wait_txe(hw); -		*rxp++ = readb(hw->base + TINY_SPI_RXDATA); -	} else if (rxp) { -		writeb(0, hw->base + TINY_SPI_TXDATA); -		if (t->len > 1) { -			writeb(0, -			       hw->base + TINY_SPI_TXDATA); -			for (i = 2; i < t->len; i++) { -				u8 rx; -				tiny_spi_wait_txr(hw); -				rx = readb(hw->base + TINY_SPI_TXDATA); -				writeb(0, hw->base + TINY_SPI_TXDATA); -				*rxp++ = rx; -			} -			tiny_spi_wait_txr(hw); -			*rxp++ = readb(hw->base + TINY_SPI_TXDATA); -		} -		tiny_spi_wait_txe(hw); -		*rxp++ = readb(hw->base + TINY_SPI_RXDATA); -	} else if (txp) { -		writeb(*txp++, hw->base + TINY_SPI_TXDATA); -		if (t->len > 1) { -			writeb(*txp++, hw->base + TINY_SPI_TXDATA); -			for (i = 2; i < t->len; i++) { -				u8 tx = *txp++; -				tiny_spi_wait_txr(hw); -				writeb(tx, hw->base + TINY_SPI_TXDATA); -			} -		} -		tiny_spi_wait_txe(hw);  	} else { -		writeb(0, hw->base + TINY_SPI_TXDATA); -		if (t->len > 1) { -			writeb(0, hw->base + TINY_SPI_TXDATA); -			for (i = 2; i < t->len; i++) { +		/* we need to tighten the transfer loop */ +		writeb(txp ? *txp++ : 0, hw->base + TINY_SPI_TXDATA); +		for (i = 1; i < t->len; i++) { +			writeb(txp ? *txp++ : 0, hw->base + TINY_SPI_TXDATA); + +			if (rxp || (i != t->len - 1))  				tiny_spi_wait_txr(hw); -				writeb(0, hw->base + TINY_SPI_TXDATA); -			} +			if (rxp) +				*rxp++ = readb(hw->base + TINY_SPI_TXDATA);  		}  		tiny_spi_wait_txe(hw); +		if (rxp) +			*rxp++ = readb(hw->base + TINY_SPI_RXDATA);  	} +  	return t->len;  } @@ -306,9 +265,7 @@ static int tiny_spi_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, hw);  	/* setup the state for the bitbang driver */ -	hw->bitbang.master = spi_master_get(master); -	if (!hw->bitbang.master) -		return err; +	hw->bitbang.master = master;  	hw->bitbang.setup_transfer = tiny_spi_setup_transfer;  	hw->bitbang.chipselect = tiny_spi_chipselect;  	hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs; diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index 5f28ddbe4f7..c5e2f718eeb 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -11,7 +11,6 @@  #include <linux/spi/spi.h>  #include <linux/module.h>  #include <linux/delay.h> -#include <linux/init.h>  #include <linux/io.h>  #include <linux/of.h> @@ -33,13 +32,6 @@ struct octeon_spi {  	u64 cs_enax;  }; -struct octeon_spi_setup { -	u32 max_speed_hz; -	u8 chip_select; -	u8 mode; -	u8 bits_per_word; -}; -  static void octeon_spi_wait_ready(struct octeon_spi *p)  {  	union cvmx_mpi_sts mpi_sts; @@ -57,6 +49,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,  				  struct spi_transfer *xfer,  				  bool last_xfer)  { +	struct spi_device *spi = msg->spi;  	union cvmx_mpi_cfg mpi_cfg;  	union cvmx_mpi_tx mpi_tx;  	unsigned int clkdiv; @@ -68,18 +61,11 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,  	int len;  	int i; -	struct octeon_spi_setup *msg_setup = spi_get_ctldata(msg->spi); - -	speed_hz = msg_setup->max_speed_hz; -	mode = msg_setup->mode; +	mode = spi->mode;  	cpha = mode & SPI_CPHA;  	cpol = mode & SPI_CPOL; -	if (xfer->speed_hz) -		speed_hz = xfer->speed_hz; - -	if (speed_hz > OCTEON_SPI_MAX_CLOCK_HZ) -		speed_hz = OCTEON_SPI_MAX_CLOCK_HZ; +	speed_hz = xfer->speed_hz ? : spi->max_speed_hz;  	clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz); @@ -93,8 +79,8 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,  	mpi_cfg.s.cslate = cpha ? 1 : 0;  	mpi_cfg.s.enable = 1; -	if (msg_setup->chip_select < 4) -		p->cs_enax |= 1ull << (12 + msg_setup->chip_select); +	if (spi->chip_select < 4) +		p->cs_enax |= 1ull << (12 + spi->chip_select);  	mpi_cfg.u64 |= p->cs_enax;  	if (mpi_cfg.u64 != p->last_cfg) { @@ -114,7 +100,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,  			cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);  		}  		mpi_tx.u64 = 0; -		mpi_tx.s.csid = msg_setup->chip_select; +		mpi_tx.s.csid = spi->chip_select;  		mpi_tx.s.leavecs = 1;  		mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;  		mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES; @@ -139,7 +125,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,  	}  	mpi_tx.u64 = 0; -	mpi_tx.s.csid = msg_setup->chip_select; +	mpi_tx.s.csid = spi->chip_select;  	if (last_xfer)  		mpi_tx.s.leavecs = xfer->cs_change;  	else @@ -169,17 +155,9 @@ static int octeon_spi_transfer_one_message(struct spi_master *master,  	int status = 0;  	struct spi_transfer *xfer; -	/* -	 * We better have set the configuration via a call to .setup -	 * before we get here. -	 */ -	if (spi_get_ctldata(msg->spi) == NULL) { -		status = -EINVAL; -		goto err; -	} -  	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		bool last_xfer = &xfer->transfer_list == msg->transfers.prev; +		bool last_xfer = list_is_last(&xfer->transfer_list, +					      &msg->transfers);  		int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer);  		if (r < 0) {  			status = r; @@ -194,41 +172,6 @@ err:  	return status;  } -static struct octeon_spi_setup *octeon_spi_new_setup(struct spi_device *spi) -{ -	struct octeon_spi_setup *setup = kzalloc(sizeof(*setup), GFP_KERNEL); -	if (!setup) -		return NULL; - -	setup->max_speed_hz = spi->max_speed_hz; -	setup->chip_select = spi->chip_select; -	setup->mode = spi->mode; -	setup->bits_per_word = spi->bits_per_word; -	return setup; -} - -static int octeon_spi_setup(struct spi_device *spi) -{ -	struct octeon_spi_setup *new_setup; -	struct octeon_spi_setup *old_setup = spi_get_ctldata(spi); - -	new_setup = octeon_spi_new_setup(spi); -	if (!new_setup) -		return -ENOMEM; - -	spi_set_ctldata(spi, new_setup); -	kfree(old_setup); - -	return 0; -} - -static void octeon_spi_cleanup(struct spi_device *spi) -{ -	struct octeon_spi_setup *old_setup = spi_get_ctldata(spi); -	spi_set_ctldata(spi, NULL); -	kfree(old_setup); -} -  static int octeon_spi_probe(struct platform_device *pdev)  {  	struct resource *res_mem; @@ -257,8 +200,6 @@ static int octeon_spi_probe(struct platform_device *pdev)  	p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start,  					     resource_size(res_mem)); -	/* Dynamic bus numbering */ -	master->bus_num = -1;  	master->num_chipselect = 4;  	master->mode_bits = SPI_CPHA |  			    SPI_CPOL | @@ -266,13 +207,12 @@ static int octeon_spi_probe(struct platform_device *pdev)  			    SPI_LSB_FIRST |  			    SPI_3WIRE; -	master->setup = octeon_spi_setup; -	master->cleanup = octeon_spi_cleanup;  	master->transfer_one_message = octeon_spi_transfer_one_message;  	master->bits_per_word_mask = SPI_BPW_MASK(8); +	master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;  	master->dev.of_node = pdev->dev.of_node; -	err = spi_register_master(master); +	err = devm_spi_register_master(&pdev->dev, master);  	if (err) {  		dev_err(&pdev->dev, "register master failed: %d\n", err);  		goto fail; @@ -292,8 +232,6 @@ static int octeon_spi_remove(struct platform_device *pdev)  	struct octeon_spi *p = spi_master_get_devdata(master);  	u64 register_base = p->register_base; -	spi_unregister_master(master); -  	/* Clear the CSENA* and put everything in a known state. */  	cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0); diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 69ecf05757d..e7ffcded4e1 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -83,15 +83,11 @@  #define SPI_SHUTDOWN	1  struct omap1_spi100k { -	struct spi_master       *master;  	struct clk              *ick;  	struct clk              *fck;  	/* Virtual base address of the controller */  	void __iomem            *base; - -	/* State of the SPI */ -	unsigned int		state;  };  struct omap1_spi100k_cs { @@ -99,13 +95,6 @@ struct omap1_spi100k_cs {  	int                     word_len;  }; -#define MOD_REG_BIT(val, mask, set) do { \ -	if (set) \ -		val |= mask; \ -	else \ -		val &= ~mask; \ -} while (0) -  static void spi100k_enable_clock(struct spi_master *master)  {  	unsigned int val; @@ -139,7 +128,7 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)  	}  	spi100k_enable_clock(master); -	writew( data , spi100k->base + SPI_TX_MSB); +	writew(data , spi100k->base + SPI_TX_MSB);  	writew(SPI_CTRL_SEN(0) |  	       SPI_CTRL_WORD_SIZE(len) | @@ -147,7 +136,8 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)  	       spi100k->base + SPI_CTRL);  	/* Wait for bit ack send change */ -	while((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_WE) != SPI_STATUS_WE); +	while ((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_WE) != SPI_STATUS_WE) +		;  	udelay(1000);  	spi100k_disable_clock(master); @@ -155,7 +145,7 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)  static int spi100k_read_data(struct spi_master *master, int len)  { -	int dataH,dataL; +	int dataH, dataL;  	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);  	/* Always do at least 16 bits */ @@ -168,7 +158,8 @@ static int spi100k_read_data(struct spi_master *master, int len)  	       SPI_CTRL_RD,  	       spi100k->base + SPI_CTRL); -	while((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_RD) != SPI_STATUS_RD); +	while ((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_RD) != SPI_STATUS_RD) +		;  	udelay(1000);  	dataL = readw(spi100k->base + SPI_RX_LSB); @@ -204,12 +195,10 @@ static void omap1_spi100k_force_cs(struct omap1_spi100k *spi100k, int enable)  static unsigned  omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  { -	struct omap1_spi100k    *spi100k;  	struct omap1_spi100k_cs *cs = spi->controller_state;  	unsigned int            count, c;  	int                     word_len; -	spi100k = spi_master_get_devdata(spi->master);  	count = xfer->len;  	c = count;  	word_len = cs->word_len; @@ -221,12 +210,12 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  		rx = xfer->rx_buf;  		tx = xfer->tx_buf;  		do { -			c-=1; +			c -= 1;  			if (xfer->tx_buf != NULL)  				spi100k_write_data(spi->master, word_len, *tx++);  			if (xfer->rx_buf != NULL)  				*rx++ = spi100k_read_data(spi->master, word_len); -		} while(c); +		} while (c);  	} else if (word_len <= 16) {  		u16             *rx;  		const u16       *tx; @@ -234,12 +223,12 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  		rx = xfer->rx_buf;  		tx = xfer->tx_buf;  		do { -			c-=2; +			c -= 2;  			if (xfer->tx_buf != NULL) -				spi100k_write_data(spi->master,word_len, *tx++); +				spi100k_write_data(spi->master, word_len, *tx++);  			if (xfer->rx_buf != NULL) -				*rx++ = spi100k_read_data(spi->master,word_len); -		} while(c); +				*rx++ = spi100k_read_data(spi->master, word_len); +		} while (c);  	} else if (word_len <= 32) {  		u32             *rx;  		const u32       *tx; @@ -247,12 +236,12 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  		rx = xfer->rx_buf;  		tx = xfer->tx_buf;  		do { -			c-=4; +			c -= 4;  			if (xfer->tx_buf != NULL) -				spi100k_write_data(spi->master,word_len, *tx); +				spi100k_write_data(spi->master, word_len, *tx);  			if (xfer->rx_buf != NULL) -				*rx = spi100k_read_data(spi->master,word_len); -		} while(c); +				*rx = spi100k_read_data(spi->master, word_len); +		} while (c);  	}  	return count - c;  } @@ -294,7 +283,7 @@ static int omap1_spi100k_setup(struct spi_device *spi)  	spi100k = spi_master_get_devdata(spi->master);  	if (!cs) { -		cs = kzalloc(sizeof *cs, GFP_KERNEL); +		cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL);  		if (!cs)  			return -ENOMEM;  		cs->base = spi100k->base + spi->chip_select * 0x14; @@ -411,14 +400,14 @@ static int omap1_spi100k_probe(struct platform_device *pdev)  	if (!pdev->id)  		return -EINVAL; -	master = spi_alloc_master(&pdev->dev, sizeof *spi100k); +	master = spi_alloc_master(&pdev->dev, sizeof(*spi100k));  	if (master == NULL) {  		dev_dbg(&pdev->dev, "master allocation failed\n");  		return -ENOMEM;  	}  	if (pdev->id != -1) -	       master->bus_num = pdev->id; +		master->bus_num = pdev->id;  	master->setup = omap1_spi100k_setup;  	master->transfer_one_message = omap1_spi100k_transfer_one_message; @@ -434,7 +423,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, master);  	spi100k = spi_master_get_devdata(master); -	spi100k->master = master;  	/*  	 * The memory region base address is taken as the platform_data. @@ -457,12 +445,10 @@ static int omap1_spi100k_probe(struct platform_device *pdev)  		goto err;  	} -	status = spi_register_master(master); +	status = devm_spi_register_master(&pdev->dev, master);  	if (status < 0)  		goto err; -	spi100k->state = SPI_RUNNING; -  	return status;  err: @@ -470,33 +456,12 @@ err:  	return status;  } -static int omap1_spi100k_remove(struct platform_device *pdev) -{ -	struct spi_master       *master; -	struct omap1_spi100k    *spi100k; -	struct resource         *r; -	int			status = 0; - -	master = platform_get_drvdata(pdev); -	spi100k = spi_master_get_devdata(master); - -	if (status != 0) -		return status; - -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - -	spi_unregister_master(master); - -	return 0; -} -  static struct platform_driver omap1_spi100k_driver = {  	.driver = {  		.name		= "omap1_spi100k",  		.owner		= THIS_MODULE,  	},  	.probe		= omap1_spi100k_probe, -	.remove		= omap1_spi100k_remove,  };  module_platform_driver(omap1_spi100k_driver); @@ -504,4 +469,3 @@ module_platform_driver(omap1_spi100k_driver);  MODULE_DESCRIPTION("OMAP7xx SPI 100k controller driver");  MODULE_AUTHOR("Fabrice Crohas <fcrohas@gmail.com>");  MODULE_LICENSE("GPL"); - diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index a6a8f096175..0f5a0aa3b87 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -37,7 +37,6 @@  #include <linux/init.h>  #include <linux/delay.h>  #include <linux/platform_device.h> -#include <linux/workqueue.h>  #include <linux/interrupt.h>  #include <linux/err.h>  #include <linux/clk.h> @@ -99,7 +98,6 @@ struct uwire_spi {  };  struct uwire_state { -	unsigned	bits_per_word;  	unsigned	div1_idx;  }; @@ -210,9 +208,8 @@ static void uwire_chipselect(struct spi_device *spi, int value)  static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)  { -	struct uwire_state *ust = spi->controller_state;  	unsigned	len = t->len; -	unsigned	bits = ust->bits_per_word; +	unsigned	bits = t->bits_per_word ? : spi->bits_per_word;  	unsigned	bytes;  	u16		val, w;  	int		status = 0; @@ -220,10 +217,6 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)  	if (!t->tx_buf && !t->rx_buf)  		return 0; -	/* Microwire doesn't read and write concurrently */ -	if (t->tx_buf && t->rx_buf) -		return -EPERM; -  	w = spi->chip_select << 10;  	w |= CS_CMD; @@ -322,7 +315,6 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  	struct uwire_state	*ust = spi->controller_state;  	struct uwire_spi	*uwire;  	unsigned		flags = 0; -	unsigned		bits;  	unsigned		hz;  	unsigned long		rate;  	int			div1_idx; @@ -332,23 +324,6 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  	uwire = spi_master_get_devdata(spi->master); -	if (spi->chip_select > 3) { -		pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select); -		status = -ENODEV; -		goto done; -	} - -	bits = spi->bits_per_word; -	if (t != NULL && t->bits_per_word) -		bits = t->bits_per_word; - -	if (bits > 16) { -		pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits); -		status = -ENODEV; -		goto done; -	} -	ust->bits_per_word = bits; -  	/* mode 0..3, clock inverted separately;  	 * standard nCS signaling;  	 * don't treat DI=high as "not ready" @@ -502,6 +477,7 @@ static int uwire_probe(struct platform_device *pdev)  		status = PTR_ERR(uwire->ck);  		dev_dbg(&pdev->dev, "no functional clock?\n");  		spi_master_put(master); +		iounmap(uwire_base);  		return status;  	}  	clk_enable(uwire->ck); @@ -515,7 +491,7 @@ static int uwire_probe(struct platform_device *pdev)  	/* the spi->mode bits understood by this driver: */  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - +	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);  	master->flags = SPI_MASTER_HALF_DUPLEX;  	master->bus_num = 2;	/* "official" */ @@ -539,14 +515,13 @@ static int uwire_probe(struct platform_device *pdev)  static int uwire_remove(struct platform_device *pdev)  {  	struct uwire_spi	*uwire = platform_get_drvdata(pdev); -	int			status;  	// FIXME remove all child devices, somewhere ... -	status = spi_bitbang_stop(&uwire->bitbang); +	spi_bitbang_stop(&uwire->bitbang);  	uwire_off(uwire);  	iounmap(uwire_base); -	return status; +	return 0;  }  /* work with hotplug and coldplug */ @@ -557,7 +532,8 @@ static struct platform_driver uwire_driver = {  		.name		= "omap_uwire",  		.owner		= THIS_MODULE,  	}, -	.remove		= uwire_remove, +	.probe = uwire_probe, +	.remove = uwire_remove,  	// suspend ... unuse ck  	// resume ... use ck  }; @@ -579,7 +555,7 @@ static int __init omap_uwire_init(void)  		omap_writel(val | 0x00AAA000, OMAP7XX_IO_CONF_9);  	} -	return platform_driver_probe(&uwire_driver, uwire_probe); +	return platform_driver_register(&uwire_driver);  }  static void __exit omap_uwire_exit(void) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index ed4af4708d9..4dc77df3886 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -22,7 +22,6 @@   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/module.h>  #include <linux/device.h> @@ -45,6 +44,7 @@  #include <linux/platform_data/spi-omap2-mcspi.h>  #define OMAP2_MCSPI_MAX_FREQ		48000000 +#define OMAP2_MCSPI_MAX_DIVIDER		4096  #define OMAP2_MCSPI_MAX_FIFODEPTH	64  #define OMAP2_MCSPI_MAX_FIFOWCNT	0xFFFF  #define SPI_AUTOSUSPEND_TIMEOUT		2000 @@ -89,6 +89,7 @@  #define OMAP2_MCSPI_CHCONF_FORCE	BIT(20)  #define OMAP2_MCSPI_CHCONF_FFET		BIT(27)  #define OMAP2_MCSPI_CHCONF_FFER		BIT(28) +#define OMAP2_MCSPI_CHCONF_CLKG		BIT(29)  #define OMAP2_MCSPI_CHSTAT_RXS		BIT(0)  #define OMAP2_MCSPI_CHSTAT_TXS		BIT(1) @@ -96,6 +97,7 @@  #define OMAP2_MCSPI_CHSTAT_TXFFE	BIT(3)  #define OMAP2_MCSPI_CHCTRL_EN		BIT(0) +#define OMAP2_MCSPI_CHCTRL_EXTCLK_MASK	(0xff << 8)  #define OMAP2_MCSPI_WAKEUPENABLE_WKEN	BIT(0) @@ -149,7 +151,7 @@ struct omap2_mcspi_cs {  	int			word_len;  	struct list_head	node;  	/* Context save and restore shadow register */ -	u32			chconf0; +	u32			chconf0, chctrl0;  };  static inline void mcspi_write_reg(struct spi_master *master, @@ -157,14 +159,14 @@ static inline void mcspi_write_reg(struct spi_master *master,  {  	struct omap2_mcspi *mcspi = spi_master_get_devdata(master); -	__raw_writel(val, mcspi->base + idx); +	writel_relaxed(val, mcspi->base + idx);  }  static inline u32 mcspi_read_reg(struct spi_master *master, int idx)  {  	struct omap2_mcspi *mcspi = spi_master_get_devdata(master); -	return __raw_readl(mcspi->base + idx); +	return readl_relaxed(mcspi->base + idx);  }  static inline void mcspi_write_cs_reg(const struct spi_device *spi, @@ -172,14 +174,14 @@ static inline void mcspi_write_cs_reg(const struct spi_device *spi,  {  	struct omap2_mcspi_cs	*cs = spi->controller_state; -	__raw_writel(val, cs->base +  idx); +	writel_relaxed(val, cs->base +  idx);  }  static inline u32 mcspi_read_cs_reg(const struct spi_device *spi, int idx)  {  	struct omap2_mcspi_cs	*cs = spi->controller_state; -	return __raw_readl(cs->base + idx); +	return readl_relaxed(cs->base + idx);  }  static inline u32 mcspi_cached_chconf0(const struct spi_device *spi) @@ -230,10 +232,16 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi,  static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)  { +	struct omap2_mcspi_cs *cs = spi->controller_state;  	u32 l; -	l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0; -	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, l); +	l = cs->chctrl0; +	if (enable) +		l |= OMAP2_MCSPI_CHCTRL_EN; +	else +		l &= ~OMAP2_MCSPI_CHCTRL_EN; +	cs->chctrl0 = l; +	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);  	/* Flash post-writes */  	mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);  } @@ -276,7 +284,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,  	struct omap2_mcspi_cs *cs = spi->controller_state;  	struct omap2_mcspi *mcspi;  	unsigned int wcnt; -	int fifo_depth, bytes_per_word; +	int max_fifo_depth, fifo_depth, bytes_per_word;  	u32 chconf, xferlevel;  	mcspi = spi_master_get_devdata(master); @@ -287,7 +295,12 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,  		if (t->len % bytes_per_word != 0)  			goto disable_fifo; -		fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH); +		if (t->rx_buf != NULL && t->tx_buf != NULL) +			max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH / 2; +		else +			max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH; + +		fifo_depth = gcd(t->len, max_fifo_depth);  		if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)  			goto disable_fifo; @@ -299,7 +312,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,  		if (t->rx_buf != NULL) {  			chconf |= OMAP2_MCSPI_CHCONF_FFER;  			xferlevel |= (fifo_depth - 1) << 8; -		} else { +		} +		if (t->tx_buf != NULL) {  			chconf |= OMAP2_MCSPI_CHCONF_FFET;  			xferlevel |= fifo_depth - 1;  		} @@ -332,7 +346,7 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)  	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable);  	list_for_each_entry(cs, &ctx->cs, node) -		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); +		writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);  }  static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) @@ -340,9 +354,9 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)  	unsigned long timeout;  	timeout = jiffies + msecs_to_jiffies(1000); -	while (!(__raw_readl(reg) & bit)) { +	while (!(readl_relaxed(reg) & bit)) {  		if (time_after(jiffies, timeout)) { -			if (!(__raw_readl(reg) & bit)) +			if (!(readl_relaxed(reg) & bit))  				return -ETIMEDOUT;  			else  				return 0; @@ -498,7 +512,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,  				((u32 *)xfer->rx_buf)[elements++] = w;  		} else {  			int bytes_per_word = mcspi_bytes_per_word(word_len); -			dev_err(&spi->dev, "DMA RX penultimate word empty"); +			dev_err(&spi->dev, "DMA RX penultimate word empty\n");  			count -= (bytes_per_word << 1);  			omap2_mcspi_set_enable(spi, 1);  			return count; @@ -516,7 +530,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,  		else /* word_len <= 32 */  			((u32 *)xfer->rx_buf)[elements] = w;  	} else { -		dev_err(&spi->dev, "DMA RX last word empty"); +		dev_err(&spi->dev, "DMA RX last word empty\n");  		count -= mcspi_bytes_per_word(word_len);  	}  	omap2_mcspi_set_enable(spi, 1); @@ -669,7 +683,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  				}  				dev_vdbg(&spi->dev, "write-%d %02x\n",  						word_len, *tx); -				__raw_writel(*tx++, tx_reg); +				writel_relaxed(*tx++, tx_reg);  			}  			if (rx != NULL) {  				if (mcspi_wait_for_reg_bit(chstat_reg, @@ -681,7 +695,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  				if (c == 1 && tx == NULL &&  				    (l & OMAP2_MCSPI_CHCONF_TURBO)) {  					omap2_mcspi_set_enable(spi, 0); -					*rx++ = __raw_readl(rx_reg); +					*rx++ = readl_relaxed(rx_reg);  					dev_vdbg(&spi->dev, "read-%d %02x\n",  						    word_len, *(rx - 1));  					if (mcspi_wait_for_reg_bit(chstat_reg, @@ -695,7 +709,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  					omap2_mcspi_set_enable(spi, 0);  				} -				*rx++ = __raw_readl(rx_reg); +				*rx++ = readl_relaxed(rx_reg);  				dev_vdbg(&spi->dev, "read-%d %02x\n",  						word_len, *(rx - 1));  			} @@ -716,7 +730,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  				}  				dev_vdbg(&spi->dev, "write-%d %04x\n",  						word_len, *tx); -				__raw_writel(*tx++, tx_reg); +				writel_relaxed(*tx++, tx_reg);  			}  			if (rx != NULL) {  				if (mcspi_wait_for_reg_bit(chstat_reg, @@ -728,7 +742,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  				if (c == 2 && tx == NULL &&  				    (l & OMAP2_MCSPI_CHCONF_TURBO)) {  					omap2_mcspi_set_enable(spi, 0); -					*rx++ = __raw_readl(rx_reg); +					*rx++ = readl_relaxed(rx_reg);  					dev_vdbg(&spi->dev, "read-%d %04x\n",  						    word_len, *(rx - 1));  					if (mcspi_wait_for_reg_bit(chstat_reg, @@ -742,7 +756,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  					omap2_mcspi_set_enable(spi, 0);  				} -				*rx++ = __raw_readl(rx_reg); +				*rx++ = readl_relaxed(rx_reg);  				dev_vdbg(&spi->dev, "read-%d %04x\n",  						word_len, *(rx - 1));  			} @@ -763,7 +777,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  				}  				dev_vdbg(&spi->dev, "write-%d %08x\n",  						word_len, *tx); -				__raw_writel(*tx++, tx_reg); +				writel_relaxed(*tx++, tx_reg);  			}  			if (rx != NULL) {  				if (mcspi_wait_for_reg_bit(chstat_reg, @@ -775,7 +789,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  				if (c == 4 && tx == NULL &&  				    (l & OMAP2_MCSPI_CHCONF_TURBO)) {  					omap2_mcspi_set_enable(spi, 0); -					*rx++ = __raw_readl(rx_reg); +					*rx++ = readl_relaxed(rx_reg);  					dev_vdbg(&spi->dev, "read-%d %08x\n",  						    word_len, *(rx - 1));  					if (mcspi_wait_for_reg_bit(chstat_reg, @@ -789,7 +803,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)  					omap2_mcspi_set_enable(spi, 0);  				} -				*rx++ = __raw_readl(rx_reg); +				*rx++ = readl_relaxed(rx_reg);  				dev_vdbg(&spi->dev, "read-%d %08x\n",  						word_len, *(rx - 1));  			} @@ -834,7 +848,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,  	struct omap2_mcspi_cs *cs = spi->controller_state;  	struct omap2_mcspi *mcspi;  	struct spi_master *spi_cntrl; -	u32 l = 0, div = 0; +	u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0;  	u8 word_len = spi->bits_per_word;  	u32 speed_hz = spi->max_speed_hz; @@ -850,7 +864,17 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,  		speed_hz = t->speed_hz;  	speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ); -	div = omap2_mcspi_calc_divisor(speed_hz); +	if (speed_hz < (OMAP2_MCSPI_MAX_FREQ / OMAP2_MCSPI_MAX_DIVIDER)) { +		clkd = omap2_mcspi_calc_divisor(speed_hz); +		speed_hz = OMAP2_MCSPI_MAX_FREQ >> clkd; +		clkg = 0; +	} else { +		div = (OMAP2_MCSPI_MAX_FREQ + speed_hz - 1) / speed_hz; +		speed_hz = OMAP2_MCSPI_MAX_FREQ / div; +		clkd = (div - 1) & 0xf; +		extclk = (div - 1) >> 4; +		clkg = OMAP2_MCSPI_CHCONF_CLKG; +	}  	l = mcspi_cached_chconf0(spi); @@ -879,7 +903,16 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,  	/* set clock divisor */  	l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK; -	l |= div << 2; +	l |= clkd << 2; + +	/* set clock granularity */ +	l &= ~OMAP2_MCSPI_CHCONF_CLKG; +	l |= clkg; +	if (clkg) { +		cs->chctrl0 &= ~OMAP2_MCSPI_CHCTRL_EXTCLK_MASK; +		cs->chctrl0 |= extclk << 8; +		mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0); +	}  	/* set SPI mode 0..3 */  	if (spi->mode & SPI_CPOL) @@ -894,7 +927,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,  	mcspi_write_chconf0(spi, l);  	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", -			OMAP2_MCSPI_MAX_FREQ >> div, +			speed_hz,  			(spi->mode & SPI_CPHA) ? "trailing" : "leading",  			(spi->mode & SPI_CPOL) ? "inverted" : "normal"); @@ -966,6 +999,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)  		cs->base = mcspi->base + spi->chip_select * 0x14;  		cs->phys = mcspi->phys + spi->chip_select * 0x14;  		cs->chconf0 = 0; +		cs->chctrl0 = 0;  		spi->controller_state = cs;  		/* Link this to context save list */  		list_add_tail(&cs->node, &ctx->cs); @@ -1051,12 +1085,15 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)  			status = -EINVAL;  			break;  		} -		if (par_override || t->speed_hz || t->bits_per_word) { +		if (par_override || +		    (t->speed_hz != spi->max_speed_hz) || +		    (t->bits_per_word != spi->bits_per_word)) {  			par_override = 1;  			status = omap2_mcspi_setup_transfer(spi, t);  			if (status < 0)  				break; -			if (!t->speed_hz && !t->bits_per_word) +			if (t->speed_hz == spi->max_speed_hz && +			    t->bits_per_word == spi->bits_per_word)  				par_override = 0;  		}  		if (cd && cd->cs_per_word) { @@ -1101,7 +1138,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)  			/* RX_ONLY mode needs dummy data in TX reg */  			if (t->tx_buf == NULL) -				__raw_writel(0, cs->base +				writel_relaxed(0, cs->base  						+ OMAP2_MCSPI_TX0);  			if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && @@ -1170,16 +1207,12 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,  	m->actual_length = 0;  	m->status = 0; -	/* reject invalid messages and transfers */ -	if (list_empty(&m->transfers)) -		return -EINVAL;  	list_for_each_entry(t, &m->transfers, transfer_list) {  		const void	*tx_buf = t->tx_buf;  		void		*rx_buf = t->rx_buf;  		unsigned	len = t->len; -		if (t->speed_hz > OMAP2_MCSPI_MAX_FREQ -				|| (len && !(rx_buf || tx_buf))) { +		if ((len && !(rx_buf || tx_buf))) {  			dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",  					t->speed_hz,  					len, @@ -1188,12 +1221,6 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,  					t->bits_per_word);  			return -EINVAL;  		} -		if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) { -			dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n", -					t->speed_hz, -					OMAP2_MCSPI_MAX_FREQ >> 15); -			return -EINVAL; -		}  		if (m->is_dma_mapped || len < DMA_MIN_BYTES)  			continue; @@ -1305,6 +1332,8 @@ static int omap2_mcspi_probe(struct platform_device *pdev)  	master->transfer_one_message = omap2_mcspi_transfer_one_message;  	master->cleanup = omap2_mcspi_cleanup;  	master->dev.of_node = node; +	master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; +	master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;  	platform_set_drvdata(pdev, master); @@ -1350,12 +1379,13 @@ static int omap2_mcspi_probe(struct platform_device *pdev)  	INIT_LIST_HEAD(&mcspi->ctx.cs); -	mcspi->dma_channels = kcalloc(master->num_chipselect, -			sizeof(struct omap2_mcspi_dma), -			GFP_KERNEL); - -	if (mcspi->dma_channels == NULL) +	mcspi->dma_channels = devm_kcalloc(&pdev->dev, master->num_chipselect, +					   sizeof(struct omap2_mcspi_dma), +					   GFP_KERNEL); +	if (mcspi->dma_channels == NULL) { +		status = -ENOMEM;  		goto free_master; +	}  	for (i = 0; i < master->num_chipselect; i++) {  		char *dma_rx_ch_name = mcspi->dma_channels[i].dma_rx_ch_name; @@ -1397,7 +1427,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)  	}  	if (status < 0) -		goto dma_chnl_free; +		goto free_master;  	pm_runtime_use_autosuspend(&pdev->dev);  	pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); @@ -1407,7 +1437,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)  	if (status < 0)  		goto disable_pm; -	status = spi_register_master(master); +	status = devm_spi_register_master(&pdev->dev, master);  	if (status < 0)  		goto disable_pm; @@ -1415,8 +1445,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev)  disable_pm:  	pm_runtime_disable(&pdev->dev); -dma_chnl_free: -	kfree(mcspi->dma_channels);  free_master:  	spi_master_put(master);  	return status; @@ -1424,20 +1452,12 @@ free_master:  static int omap2_mcspi_remove(struct platform_device *pdev)  { -	struct spi_master	*master; -	struct omap2_mcspi	*mcspi; -	struct omap2_mcspi_dma	*dma_channels; - -	master = platform_get_drvdata(pdev); -	mcspi = spi_master_get_devdata(master); -	dma_channels = mcspi->dma_channels; +	struct spi_master *master = platform_get_drvdata(pdev); +	struct omap2_mcspi *mcspi = spi_master_get_devdata(master);  	pm_runtime_put_sync(mcspi->dev);  	pm_runtime_disable(&pdev->dev); -	spi_unregister_master(master); -	kfree(dma_channels); -  	return 0;  } @@ -1465,9 +1485,9 @@ static int omap2_mcspi_resume(struct device *dev)  			 * change in account.  			 */  			cs->chconf0 |= OMAP2_MCSPI_CHCONF_FORCE; -			__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); +			writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);  			cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE; -			__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); +			writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);  		}  	}  	pm_runtime_mark_last_busy(mcspi->dev); diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 1d1d321d90c..d018a4aac3a 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -9,7 +9,6 @@   * published by the Free Software Foundation.   */ -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/delay.h>  #include <linux/platform_device.h> @@ -43,8 +42,6 @@  struct orion_spi {  	struct spi_master	*master;  	void __iomem		*base; -	unsigned int		max_speed; -	unsigned int		min_speed;  	struct clk              *clk;  }; @@ -75,23 +72,6 @@ orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)  	writel(val, reg_addr);  } -static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size) -{ -	if (size == 16) { -		orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, -				  ORION_SPI_IF_8_16_BIT_MODE); -	} else if (size == 8) { -		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG, -				  ORION_SPI_IF_8_16_BIT_MODE); -	} else { -		pr_debug("Bad bits per word value %d (only 8 or 16 are " -			 "allowed).\n", size); -		return -EINVAL; -	} - -	return 0; -} -  static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)  {  	u32 tclk_hz; @@ -170,7 +150,14 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  	if (rc)  		return rc; -	return orion_spi_set_transfer_size(orion_spi, bits_per_word); +	if (bits_per_word == 16) +		orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, +				  ORION_SPI_IF_8_16_BIT_MODE); +	else +		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG, +				  ORION_SPI_IF_8_16_BIT_MODE); + +	return 0;  }  static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable) @@ -260,11 +247,9 @@ orion_spi_write_read_16bit(struct spi_device *spi,  static unsigned int  orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)  { -	struct orion_spi *orion_spi;  	unsigned int count;  	int word_len; -	orion_spi = spi_master_get_devdata(spi->master);  	word_len = spi->bits_per_word;  	count = xfer->len; @@ -310,27 +295,6 @@ static int orion_spi_transfer_one_message(struct spi_master *master,  		goto msg_done;  	list_for_each_entry(t, &m->transfers, transfer_list) { -		/* make sure buffer length is even when working in 16 -		 * bit mode*/ -		if ((t->bits_per_word == 16) && (t->len & 1)) { -			dev_err(&spi->dev, -				"message rejected : " -				"odd data length %d while in 16 bit mode\n", -				t->len); -			status = -EIO; -			goto msg_done; -		} - -		if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { -			dev_err(&spi->dev, -				"message rejected : " -				"device min speed (%d Hz) exceeds " -				"required transfer speed (%d Hz)\n", -				orion_spi->min_speed, t->speed_hz); -			status = -EIO; -			goto msg_done; -		} -  		if (par_override || t->speed_hz || t->bits_per_word) {  			par_override = 1;  			status = orion_spi_setup_transfer(spi, t); @@ -375,28 +339,6 @@ static int orion_spi_reset(struct orion_spi *orion_spi)  	return 0;  } -static int orion_spi_setup(struct spi_device *spi) -{ -	struct orion_spi *orion_spi; - -	orion_spi = spi_master_get_devdata(spi->master); - -	if ((spi->max_speed_hz == 0) -			|| (spi->max_speed_hz > orion_spi->max_speed)) -		spi->max_speed_hz = orion_spi->max_speed; - -	if (spi->max_speed_hz < orion_spi->min_speed) { -		dev_err(&spi->dev, "setup: requested speed too low %d Hz\n", -			spi->max_speed_hz); -		return -EINVAL; -	} - -	/* -	 * baudrate & width will be set orion_spi_setup_transfer -	 */ -	return 0; -} -  static int orion_spi_probe(struct platform_device *pdev)  {  	struct spi_master *master; @@ -407,7 +349,7 @@ static int orion_spi_probe(struct platform_device *pdev)  	const u32 *iprop;  	int size; -	master = spi_alloc_master(&pdev->dev, sizeof *spi); +	master = spi_alloc_master(&pdev->dev, sizeof(*spi));  	if (master == NULL) {  		dev_dbg(&pdev->dev, "master allocation failed\n");  		return -ENOMEM; @@ -425,16 +367,16 @@ static int orion_spi_probe(struct platform_device *pdev)  	/* we support only mode 0, and no options */  	master->mode_bits = SPI_CPHA | SPI_CPOL; -	master->setup = orion_spi_setup;  	master->transfer_one_message = orion_spi_transfer_one_message;  	master->num_chipselect = ORION_NUM_CHIPSELECTS; +	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);  	platform_set_drvdata(pdev, master);  	spi = spi_master_get_devdata(master);  	spi->master = master; -	spi->clk = clk_get(&pdev->dev, NULL); +	spi->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(spi->clk)) {  		status = PTR_ERR(spi->clk);  		goto out; @@ -443,8 +385,8 @@ static int orion_spi_probe(struct platform_device *pdev)  	clk_prepare(spi->clk);  	clk_enable(spi->clk);  	tclk_hz = clk_get_rate(spi->clk); -	spi->max_speed = DIV_ROUND_UP(tclk_hz, 4); -	spi->min_speed = DIV_ROUND_UP(tclk_hz, 30); +	master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4); +	master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30);  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	spi->base = devm_ioremap_resource(&pdev->dev, r); @@ -457,7 +399,7 @@ static int orion_spi_probe(struct platform_device *pdev)  		goto out_rel_clk;  	master->dev.of_node = pdev->dev.of_node; -	status = spi_register_master(master); +	status = devm_spi_register_master(&pdev->dev, master);  	if (status < 0)  		goto out_rel_clk; @@ -465,7 +407,6 @@ static int orion_spi_probe(struct platform_device *pdev)  out_rel_clk:  	clk_disable_unprepare(spi->clk); -	clk_put(spi->clk);  out:  	spi_master_put(master);  	return status; @@ -481,9 +422,6 @@ static int orion_spi_remove(struct platform_device *pdev)  	spi = spi_master_get_devdata(master);  	clk_disable_unprepare(spi->clk); -	clk_put(spi->clk); - -	spi_unregister_master(master);  	return 0;  } diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 9c511a954d2..66d2ae21e78 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -459,9 +459,8 @@ static void giveback(struct pl022 *pl022)  	struct spi_transfer *last_transfer;  	pl022->next_msg_cs_active = false; -	last_transfer = list_entry(pl022->cur_msg->transfers.prev, -					struct spi_transfer, -					transfer_list); +	last_transfer = list_last_entry(&pl022->cur_msg->transfers, +					struct spi_transfer, transfer_list);  	/* Delay if requested before any change in chip select */  	if (last_transfer->delay_usecs) @@ -1112,10 +1111,8 @@ static int pl022_dma_probe(struct pl022 *pl022)  	}  	pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); -	if (!pl022->dummypage) { -		dev_dbg(&pl022->adev->dev, "no DMA dummypage!\n"); +	if (!pl022->dummypage)  		goto err_no_dummypage; -	}  	dev_info(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n",  		 dma_chan_name(pl022->dma_rx_channel), @@ -1619,7 +1616,6 @@ static int verify_controller_parameters(struct pl022 *pl022,  		dev_err(&pl022->adev->dev,  			"RX FIFO Trigger Level is configured incorrectly\n");  		return -EINVAL; -		break;  	}  	switch (chip_info->tx_lev_trig) {  	case SSP_TX_1_OR_MORE_EMPTY_LOC: @@ -1645,7 +1641,6 @@ static int verify_controller_parameters(struct pl022 *pl022,  		dev_err(&pl022->adev->dev,  			"TX FIFO Trigger Level is configured incorrectly\n");  		return -EINVAL; -		break;  	}  	if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) {  		if ((chip_info->ctrl_len < SSP_BITS_4) @@ -1812,11 +1807,8 @@ static int pl022_setup(struct spi_device *spi)  	if (chip == NULL) {  		chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); -		if (!chip) { -			dev_err(&spi->dev, -				"cannot allocate controller state\n"); +		if (!chip)  			return -ENOMEM; -		}  		dev_dbg(&spi->dev,  			"allocated memory for controller's runtime state\n");  	} @@ -2053,10 +2045,8 @@ pl022_platform_data_dt_get(struct device *dev)  	}  	pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL); -	if (!pd) { -		dev_err(dev, "cannot allocate platform data memory\n"); +	if (!pd)  		return NULL; -	}  	pd->bus_id = -1;  	pd->enable_dma = 1; @@ -2111,8 +2101,6 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)  	pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),  					  GFP_KERNEL); -	pinctrl_pm_select_default_state(dev); -  	/*  	 * Bus Number Which has been Assigned to this SSP controller  	 * on this board @@ -2175,8 +2163,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)  		status = -ENOMEM;  		goto err_no_ioremap;  	} -	printk(KERN_INFO "pl022: mapped registers from %pa to %p\n", -	       &adev->res.start, pl022->virtbase); +	dev_info(&adev->dev, "mapped registers from %pa to %p\n", +		&adev->res.start, pl022->virtbase);  	pl022->clk = devm_clk_get(&adev->dev, NULL);  	if (IS_ERR(pl022->clk)) { @@ -2185,13 +2173,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)  		goto err_no_clk;  	} -	status = clk_prepare(pl022->clk); -	if (status) { -		dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n"); -		goto  err_clk_prep; -	} - -	status = clk_enable(pl022->clk); +	status = clk_prepare_enable(pl022->clk);  	if (status) {  		dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");  		goto err_no_clk_en; @@ -2227,7 +2209,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)  	/* Register with the SPI framework */  	amba_set_drvdata(adev, pl022); -	status = spi_register_master(master); +	status = devm_spi_register_master(&adev->dev, master);  	if (status != 0) {  		dev_err(&adev->dev,  			"probe - problem registering spi master\n"); @@ -2252,10 +2234,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)  	if (platform_info->enable_dma)  		pl022_dma_remove(pl022);   err_no_irq: -	clk_disable(pl022->clk); +	clk_disable_unprepare(pl022->clk);   err_no_clk_en: -	clk_unprepare(pl022->clk); - err_clk_prep:   err_no_clk:   err_no_ioremap:  	amba_release_regions(adev); @@ -2283,44 +2263,13 @@ pl022_remove(struct amba_device *adev)  	if (pl022->master_info->enable_dma)  		pl022_dma_remove(pl022); -	clk_disable(pl022->clk); -	clk_unprepare(pl022->clk); +	clk_disable_unprepare(pl022->clk);  	amba_release_regions(adev);  	tasklet_disable(&pl022->pump_transfers); -	spi_unregister_master(pl022->master); -	amba_set_drvdata(adev, NULL);  	return 0;  } -#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME) -/* - * These two functions are used from both suspend/resume and - * the runtime counterparts to handle external resources like - * clocks, pins and regulators when going to sleep. - */ -static void pl022_suspend_resources(struct pl022 *pl022, bool runtime) -{ -	clk_disable(pl022->clk); - -	if (runtime) -		pinctrl_pm_select_idle_state(&pl022->adev->dev); -	else -		pinctrl_pm_select_sleep_state(&pl022->adev->dev); -} - -static void pl022_resume_resources(struct pl022 *pl022, bool runtime) -{ -	/* First go to the default state */ -	pinctrl_pm_select_default_state(&pl022->adev->dev); -	if (!runtime) -		/* Then let's idle the pins until the next transfer happens */ -		pinctrl_pm_select_idle_state(&pl022->adev->dev); - -	clk_enable(pl022->clk); -} -#endif - -#ifdef CONFIG_SUSPEND +#ifdef CONFIG_PM_SLEEP  static int pl022_suspend(struct device *dev)  {  	struct pl022 *pl022 = dev_get_drvdata(dev); @@ -2332,8 +2281,13 @@ static int pl022_suspend(struct device *dev)  		return ret;  	} -	pm_runtime_get_sync(dev); -	pl022_suspend_resources(pl022, false); +	ret = pm_runtime_force_suspend(dev); +	if (ret) { +		spi_master_resume(pl022->master); +		return ret; +	} + +	pinctrl_pm_select_sleep_state(dev);  	dev_dbg(dev, "suspended\n");  	return 0; @@ -2344,8 +2298,9 @@ static int pl022_resume(struct device *dev)  	struct pl022 *pl022 = dev_get_drvdata(dev);  	int ret; -	pl022_resume_resources(pl022, false); -	pm_runtime_put(dev); +	ret = pm_runtime_force_resume(dev); +	if (ret) +		dev_err(dev, "problem resuming\n");  	/* Start the queue running */  	ret = spi_master_resume(pl022->master); @@ -2356,14 +2311,16 @@ static int pl022_resume(struct device *dev)  	return ret;  } -#endif	/* CONFIG_PM */ +#endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM  static int pl022_runtime_suspend(struct device *dev)  {  	struct pl022 *pl022 = dev_get_drvdata(dev); -	pl022_suspend_resources(pl022, true); +	clk_disable_unprepare(pl022->clk); +	pinctrl_pm_select_idle_state(dev); +  	return 0;  } @@ -2371,14 +2328,16 @@ static int pl022_runtime_resume(struct device *dev)  {  	struct pl022 *pl022 = dev_get_drvdata(dev); -	pl022_resume_resources(pl022, true); +	pinctrl_pm_select_default_state(dev); +	clk_prepare_enable(pl022->clk); +  	return 0;  }  #endif  static const struct dev_pm_ops pl022_dev_pm_ops = {  	SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) -	SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL) +	SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)  };  static struct vendor_data vendor_arm = { diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 0ee53c25ba5..80b8408ac3e 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -24,11 +24,12 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/sched.h>  #include <linux/slab.h>  #include <linux/errno.h>  #include <linux/wait.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/of_gpio.h>  #include <linux/interrupt.h> @@ -396,7 +397,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)  	master->dev.of_node = np;  	platform_set_drvdata(op, master);  	hw = spi_master_get_devdata(master); -	hw->master = spi_master_get(master); +	hw->master = master;  	hw->dev = dev;  	init_completion(&hw->done); @@ -558,6 +559,7 @@ static int spi_ppc4xx_of_remove(struct platform_device *op)  	free_irq(hw->irqnum, hw);  	iounmap(hw->regs);  	free_gpios(hw); +	spi_master_put(master);  	return 0;  } diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index 3c0b55125f1..c41ff148a2b 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -9,7 +9,6 @@   * published by the Free Software Foundation.   */ -#include <linux/init.h>  #include <linux/device.h>  #include <linux/dma-mapping.h>  #include <linux/dmaengine.h> @@ -30,18 +29,6 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data,  	struct sg_table *sgt;  	void *buf, *pbuf; -	/* -	 * Some DMA controllers have problems transferring buffers that are -	 * not multiple of 4 bytes. So we truncate the transfer so that it -	 * is suitable for such controllers, and handle the trailing bytes -	 * manually after the DMA completes. -	 * -	 * REVISIT: It would be better if this information could be -	 * retrieved directly from the DMA device in a similar way than -	 * ->copy_align etc. is done. -	 */ -	len = ALIGN(drv_data->len, 4); -  	if (dir == DMA_TO_DEVICE) {  		dmadev = drv_data->tx_chan->device->dev;  		sgt = &drv_data->tx_sgt; @@ -145,12 +132,8 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,  		if (!error) {  			pxa2xx_spi_unmap_dma_buffers(drv_data); -			/* Handle the last bytes of unaligned transfer */  			drv_data->tx += drv_data->tx_map_len; -			drv_data->write(drv_data); -  			drv_data->rx += drv_data->rx_map_len; -			drv_data->read(drv_data);  			msg->actual_length += drv_data->len;  			msg->state = pxa2xx_spi_next_transfer(drv_data); @@ -385,7 +368,7 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,  	 * otherwise we use the default. Also we use the default FIFO  	 * thresholds for now.  	 */ -	*burst_code = chip_info ? chip_info->dma_burst_size : 16; +	*burst_code = chip_info ? chip_info->dma_burst_size : 1;  	*threshold = SSCR1_RxTresh(RX_THRESH_DFLT)  		   | SSCR1_TxTresh(TX_THRESH_DFLT); diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 74bc1877565..c1865c92ccb 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -8,7 +8,43 @@  #include <linux/module.h>  #include <linux/spi/pxa2xx_spi.h> -static int ce4100_spi_probe(struct pci_dev *dev, +enum { +	PORT_CE4100, +	PORT_BYT, +}; + +struct pxa_spi_info { +	enum pxa_ssp_type type; +	int port_id; +	int num_chipselect; +	int tx_slave_id; +	int tx_chan_id; +	int rx_slave_id; +	int rx_chan_id; +}; + +static struct pxa_spi_info spi_info_configs[] = { +	[PORT_CE4100] = { +		.type = PXA25x_SSP, +		.port_id =  -1, +		.num_chipselect = -1, +		.tx_slave_id = -1, +		.tx_chan_id = -1, +		.rx_slave_id = -1, +		.rx_chan_id = -1, +	}, +	[PORT_BYT] = { +		.type = LPSS_SSP, +		.port_id = 0, +		.num_chipselect = 1, +		.tx_slave_id = 0, +		.tx_chan_id = 0, +		.rx_slave_id = 1, +		.rx_chan_id = 1, +	}, +}; + +static int pxa2xx_spi_pci_probe(struct pci_dev *dev,  		const struct pci_device_id *ent)  {  	struct platform_device_info pi; @@ -16,6 +52,7 @@ static int ce4100_spi_probe(struct pci_dev *dev,  	struct platform_device *pdev;  	struct pxa2xx_spi_master spi_pdata;  	struct ssp_device *ssp; +	struct pxa_spi_info *c;  	ret = pcim_enable_device(dev);  	if (ret) @@ -25,8 +62,16 @@ static int ce4100_spi_probe(struct pci_dev *dev,  	if (ret)  		return ret; +	c = &spi_info_configs[ent->driver_data]; +  	memset(&spi_pdata, 0, sizeof(spi_pdata)); -	spi_pdata.num_chipselect = dev->devfn; +	spi_pdata.num_chipselect = (c->num_chipselect > 0) ? +					c->num_chipselect : dev->devfn; +	spi_pdata.tx_slave_id = c->tx_slave_id; +	spi_pdata.tx_chan_id = c->tx_chan_id; +	spi_pdata.rx_slave_id = c->rx_slave_id; +	spi_pdata.rx_chan_id = c->rx_chan_id; +	spi_pdata.enable_dma = c->rx_slave_id >= 0 && c->tx_slave_id >= 0;  	ssp = &spi_pdata.ssp;  	ssp->phys_base = pci_resource_start(dev, 0); @@ -36,8 +81,8 @@ static int ce4100_spi_probe(struct pci_dev *dev,  		return -EIO;  	}  	ssp->irq = dev->irq; -	ssp->port_id = dev->devfn; -	ssp->type = PXA25x_SSP; +	ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; +	ssp->type = c->type;  	memset(&pi, 0, sizeof(pi));  	pi.parent = &dev->dev; @@ -55,28 +100,29 @@ static int ce4100_spi_probe(struct pci_dev *dev,  	return 0;  } -static void ce4100_spi_remove(struct pci_dev *dev) +static void pxa2xx_spi_pci_remove(struct pci_dev *dev)  {  	struct platform_device *pdev = pci_get_drvdata(dev);  	platform_device_unregister(pdev);  } -static DEFINE_PCI_DEVICE_TABLE(ce4100_spi_devices) = { -	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, +static const struct pci_device_id pxa2xx_spi_pci_devices[] = { +	{ PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, +	{ PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },  	{ },  }; -MODULE_DEVICE_TABLE(pci, ce4100_spi_devices); +MODULE_DEVICE_TABLE(pci, pxa2xx_spi_pci_devices); -static struct pci_driver ce4100_spi_driver = { -	.name           = "ce4100_spi", -	.id_table       = ce4100_spi_devices, -	.probe          = ce4100_spi_probe, -	.remove         = ce4100_spi_remove, +static struct pci_driver pxa2xx_spi_pci_driver = { +	.name           = "pxa2xx_spi_pci", +	.id_table       = pxa2xx_spi_pci_devices, +	.probe          = pxa2xx_spi_pci_probe, +	.remove         = pxa2xx_spi_pci_remove,  }; -module_pci_driver(ce4100_spi_driver); +module_pci_driver(pxa2xx_spi_pci_driver); -MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver"); +MODULE_DESCRIPTION("CE4100/LPSS PCI-SPI glue code for PXA's driver");  MODULE_LICENSE("GPL v2");  MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); diff --git a/drivers/spi/spi-pxa2xx-pxadma.c b/drivers/spi/spi-pxa2xx-pxadma.c index 2916efc7cfe..e8a26f25d5c 100644 --- a/drivers/spi/spi-pxa2xx-pxadma.c +++ b/drivers/spi/spi-pxa2xx-pxadma.c @@ -18,7 +18,6 @@   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ -#include <linux/init.h>  #include <linux/delay.h>  #include <linux/device.h>  #include <linux/dma-mapping.h> diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 2eb06ee0b32..fe792106bdc 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -27,7 +27,6 @@  #include <linux/platform_device.h>  #include <linux/spi/pxa2xx_spi.h>  #include <linux/spi/spi.h> -#include <linux/workqueue.h>  #include <linux/delay.h>  #include <linux/gpio.h>  #include <linux/slab.h> @@ -119,6 +118,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data)  	 */  	orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); +	/* Test SPI_CS_CONTROL_SW_MODE bit enabling */  	value = orig | SPI_CS_CONTROL_SW_MODE;  	writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);  	value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); @@ -127,10 +127,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data)  		goto detection_done;  	} -	value &= ~SPI_CS_CONTROL_SW_MODE; +	orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); + +	/* Test SPI_CS_CONTROL_SW_MODE bit disabling */ +	value = orig & ~SPI_CS_CONTROL_SW_MODE;  	writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);  	value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); -	if (value != orig) { +	if (value != (orig & ~SPI_CS_CONTROL_SW_MODE)) {  		offset = 0x800;  		goto detection_done;  	} @@ -362,8 +365,7 @@ static void giveback(struct driver_data *drv_data)  	drv_data->cur_msg = NULL;  	drv_data->cur_transfer = NULL; -	last_transfer = list_entry(msg->transfers.prev, -					struct spi_transfer, +	last_transfer = list_last_entry(&msg->transfers, struct spi_transfer,  					transfer_list);  	/* Delay if requested before any change in chip select */ @@ -546,8 +548,17 @@ static irqreturn_t ssp_int(int irq, void *dev_id)  	if (pm_runtime_suspended(&drv_data->pdev->dev))  		return IRQ_NONE; -	sccr1_reg = read_SSCR1(reg); +	/* +	 * If the device is not yet in RPM suspended state and we get an +	 * interrupt that is meant for another device, check if status bits +	 * are all set to one. That means that the device is already +	 * powered off. +	 */  	status = read_SSSR(reg); +	if (status == ~0) +		return IRQ_NONE; + +	sccr1_reg = read_SSCR1(reg);  	/* Ignore possible writes if we don't need to write */  	if (!(sccr1_reg & SSCR1_TIE)) @@ -564,8 +575,8 @@ static irqreturn_t ssp_int(int irq, void *dev_id)  			write_SSTO(0, reg);  		write_SSSR_CS(drv_data, drv_data->clear_sr); -		dev_err(&drv_data->pdev->dev, "bad message state " -			"in interrupt handler\n"); +		dev_err(&drv_data->pdev->dev, +			"bad message state in interrupt handler\n");  		/* Never fail */  		return IRQ_HANDLED; @@ -642,8 +653,8 @@ static void pump_transfers(unsigned long data)  		if (message->is_dma_mapped  				|| transfer->rx_dma || transfer->tx_dma) {  			dev_err(&drv_data->pdev->dev, -				"pump_transfers: mapped transfer length " -				"of %u is greater than %d\n", +				"pump_transfers: mapped transfer length of " +				"%u is greater than %d\n",  				transfer->len, MAX_DMA_LEN);  			message->status = -EINVAL;  			giveback(drv_data); @@ -651,11 +662,10 @@ static void pump_transfers(unsigned long data)  		}  		/* warn ... we force this to PIO mode */ -		if (printk_ratelimit()) -			dev_warn(&message->spi->dev, "pump_transfers: " -				"DMA disabled for transfer length %ld " -				"greater than %d\n", -				(long)drv_data->len, MAX_DMA_LEN); +		dev_warn_ratelimited(&message->spi->dev, +				     "pump_transfers: DMA disabled for transfer length %ld " +				     "greater than %d\n", +				     (long)drv_data->len, MAX_DMA_LEN);  	}  	/* Setup the transfer state based on the type of transfer */ @@ -717,11 +727,8 @@ static void pump_transfers(unsigned long data)  							message->spi,  							bits, &dma_burst,  							&dma_thresh)) -				if (printk_ratelimit()) -					dev_warn(&message->spi->dev, -						"pump_transfers: " -						"DMA burst size reduced to " -						"match bits_per_word\n"); +				dev_warn_ratelimited(&message->spi->dev, +						     "pump_transfers: DMA burst size reduced to match bits_per_word\n");  		}  		cr0 = clk_div @@ -845,8 +852,8 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip,  	if (gpio_is_valid(chip_info->gpio_cs)) {  		err = gpio_request(chip_info->gpio_cs, "SPI_CS");  		if (err) { -			dev_err(&spi->dev, "failed to request chip select " -					"GPIO%d\n", chip_info->gpio_cs); +			dev_err(&spi->dev, "failed to request chip select GPIO%d\n", +				chip_info->gpio_cs);  			return err;  		} @@ -882,16 +889,13 @@ static int setup(struct spi_device *spi)  	chip = spi_get_ctldata(spi);  	if (!chip) {  		chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); -		if (!chip) { -			dev_err(&spi->dev, -				"failed setup: can't allocate chip data\n"); +		if (!chip)  			return -ENOMEM; -		}  		if (drv_data->ssp_type == CE4100_SSP) {  			if (spi->chip_select > 4) { -				dev_err(&spi->dev, "failed setup: " -				"cs number must not be > 4.\n"); +				dev_err(&spi->dev, +					"failed setup: cs number must not be > 4.\n");  				kfree(chip);  				return -EINVAL;  			} @@ -947,8 +951,8 @@ static int setup(struct spi_device *spi)  						spi->bits_per_word,  						&chip->dma_burst_size,  						&chip->dma_threshold)) { -			dev_warn(&spi->dev, "in setup: DMA burst size reduced " -					"to match bits_per_word\n"); +			dev_warn(&spi->dev, +				 "in setup: DMA burst size reduced to match bits_per_word\n");  		}  	} @@ -1033,11 +1037,8 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)  		return NULL;  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); -	if (!pdata) { -		dev_err(&pdev->dev, -			"failed to allocate memory for platform data\n"); +	if (!pdata)  		return NULL; -	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!res) @@ -1061,6 +1062,8 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)  	pdata->num_chipselect = 1;  	pdata->enable_dma = true; +	pdata->tx_chan_id = -1; +	pdata->rx_chan_id = -1;  	return pdata;  } @@ -1068,6 +1071,8 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)  static struct acpi_device_id pxa2xx_spi_acpi_match[] = {  	{ "INT33C0", 0 },  	{ "INT33C1", 0 }, +	{ "INT3430", 0 }, +	{ "INT3431", 0 },  	{ "80860F0E", 0 },  	{ },  }; @@ -1194,19 +1199,19 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)  	tasklet_init(&drv_data->pump_transfers, pump_transfers,  		     (unsigned long)drv_data); +	pm_runtime_set_autosuspend_delay(&pdev->dev, 50); +	pm_runtime_use_autosuspend(&pdev->dev); +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_enable(&pdev->dev); +  	/* Register with the SPI framework */  	platform_set_drvdata(pdev, drv_data); -	status = spi_register_master(master); +	status = devm_spi_register_master(&pdev->dev, master);  	if (status != 0) {  		dev_err(&pdev->dev, "problem registering spi master\n");  		goto out_error_clock_enabled;  	} -	pm_runtime_set_autosuspend_delay(&pdev->dev, 50); -	pm_runtime_use_autosuspend(&pdev->dev); -	pm_runtime_set_active(&pdev->dev); -	pm_runtime_enable(&pdev->dev); -  	return status;  out_error_clock_enabled: @@ -1248,9 +1253,6 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)  	/* Release SSP */  	pxa_ssp_free(ssp); -	/* Disconnect from the SPI framework */ -	spi_unregister_master(drv_data->master); -  	return 0;  } @@ -1262,7 +1264,7 @@ static void pxa2xx_spi_shutdown(struct platform_device *pdev)  		dev_err(&pdev->dev, "shutdown failed with %d\n", status);  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int pxa2xx_spi_suspend(struct device *dev)  {  	struct driver_data *drv_data = dev_get_drvdata(dev); @@ -1289,6 +1291,9 @@ static int pxa2xx_spi_resume(struct device *dev)  	/* Enable the SSP clock */  	clk_prepare_enable(ssp->clk); +	/* Restore LPSS private register bits */ +	lpss_ssp_setup(drv_data); +  	/* Start the queue running */  	status = spi_master_resume(drv_data->master);  	if (status != 0) { diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c new file mode 100644 index 00000000000..c08da380cb2 --- /dev/null +++ b/drivers/spi/spi-qup.c @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2008-2014, The Linux foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License rev 2 and + * only rev 2 as published by the free Software foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/spi/spi.h> + +#define QUP_CONFIG			0x0000 +#define QUP_STATE			0x0004 +#define QUP_IO_M_MODES			0x0008 +#define QUP_SW_RESET			0x000c +#define QUP_OPERATIONAL			0x0018 +#define QUP_ERROR_FLAGS			0x001c +#define QUP_ERROR_FLAGS_EN		0x0020 +#define QUP_OPERATIONAL_MASK		0x0028 +#define QUP_HW_VERSION			0x0030 +#define QUP_MX_OUTPUT_CNT		0x0100 +#define QUP_OUTPUT_FIFO			0x0110 +#define QUP_MX_WRITE_CNT		0x0150 +#define QUP_MX_INPUT_CNT		0x0200 +#define QUP_MX_READ_CNT			0x0208 +#define QUP_INPUT_FIFO			0x0218 + +#define SPI_CONFIG			0x0300 +#define SPI_IO_CONTROL			0x0304 +#define SPI_ERROR_FLAGS			0x0308 +#define SPI_ERROR_FLAGS_EN		0x030c + +/* QUP_CONFIG fields */ +#define QUP_CONFIG_SPI_MODE		(1 << 8) +#define QUP_CONFIG_CLOCK_AUTO_GATE	BIT(13) +#define QUP_CONFIG_NO_INPUT		BIT(7) +#define QUP_CONFIG_NO_OUTPUT		BIT(6) +#define QUP_CONFIG_N			0x001f + +/* QUP_STATE fields */ +#define QUP_STATE_VALID			BIT(2) +#define QUP_STATE_RESET			0 +#define QUP_STATE_RUN			1 +#define QUP_STATE_PAUSE			3 +#define QUP_STATE_MASK			3 +#define QUP_STATE_CLEAR			2 + +#define QUP_HW_VERSION_2_1_1		0x20010001 + +/* QUP_IO_M_MODES fields */ +#define QUP_IO_M_PACK_EN		BIT(15) +#define QUP_IO_M_UNPACK_EN		BIT(14) +#define QUP_IO_M_INPUT_MODE_MASK_SHIFT	12 +#define QUP_IO_M_OUTPUT_MODE_MASK_SHIFT	10 +#define QUP_IO_M_INPUT_MODE_MASK	(3 << QUP_IO_M_INPUT_MODE_MASK_SHIFT) +#define QUP_IO_M_OUTPUT_MODE_MASK	(3 << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT) + +#define QUP_IO_M_OUTPUT_BLOCK_SIZE(x)	(((x) & (0x03 << 0)) >> 0) +#define QUP_IO_M_OUTPUT_FIFO_SIZE(x)	(((x) & (0x07 << 2)) >> 2) +#define QUP_IO_M_INPUT_BLOCK_SIZE(x)	(((x) & (0x03 << 5)) >> 5) +#define QUP_IO_M_INPUT_FIFO_SIZE(x)	(((x) & (0x07 << 7)) >> 7) + +#define QUP_IO_M_MODE_FIFO		0 +#define QUP_IO_M_MODE_BLOCK		1 +#define QUP_IO_M_MODE_DMOV		2 +#define QUP_IO_M_MODE_BAM		3 + +/* QUP_OPERATIONAL fields */ +#define QUP_OP_MAX_INPUT_DONE_FLAG	BIT(11) +#define QUP_OP_MAX_OUTPUT_DONE_FLAG	BIT(10) +#define QUP_OP_IN_SERVICE_FLAG		BIT(9) +#define QUP_OP_OUT_SERVICE_FLAG		BIT(8) +#define QUP_OP_IN_FIFO_FULL		BIT(7) +#define QUP_OP_OUT_FIFO_FULL		BIT(6) +#define QUP_OP_IN_FIFO_NOT_EMPTY	BIT(5) +#define QUP_OP_OUT_FIFO_NOT_EMPTY	BIT(4) + +/* QUP_ERROR_FLAGS and QUP_ERROR_FLAGS_EN fields */ +#define QUP_ERROR_OUTPUT_OVER_RUN	BIT(5) +#define QUP_ERROR_INPUT_UNDER_RUN	BIT(4) +#define QUP_ERROR_OUTPUT_UNDER_RUN	BIT(3) +#define QUP_ERROR_INPUT_OVER_RUN	BIT(2) + +/* SPI_CONFIG fields */ +#define SPI_CONFIG_HS_MODE		BIT(10) +#define SPI_CONFIG_INPUT_FIRST		BIT(9) +#define SPI_CONFIG_LOOPBACK		BIT(8) + +/* SPI_IO_CONTROL fields */ +#define SPI_IO_C_FORCE_CS		BIT(11) +#define SPI_IO_C_CLK_IDLE_HIGH		BIT(10) +#define SPI_IO_C_MX_CS_MODE		BIT(8) +#define SPI_IO_C_CS_N_POLARITY_0	BIT(4) +#define SPI_IO_C_CS_SELECT(x)		(((x) & 3) << 2) +#define SPI_IO_C_CS_SELECT_MASK		0x000c +#define SPI_IO_C_TRISTATE_CS		BIT(1) +#define SPI_IO_C_NO_TRI_STATE		BIT(0) + +/* SPI_ERROR_FLAGS and SPI_ERROR_FLAGS_EN fields */ +#define SPI_ERROR_CLK_OVER_RUN		BIT(1) +#define SPI_ERROR_CLK_UNDER_RUN		BIT(0) + +#define SPI_NUM_CHIPSELECTS		4 + +/* high speed mode is when bus rate is greater then 26MHz */ +#define SPI_HS_MIN_RATE			26000000 +#define SPI_MAX_RATE			50000000 + +#define SPI_DELAY_THRESHOLD		1 +#define SPI_DELAY_RETRY			10 + +struct spi_qup { +	void __iomem		*base; +	struct device		*dev; +	struct clk		*cclk;	/* core clock */ +	struct clk		*iclk;	/* interface clock */ +	int			irq; +	spinlock_t		lock; + +	int			in_fifo_sz; +	int			out_fifo_sz; +	int			in_blk_sz; +	int			out_blk_sz; + +	struct spi_transfer	*xfer; +	struct completion	done; +	int			error; +	int			w_size;	/* bytes per SPI word */ +	int			tx_bytes; +	int			rx_bytes; +}; + + +static inline bool spi_qup_is_valid_state(struct spi_qup *controller) +{ +	u32 opstate = readl_relaxed(controller->base + QUP_STATE); + +	return opstate & QUP_STATE_VALID; +} + +static int spi_qup_set_state(struct spi_qup *controller, u32 state) +{ +	unsigned long loop; +	u32 cur_state; + +	loop = 0; +	while (!spi_qup_is_valid_state(controller)) { + +		usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2); + +		if (++loop > SPI_DELAY_RETRY) +			return -EIO; +	} + +	if (loop) +		dev_dbg(controller->dev, "invalid state for %ld,us %d\n", +			loop, state); + +	cur_state = readl_relaxed(controller->base + QUP_STATE); +	/* +	 * Per spec: for PAUSE_STATE to RESET_STATE, two writes +	 * of (b10) are required +	 */ +	if (((cur_state & QUP_STATE_MASK) == QUP_STATE_PAUSE) && +	    (state == QUP_STATE_RESET)) { +		writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE); +		writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE); +	} else { +		cur_state &= ~QUP_STATE_MASK; +		cur_state |= state; +		writel_relaxed(cur_state, controller->base + QUP_STATE); +	} + +	loop = 0; +	while (!spi_qup_is_valid_state(controller)) { + +		usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2); + +		if (++loop > SPI_DELAY_RETRY) +			return -EIO; +	} + +	return 0; +} + + +static void spi_qup_fifo_read(struct spi_qup *controller, +			    struct spi_transfer *xfer) +{ +	u8 *rx_buf = xfer->rx_buf; +	u32 word, state; +	int idx, shift, w_size; + +	w_size = controller->w_size; + +	while (controller->rx_bytes < xfer->len) { + +		state = readl_relaxed(controller->base + QUP_OPERATIONAL); +		if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY)) +			break; + +		word = readl_relaxed(controller->base + QUP_INPUT_FIFO); + +		if (!rx_buf) { +			controller->rx_bytes += w_size; +			continue; +		} + +		for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) { +			/* +			 * The data format depends on bytes per SPI word: +			 *  4 bytes: 0x12345678 +			 *  2 bytes: 0x00001234 +			 *  1 byte : 0x00000012 +			 */ +			shift = BITS_PER_BYTE; +			shift *= (w_size - idx - 1); +			rx_buf[controller->rx_bytes] = word >> shift; +		} +	} +} + +static void spi_qup_fifo_write(struct spi_qup *controller, +			    struct spi_transfer *xfer) +{ +	const u8 *tx_buf = xfer->tx_buf; +	u32 word, state, data; +	int idx, w_size; + +	w_size = controller->w_size; + +	while (controller->tx_bytes < xfer->len) { + +		state = readl_relaxed(controller->base + QUP_OPERATIONAL); +		if (state & QUP_OP_OUT_FIFO_FULL) +			break; + +		word = 0; +		for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) { + +			if (!tx_buf) { +				controller->tx_bytes += w_size; +				break; +			} + +			data = tx_buf[controller->tx_bytes]; +			word |= data << (BITS_PER_BYTE * (3 - idx)); +		} + +		writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO); +	} +} + +static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) +{ +	struct spi_qup *controller = dev_id; +	struct spi_transfer *xfer; +	u32 opflags, qup_err, spi_err; +	unsigned long flags; +	int error = 0; + +	spin_lock_irqsave(&controller->lock, flags); +	xfer = controller->xfer; +	controller->xfer = NULL; +	spin_unlock_irqrestore(&controller->lock, flags); + +	qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS); +	spi_err = readl_relaxed(controller->base + SPI_ERROR_FLAGS); +	opflags = readl_relaxed(controller->base + QUP_OPERATIONAL); + +	writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS); +	writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS); +	writel_relaxed(opflags, controller->base + QUP_OPERATIONAL); + +	if (!xfer) { +		dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n", +				    qup_err, spi_err, opflags); +		return IRQ_HANDLED; +	} + +	if (qup_err) { +		if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN) +			dev_warn(controller->dev, "OUTPUT_OVER_RUN\n"); +		if (qup_err & QUP_ERROR_INPUT_UNDER_RUN) +			dev_warn(controller->dev, "INPUT_UNDER_RUN\n"); +		if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN) +			dev_warn(controller->dev, "OUTPUT_UNDER_RUN\n"); +		if (qup_err & QUP_ERROR_INPUT_OVER_RUN) +			dev_warn(controller->dev, "INPUT_OVER_RUN\n"); + +		error = -EIO; +	} + +	if (spi_err) { +		if (spi_err & SPI_ERROR_CLK_OVER_RUN) +			dev_warn(controller->dev, "CLK_OVER_RUN\n"); +		if (spi_err & SPI_ERROR_CLK_UNDER_RUN) +			dev_warn(controller->dev, "CLK_UNDER_RUN\n"); + +		error = -EIO; +	} + +	if (opflags & QUP_OP_IN_SERVICE_FLAG) +		spi_qup_fifo_read(controller, xfer); + +	if (opflags & QUP_OP_OUT_SERVICE_FLAG) +		spi_qup_fifo_write(controller, xfer); + +	spin_lock_irqsave(&controller->lock, flags); +	controller->error = error; +	controller->xfer = xfer; +	spin_unlock_irqrestore(&controller->lock, flags); + +	if (controller->rx_bytes == xfer->len || error) +		complete(&controller->done); + +	return IRQ_HANDLED; +} + + +/* set clock freq ... bits per word */ +static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) +{ +	struct spi_qup *controller = spi_master_get_devdata(spi->master); +	u32 config, iomode, mode; +	int ret, n_words, w_size; + +	if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) { +		dev_err(controller->dev, "too big size for loopback %d > %d\n", +			xfer->len, controller->in_fifo_sz); +		return -EIO; +	} + +	ret = clk_set_rate(controller->cclk, xfer->speed_hz); +	if (ret) { +		dev_err(controller->dev, "fail to set frequency %d", +			xfer->speed_hz); +		return -EIO; +	} + +	if (spi_qup_set_state(controller, QUP_STATE_RESET)) { +		dev_err(controller->dev, "cannot set RESET state\n"); +		return -EIO; +	} + +	w_size = 4; +	if (xfer->bits_per_word <= 8) +		w_size = 1; +	else if (xfer->bits_per_word <= 16) +		w_size = 2; + +	n_words = xfer->len / w_size; +	controller->w_size = w_size; + +	if (n_words <= (controller->in_fifo_sz / sizeof(u32))) { +		mode = QUP_IO_M_MODE_FIFO; +		writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT); +		writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT); +		/* must be zero for FIFO */ +		writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT); +		writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); +	} else { +		mode = QUP_IO_M_MODE_BLOCK; +		writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); +		writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); +		/* must be zero for BLOCK and BAM */ +		writel_relaxed(0, controller->base + QUP_MX_READ_CNT); +		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); +	} + +	iomode = readl_relaxed(controller->base + QUP_IO_M_MODES); +	/* Set input and output transfer mode */ +	iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK); +	iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN); +	iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT); +	iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT); + +	writel_relaxed(iomode, controller->base + QUP_IO_M_MODES); + +	config = readl_relaxed(controller->base + SPI_CONFIG); + +	if (spi->mode & SPI_LOOP) +		config |= SPI_CONFIG_LOOPBACK; +	else +		config &= ~SPI_CONFIG_LOOPBACK; + +	if (spi->mode & SPI_CPHA) +		config &= ~SPI_CONFIG_INPUT_FIRST; +	else +		config |= SPI_CONFIG_INPUT_FIRST; + +	/* +	 * HS_MODE improves signal stability for spi-clk high rates, +	 * but is invalid in loop back mode. +	 */ +	if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(spi->mode & SPI_LOOP)) +		config |= SPI_CONFIG_HS_MODE; +	else +		config &= ~SPI_CONFIG_HS_MODE; + +	writel_relaxed(config, controller->base + SPI_CONFIG); + +	config = readl_relaxed(controller->base + QUP_CONFIG); +	config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N); +	config |= xfer->bits_per_word - 1; +	config |= QUP_CONFIG_SPI_MODE; +	writel_relaxed(config, controller->base + QUP_CONFIG); + +	writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); +	return 0; +} + +static int spi_qup_transfer_one(struct spi_master *master, +			      struct spi_device *spi, +			      struct spi_transfer *xfer) +{ +	struct spi_qup *controller = spi_master_get_devdata(master); +	unsigned long timeout, flags; +	int ret = -EIO; + +	ret = spi_qup_io_config(spi, xfer); +	if (ret) +		return ret; + +	timeout = DIV_ROUND_UP(xfer->speed_hz, MSEC_PER_SEC); +	timeout = DIV_ROUND_UP(xfer->len * 8, timeout); +	timeout = 100 * msecs_to_jiffies(timeout); + +	reinit_completion(&controller->done); + +	spin_lock_irqsave(&controller->lock, flags); +	controller->xfer     = xfer; +	controller->error    = 0; +	controller->rx_bytes = 0; +	controller->tx_bytes = 0; +	spin_unlock_irqrestore(&controller->lock, flags); + +	if (spi_qup_set_state(controller, QUP_STATE_RUN)) { +		dev_warn(controller->dev, "cannot set RUN state\n"); +		goto exit; +	} + +	if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) { +		dev_warn(controller->dev, "cannot set PAUSE state\n"); +		goto exit; +	} + +	spi_qup_fifo_write(controller, xfer); + +	if (spi_qup_set_state(controller, QUP_STATE_RUN)) { +		dev_warn(controller->dev, "cannot set EXECUTE state\n"); +		goto exit; +	} + +	if (!wait_for_completion_timeout(&controller->done, timeout)) +		ret = -ETIMEDOUT; +exit: +	spi_qup_set_state(controller, QUP_STATE_RESET); +	spin_lock_irqsave(&controller->lock, flags); +	controller->xfer = NULL; +	if (!ret) +		ret = controller->error; +	spin_unlock_irqrestore(&controller->lock, flags); +	return ret; +} + +static int spi_qup_probe(struct platform_device *pdev) +{ +	struct spi_master *master; +	struct clk *iclk, *cclk; +	struct spi_qup *controller; +	struct resource *res; +	struct device *dev; +	void __iomem *base; +	u32 data, max_freq, iomode; +	int ret, irq, size; + +	dev = &pdev->dev; +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	base = devm_ioremap_resource(dev, res); +	if (IS_ERR(base)) +		return PTR_ERR(base); + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) +		return irq; + +	cclk = devm_clk_get(dev, "core"); +	if (IS_ERR(cclk)) +		return PTR_ERR(cclk); + +	iclk = devm_clk_get(dev, "iface"); +	if (IS_ERR(iclk)) +		return PTR_ERR(iclk); + +	/* This is optional parameter */ +	if (of_property_read_u32(dev->of_node, "spi-max-frequency", &max_freq)) +		max_freq = SPI_MAX_RATE; + +	if (!max_freq || max_freq > SPI_MAX_RATE) { +		dev_err(dev, "invalid clock frequency %d\n", max_freq); +		return -ENXIO; +	} + +	ret = clk_prepare_enable(cclk); +	if (ret) { +		dev_err(dev, "cannot enable core clock\n"); +		return ret; +	} + +	ret = clk_prepare_enable(iclk); +	if (ret) { +		clk_disable_unprepare(cclk); +		dev_err(dev, "cannot enable iface clock\n"); +		return ret; +	} + +	data = readl_relaxed(base + QUP_HW_VERSION); + +	if (data < QUP_HW_VERSION_2_1_1) { +		clk_disable_unprepare(cclk); +		clk_disable_unprepare(iclk); +		dev_err(dev, "v.%08x is not supported\n", data); +		return -ENXIO; +	} + +	master = spi_alloc_master(dev, sizeof(struct spi_qup)); +	if (!master) { +		clk_disable_unprepare(cclk); +		clk_disable_unprepare(iclk); +		dev_err(dev, "cannot allocate master\n"); +		return -ENOMEM; +	} + +	/* use num-cs unless not present or out of range */ +	if (of_property_read_u16(dev->of_node, "num-cs", +			&master->num_chipselect) || +			(master->num_chipselect > SPI_NUM_CHIPSELECTS)) +		master->num_chipselect = SPI_NUM_CHIPSELECTS; + +	master->bus_num = pdev->id; +	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; +	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); +	master->max_speed_hz = max_freq; +	master->transfer_one = spi_qup_transfer_one; +	master->dev.of_node = pdev->dev.of_node; +	master->auto_runtime_pm = true; + +	platform_set_drvdata(pdev, master); + +	controller = spi_master_get_devdata(master); + +	controller->dev = dev; +	controller->base = base; +	controller->iclk = iclk; +	controller->cclk = cclk; +	controller->irq = irq; + +	spin_lock_init(&controller->lock); +	init_completion(&controller->done); + +	iomode = readl_relaxed(base + QUP_IO_M_MODES); + +	size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode); +	if (size) +		controller->out_blk_sz = size * 16; +	else +		controller->out_blk_sz = 4; + +	size = QUP_IO_M_INPUT_BLOCK_SIZE(iomode); +	if (size) +		controller->in_blk_sz = size * 16; +	else +		controller->in_blk_sz = 4; + +	size = QUP_IO_M_OUTPUT_FIFO_SIZE(iomode); +	controller->out_fifo_sz = controller->out_blk_sz * (2 << size); + +	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode); +	controller->in_fifo_sz = controller->in_blk_sz * (2 << size); + +	dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", +		 data, controller->in_blk_sz, controller->in_fifo_sz, +		 controller->out_blk_sz, controller->out_fifo_sz); + +	writel_relaxed(1, base + QUP_SW_RESET); + +	ret = spi_qup_set_state(controller, QUP_STATE_RESET); +	if (ret) { +		dev_err(dev, "cannot set RESET state\n"); +		goto error; +	} + +	writel_relaxed(0, base + QUP_OPERATIONAL); +	writel_relaxed(0, base + QUP_IO_M_MODES); +	writel_relaxed(0, base + QUP_OPERATIONAL_MASK); +	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN, +		       base + SPI_ERROR_FLAGS_EN); + +	writel_relaxed(0, base + SPI_CONFIG); +	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL); + +	ret = devm_request_irq(dev, irq, spi_qup_qup_irq, +			       IRQF_TRIGGER_HIGH, pdev->name, controller); +	if (ret) +		goto error; + +	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); +	pm_runtime_use_autosuspend(dev); +	pm_runtime_set_active(dev); +	pm_runtime_enable(dev); + +	ret = devm_spi_register_master(dev, master); +	if (ret) +		goto disable_pm; + +	return 0; + +disable_pm: +	pm_runtime_disable(&pdev->dev); +error: +	clk_disable_unprepare(cclk); +	clk_disable_unprepare(iclk); +	spi_master_put(master); +	return ret; +} + +#ifdef CONFIG_PM_RUNTIME +static int spi_qup_pm_suspend_runtime(struct device *device) +{ +	struct spi_master *master = dev_get_drvdata(device); +	struct spi_qup *controller = spi_master_get_devdata(master); +	u32 config; + +	/* Enable clocks auto gaiting */ +	config = readl(controller->base + QUP_CONFIG); +	config |= QUP_CONFIG_CLOCK_AUTO_GATE; +	writel_relaxed(config, controller->base + QUP_CONFIG); +	return 0; +} + +static int spi_qup_pm_resume_runtime(struct device *device) +{ +	struct spi_master *master = dev_get_drvdata(device); +	struct spi_qup *controller = spi_master_get_devdata(master); +	u32 config; + +	/* Disable clocks auto gaiting */ +	config = readl_relaxed(controller->base + QUP_CONFIG); +	config &= ~QUP_CONFIG_CLOCK_AUTO_GATE; +	writel_relaxed(config, controller->base + QUP_CONFIG); +	return 0; +} +#endif /* CONFIG_PM_RUNTIME */ + +#ifdef CONFIG_PM_SLEEP +static int spi_qup_suspend(struct device *device) +{ +	struct spi_master *master = dev_get_drvdata(device); +	struct spi_qup *controller = spi_master_get_devdata(master); +	int ret; + +	ret = spi_master_suspend(master); +	if (ret) +		return ret; + +	ret = spi_qup_set_state(controller, QUP_STATE_RESET); +	if (ret) +		return ret; + +	clk_disable_unprepare(controller->cclk); +	clk_disable_unprepare(controller->iclk); +	return 0; +} + +static int spi_qup_resume(struct device *device) +{ +	struct spi_master *master = dev_get_drvdata(device); +	struct spi_qup *controller = spi_master_get_devdata(master); +	int ret; + +	ret = clk_prepare_enable(controller->iclk); +	if (ret) +		return ret; + +	ret = clk_prepare_enable(controller->cclk); +	if (ret) +		return ret; + +	ret = spi_qup_set_state(controller, QUP_STATE_RESET); +	if (ret) +		return ret; + +	return spi_master_resume(master); +} +#endif /* CONFIG_PM_SLEEP */ + +static int spi_qup_remove(struct platform_device *pdev) +{ +	struct spi_master *master = dev_get_drvdata(&pdev->dev); +	struct spi_qup *controller = spi_master_get_devdata(master); +	int ret; + +	ret = pm_runtime_get_sync(&pdev->dev); +	if (ret < 0) +		return ret; + +	ret = spi_qup_set_state(controller, QUP_STATE_RESET); +	if (ret) +		return ret; + +	clk_disable_unprepare(controller->cclk); +	clk_disable_unprepare(controller->iclk); + +	pm_runtime_put_noidle(&pdev->dev); +	pm_runtime_disable(&pdev->dev); +	return 0; +} + +static const struct of_device_id spi_qup_dt_match[] = { +	{ .compatible = "qcom,spi-qup-v2.1.1", }, +	{ .compatible = "qcom,spi-qup-v2.2.1", }, +	{ } +}; +MODULE_DEVICE_TABLE(of, spi_qup_dt_match); + +static const struct dev_pm_ops spi_qup_dev_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(spi_qup_suspend, spi_qup_resume) +	SET_RUNTIME_PM_OPS(spi_qup_pm_suspend_runtime, +			   spi_qup_pm_resume_runtime, +			   NULL) +}; + +static struct platform_driver spi_qup_driver = { +	.driver = { +		.name		= "spi_qup", +		.owner		= THIS_MODULE, +		.pm		= &spi_qup_dev_pm_ops, +		.of_match_table = spi_qup_dt_match, +	}, +	.probe = spi_qup_probe, +	.remove = spi_qup_remove, +}; +module_platform_driver(spi_qup_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:spi_qup"); diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 8719206a03a..10112745bb1 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1,7 +1,8 @@  /*   * SH RSPI driver   * - * Copyright (C) 2012  Renesas Solutions Corp. + * Copyright (C) 2012, 2013  Renesas Solutions Corp. + * Copyright (C) 2014 Glider bvba   *   * Based on spi-sh.c:   * Copyright (C) 2011 Renesas Solutions Corp. @@ -25,223 +26,294 @@  #include <linux/kernel.h>  #include <linux/sched.h>  #include <linux/errno.h> -#include <linux/list.h> -#include <linux/workqueue.h>  #include <linux/interrupt.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/clk.h>  #include <linux/dmaengine.h>  #include <linux/dma-mapping.h> +#include <linux/of_device.h> +#include <linux/pm_runtime.h>  #include <linux/sh_dma.h>  #include <linux/spi/spi.h>  #include <linux/spi/rspi.h> -#define RSPI_SPCR		0x00 -#define RSPI_SSLP		0x01 -#define RSPI_SPPCR		0x02 -#define RSPI_SPSR		0x03 -#define RSPI_SPDR		0x04 -#define RSPI_SPSCR		0x08 -#define RSPI_SPSSR		0x09 -#define RSPI_SPBR		0x0a -#define RSPI_SPDCR		0x0b -#define RSPI_SPCKD		0x0c -#define RSPI_SSLND		0x0d -#define RSPI_SPND		0x0e -#define RSPI_SPCR2		0x0f -#define RSPI_SPCMD0		0x10 -#define RSPI_SPCMD1		0x12 -#define RSPI_SPCMD2		0x14 -#define RSPI_SPCMD3		0x16 -#define RSPI_SPCMD4		0x18 -#define RSPI_SPCMD5		0x1a -#define RSPI_SPCMD6		0x1c -#define RSPI_SPCMD7		0x1e - -/* SPCR */ -#define SPCR_SPRIE		0x80 -#define SPCR_SPE		0x40 -#define SPCR_SPTIE		0x20 -#define SPCR_SPEIE		0x10 -#define SPCR_MSTR		0x08 -#define SPCR_MODFEN		0x04 -#define SPCR_TXMD		0x02 -#define SPCR_SPMS		0x01 - -/* SSLP */ -#define SSLP_SSL1P		0x02 -#define SSLP_SSL0P		0x01 - -/* SPPCR */ -#define SPPCR_MOIFE		0x20 -#define SPPCR_MOIFV		0x10 +#define RSPI_SPCR		0x00	/* Control Register */ +#define RSPI_SSLP		0x01	/* Slave Select Polarity Register */ +#define RSPI_SPPCR		0x02	/* Pin Control Register */ +#define RSPI_SPSR		0x03	/* Status Register */ +#define RSPI_SPDR		0x04	/* Data Register */ +#define RSPI_SPSCR		0x08	/* Sequence Control Register */ +#define RSPI_SPSSR		0x09	/* Sequence Status Register */ +#define RSPI_SPBR		0x0a	/* Bit Rate Register */ +#define RSPI_SPDCR		0x0b	/* Data Control Register */ +#define RSPI_SPCKD		0x0c	/* Clock Delay Register */ +#define RSPI_SSLND		0x0d	/* Slave Select Negation Delay Register */ +#define RSPI_SPND		0x0e	/* Next-Access Delay Register */ +#define RSPI_SPCR2		0x0f	/* Control Register 2 (SH only) */ +#define RSPI_SPCMD0		0x10	/* Command Register 0 */ +#define RSPI_SPCMD1		0x12	/* Command Register 1 */ +#define RSPI_SPCMD2		0x14	/* Command Register 2 */ +#define RSPI_SPCMD3		0x16	/* Command Register 3 */ +#define RSPI_SPCMD4		0x18	/* Command Register 4 */ +#define RSPI_SPCMD5		0x1a	/* Command Register 5 */ +#define RSPI_SPCMD6		0x1c	/* Command Register 6 */ +#define RSPI_SPCMD7		0x1e	/* Command Register 7 */ +#define RSPI_SPCMD(i)		(RSPI_SPCMD0 + (i) * 2) +#define RSPI_NUM_SPCMD		8 +#define RSPI_RZ_NUM_SPCMD	4 +#define QSPI_NUM_SPCMD		4 + +/* RSPI on RZ only */ +#define RSPI_SPBFCR		0x20	/* Buffer Control Register */ +#define RSPI_SPBFDR		0x22	/* Buffer Data Count Setting Register */ + +/* QSPI only */ +#define QSPI_SPBFCR		0x18	/* Buffer Control Register */ +#define QSPI_SPBDCR		0x1a	/* Buffer Data Count Register */ +#define QSPI_SPBMUL0		0x1c	/* Transfer Data Length Multiplier Setting Register 0 */ +#define QSPI_SPBMUL1		0x20	/* Transfer Data Length Multiplier Setting Register 1 */ +#define QSPI_SPBMUL2		0x24	/* Transfer Data Length Multiplier Setting Register 2 */ +#define QSPI_SPBMUL3		0x28	/* Transfer Data Length Multiplier Setting Register 3 */ +#define QSPI_SPBMUL(i)		(QSPI_SPBMUL0 + (i) * 4) + +/* SPCR - Control Register */ +#define SPCR_SPRIE		0x80	/* Receive Interrupt Enable */ +#define SPCR_SPE		0x40	/* Function Enable */ +#define SPCR_SPTIE		0x20	/* Transmit Interrupt Enable */ +#define SPCR_SPEIE		0x10	/* Error Interrupt Enable */ +#define SPCR_MSTR		0x08	/* Master/Slave Mode Select */ +#define SPCR_MODFEN		0x04	/* Mode Fault Error Detection Enable */ +/* RSPI on SH only */ +#define SPCR_TXMD		0x02	/* TX Only Mode (vs. Full Duplex) */ +#define SPCR_SPMS		0x01	/* 3-wire Mode (vs. 4-wire) */ +/* QSPI on R-Car M2 only */ +#define SPCR_WSWAP		0x02	/* Word Swap of read-data for DMAC */ +#define SPCR_BSWAP		0x01	/* Byte Swap of read-data for DMAC */ + +/* SSLP - Slave Select Polarity Register */ +#define SSLP_SSL1P		0x02	/* SSL1 Signal Polarity Setting */ +#define SSLP_SSL0P		0x01	/* SSL0 Signal Polarity Setting */ + +/* SPPCR - Pin Control Register */ +#define SPPCR_MOIFE		0x20	/* MOSI Idle Value Fixing Enable */ +#define SPPCR_MOIFV		0x10	/* MOSI Idle Fixed Value */  #define SPPCR_SPOM		0x04 -#define SPPCR_SPLP2		0x02 -#define SPPCR_SPLP		0x01 - -/* SPSR */ -#define SPSR_SPRF		0x80 -#define SPSR_SPTEF		0x20 -#define SPSR_PERF		0x08 -#define SPSR_MODF		0x04 -#define SPSR_IDLNF		0x02 -#define SPSR_OVRF		0x01 - -/* SPSCR */ -#define SPSCR_SPSLN_MASK	0x07 - -/* SPSSR */ -#define SPSSR_SPECM_MASK	0x70 -#define SPSSR_SPCP_MASK		0x07 - -/* SPDCR */ -#define SPDCR_SPLW		0x20 -#define SPDCR_SPRDTD		0x10 +#define SPPCR_SPLP2		0x02	/* Loopback Mode 2 (non-inverting) */ +#define SPPCR_SPLP		0x01	/* Loopback Mode (inverting) */ + +#define SPPCR_IO3FV		0x04	/* Single-/Dual-SPI Mode IO3 Output Fixed Value */ +#define SPPCR_IO2FV		0x04	/* Single-/Dual-SPI Mode IO2 Output Fixed Value */ + +/* SPSR - Status Register */ +#define SPSR_SPRF		0x80	/* Receive Buffer Full Flag */ +#define SPSR_TEND		0x40	/* Transmit End */ +#define SPSR_SPTEF		0x20	/* Transmit Buffer Empty Flag */ +#define SPSR_PERF		0x08	/* Parity Error Flag */ +#define SPSR_MODF		0x04	/* Mode Fault Error Flag */ +#define SPSR_IDLNF		0x02	/* RSPI Idle Flag */ +#define SPSR_OVRF		0x01	/* Overrun Error Flag (RSPI only) */ + +/* SPSCR - Sequence Control Register */ +#define SPSCR_SPSLN_MASK	0x07	/* Sequence Length Specification */ + +/* SPSSR - Sequence Status Register */ +#define SPSSR_SPECM_MASK	0x70	/* Command Error Mask */ +#define SPSSR_SPCP_MASK		0x07	/* Command Pointer Mask */ + +/* SPDCR - Data Control Register */ +#define SPDCR_TXDMY		0x80	/* Dummy Data Transmission Enable */ +#define SPDCR_SPLW1		0x40	/* Access Width Specification (RZ) */ +#define SPDCR_SPLW0		0x20	/* Access Width Specification (RZ) */ +#define SPDCR_SPLLWORD		(SPDCR_SPLW1 | SPDCR_SPLW0) +#define SPDCR_SPLWORD		SPDCR_SPLW1 +#define SPDCR_SPLBYTE		SPDCR_SPLW0 +#define SPDCR_SPLW		0x20	/* Access Width Specification (SH) */ +#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select (SH) */  #define SPDCR_SLSEL1		0x08  #define SPDCR_SLSEL0		0x04 -#define SPDCR_SLSEL_MASK	0x0c +#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select (SH) */  #define SPDCR_SPFC1		0x02  #define SPDCR_SPFC0		0x01 +#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) (SH) */ -/* SPCKD */ -#define SPCKD_SCKDL_MASK	0x07 +/* SPCKD - Clock Delay Register */ +#define SPCKD_SCKDL_MASK	0x07	/* Clock Delay Setting (1-8) */ -/* SSLND */ -#define SSLND_SLNDL_MASK	0x07 +/* SSLND - Slave Select Negation Delay Register */ +#define SSLND_SLNDL_MASK	0x07	/* SSL Negation Delay Setting (1-8) */ -/* SPND */ -#define SPND_SPNDL_MASK		0x07 +/* SPND - Next-Access Delay Register */ +#define SPND_SPNDL_MASK		0x07	/* Next-Access Delay Setting (1-8) */ -/* SPCR2 */ -#define SPCR2_PTE		0x08 -#define SPCR2_SPIE		0x04 -#define SPCR2_SPOE		0x02 -#define SPCR2_SPPE		0x01 +/* SPCR2 - Control Register 2 */ +#define SPCR2_PTE		0x08	/* Parity Self-Test Enable */ +#define SPCR2_SPIE		0x04	/* Idle Interrupt Enable */ +#define SPCR2_SPOE		0x02	/* Odd Parity Enable (vs. Even) */ +#define SPCR2_SPPE		0x01	/* Parity Enable */ -/* SPCMDn */ -#define SPCMD_SCKDEN		0x8000 -#define SPCMD_SLNDEN		0x4000 -#define SPCMD_SPNDEN		0x2000 -#define SPCMD_LSBF		0x1000 -#define SPCMD_SPB_MASK		0x0f00 +/* SPCMDn - Command Registers */ +#define SPCMD_SCKDEN		0x8000	/* Clock Delay Setting Enable */ +#define SPCMD_SLNDEN		0x4000	/* SSL Negation Delay Setting Enable */ +#define SPCMD_SPNDEN		0x2000	/* Next-Access Delay Enable */ +#define SPCMD_LSBF		0x1000	/* LSB First */ +#define SPCMD_SPB_MASK		0x0f00	/* Data Length Setting */  #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK) +#define SPCMD_SPB_8BIT		0x0000	/* QSPI only */ +#define SPCMD_SPB_16BIT		0x0100  #define SPCMD_SPB_20BIT		0x0000  #define SPCMD_SPB_24BIT		0x0100  #define SPCMD_SPB_32BIT		0x0200 -#define SPCMD_SSLKP		0x0080 -#define SPCMD_SSLA_MASK		0x0030 -#define SPCMD_BRDV_MASK		0x000c -#define SPCMD_CPOL		0x0002 -#define SPCMD_CPHA		0x0001 +#define SPCMD_SSLKP		0x0080	/* SSL Signal Level Keeping */ +#define SPCMD_SPIMOD_MASK	0x0060	/* SPI Operating Mode (QSPI only) */ +#define SPCMD_SPIMOD1		0x0040 +#define SPCMD_SPIMOD0		0x0020 +#define SPCMD_SPIMOD_SINGLE	0 +#define SPCMD_SPIMOD_DUAL	SPCMD_SPIMOD0 +#define SPCMD_SPIMOD_QUAD	SPCMD_SPIMOD1 +#define SPCMD_SPRW		0x0010	/* SPI Read/Write Access (Dual/Quad) */ +#define SPCMD_SSLA_MASK		0x0030	/* SSL Assert Signal Setting (RSPI) */ +#define SPCMD_BRDV_MASK		0x000c	/* Bit Rate Division Setting */ +#define SPCMD_CPOL		0x0002	/* Clock Polarity Setting */ +#define SPCMD_CPHA		0x0001	/* Clock Phase Setting */ + +/* SPBFCR - Buffer Control Register */ +#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset */ +#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset */ +#define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */ +#define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */  struct rspi_data {  	void __iomem *addr;  	u32 max_speed_hz;  	struct spi_master *master; -	struct list_head queue; -	struct work_struct ws;  	wait_queue_head_t wait; -	spinlock_t lock;  	struct clk *clk; -	unsigned char spsr; +	u16 spcmd; +	u8 spsr; +	u8 sppcr; +	int rx_irq, tx_irq; +	const struct spi_ops *ops; -	/* for dmaengine */ -	struct dma_chan *chan_tx; -	struct dma_chan *chan_rx; -	int irq; - -	unsigned dma_width_16bit:1;  	unsigned dma_callbacked:1; +	unsigned byte_access:1;  }; -static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset) +static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)  {  	iowrite8(data, rspi->addr + offset);  } -static void rspi_write16(struct rspi_data *rspi, u16 data, u16 offset) +static void rspi_write16(const struct rspi_data *rspi, u16 data, u16 offset)  {  	iowrite16(data, rspi->addr + offset);  } -static u8 rspi_read8(struct rspi_data *rspi, u16 offset) +static void rspi_write32(const struct rspi_data *rspi, u32 data, u16 offset)  { -	return ioread8(rspi->addr + offset); +	iowrite32(data, rspi->addr + offset);  } -static u16 rspi_read16(struct rspi_data *rspi, u16 offset) +static u8 rspi_read8(const struct rspi_data *rspi, u16 offset)  { -	return ioread16(rspi->addr + offset); +	return ioread8(rspi->addr + offset);  } -static unsigned char rspi_calc_spbr(struct rspi_data *rspi) +static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)  { -	int tmp; -	unsigned char spbr; - -	tmp = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; -	spbr = clamp(tmp, 0, 255); - -	return spbr; +	return ioread16(rspi->addr + offset);  } -static void rspi_enable_irq(struct rspi_data *rspi, u8 enable) +static void rspi_write_data(const struct rspi_data *rspi, u16 data)  { -	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR); +	if (rspi->byte_access) +		rspi_write8(rspi, data, RSPI_SPDR); +	else /* 16 bit */ +		rspi_write16(rspi, data, RSPI_SPDR);  } -static void rspi_disable_irq(struct rspi_data *rspi, u8 disable) +static u16 rspi_read_data(const struct rspi_data *rspi)  { -	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~disable, RSPI_SPCR); +	if (rspi->byte_access) +		return rspi_read8(rspi, RSPI_SPDR); +	else /* 16 bit */ +		return rspi_read16(rspi, RSPI_SPDR);  } -static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask, -				   u8 enable_bit) +/* optional functions */ +struct spi_ops { +	int (*set_config_register)(struct rspi_data *rspi, int access_size); +	int (*transfer_one)(struct spi_master *master, struct spi_device *spi, +			    struct spi_transfer *xfer); +	u16 mode_bits; +	u16 flags; +	u16 fifo_size; +}; + +/* + * functions for RSPI on legacy SH + */ +static int rspi_set_config_register(struct rspi_data *rspi, int access_size)  { -	int ret; +	int spbr; -	rspi->spsr = rspi_read8(rspi, RSPI_SPSR); -	rspi_enable_irq(rspi, enable_bit); -	ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ); -	if (ret == 0 && !(rspi->spsr & wait_mask)) -		return -ETIMEDOUT; +	/* Sets output mode, MOSI signal, and (optionally) loopback */ +	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR); -	return 0; -} +	/* Sets transfer bit rate */ +	spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), +			    2 * rspi->max_speed_hz) - 1; +	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); -static void rspi_assert_ssl(struct rspi_data *rspi) -{ -	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR); -} +	/* Disable dummy transmission, set 16-bit word access, 1 frame */ +	rspi_write8(rspi, 0, RSPI_SPDCR); +	rspi->byte_access = 0; -static void rspi_negate_ssl(struct rspi_data *rspi) -{ -	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR); +	/* Sets RSPCK, SSL, next-access delay value */ +	rspi_write8(rspi, 0x00, RSPI_SPCKD); +	rspi_write8(rspi, 0x00, RSPI_SSLND); +	rspi_write8(rspi, 0x00, RSPI_SPND); + +	/* Sets parity, interrupt mask */ +	rspi_write8(rspi, 0x00, RSPI_SPCR2); + +	/* Sets SPCMD */ +	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); +	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); + +	/* Sets RSPI mode */ +	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); + +	return 0;  } -static int rspi_set_config_register(struct rspi_data *rspi, int access_size) +/* + * functions for RSPI on RZ + */ +static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)  { -	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ -	rspi_write8(rspi, 0x00, RSPI_SPPCR); +	int spbr; + +	/* Sets output mode, MOSI signal, and (optionally) loopback */ +	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);  	/* Sets transfer bit rate */ -	rspi_write8(rspi, rspi_calc_spbr(rspi), RSPI_SPBR); +	spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), +			    2 * rspi->max_speed_hz) - 1; +	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); -	/* Sets number of frames to be used: 1 frame */ -	rspi_write8(rspi, 0x00, RSPI_SPDCR); +	/* Disable dummy transmission, set byte access */ +	rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR); +	rspi->byte_access = 1;  	/* Sets RSPCK, SSL, next-access delay value */  	rspi_write8(rspi, 0x00, RSPI_SPCKD);  	rspi_write8(rspi, 0x00, RSPI_SSLND);  	rspi_write8(rspi, 0x00, RSPI_SPND); -	/* Sets parity, interrupt mask */ -	rspi_write8(rspi, 0x00, RSPI_SPCR2); -  	/* Sets SPCMD */ -	rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP, -		     RSPI_SPCMD0); +	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); +	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);  	/* Sets RSPI mode */  	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); @@ -249,131 +321,209 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)  	return 0;  } -static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, -			 struct spi_transfer *t) +/* + * functions for QSPI + */ +static int qspi_set_config_register(struct rspi_data *rspi, int access_size)  { -	int remain = t->len; -	u8 *data; +	int spbr; -	data = (u8 *)t->tx_buf; -	while (remain > 0) { -		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, -			    RSPI_SPCR); +	/* Sets output mode, MOSI signal, and (optionally) loopback */ +	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR); -		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { -			dev_err(&rspi->master->dev, -				"%s: tx empty timeout\n", __func__); -			return -ETIMEDOUT; -		} +	/* Sets transfer bit rate */ +	spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), 2 * rspi->max_speed_hz); +	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); -		rspi_write16(rspi, *data, RSPI_SPDR); -		data++; -		remain--; -	} +	/* Disable dummy transmission, set byte access */ +	rspi_write8(rspi, 0, RSPI_SPDCR); +	rspi->byte_access = 1; -	/* Waiting for the last transmition */ -	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); +	/* Sets RSPCK, SSL, next-access delay value */ +	rspi_write8(rspi, 0x00, RSPI_SPCKD); +	rspi_write8(rspi, 0x00, RSPI_SSLND); +	rspi_write8(rspi, 0x00, RSPI_SPND); + +	/* Data Length Setting */ +	if (access_size == 8) +		rspi->spcmd |= SPCMD_SPB_8BIT; +	else if (access_size == 16) +		rspi->spcmd |= SPCMD_SPB_16BIT; +	else +		rspi->spcmd |= SPCMD_SPB_32BIT; + +	rspi->spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SPNDEN; + +	/* Resets transfer data length */ +	rspi_write32(rspi, 0, QSPI_SPBMUL0); + +	/* Resets transmit and receive buffer */ +	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); +	/* Sets buffer to allow normal operation */ +	rspi_write8(rspi, 0x00, QSPI_SPBFCR); + +	/* Sets SPCMD */ +	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); + +	/* Enables SPI function in master mode */ +	rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);  	return 0;  } -static void rspi_dma_complete(void *arg) +#define set_config_register(spi, n) spi->ops->set_config_register(spi, n) + +static void rspi_enable_irq(const struct rspi_data *rspi, u8 enable)  { -	struct rspi_data *rspi = arg; +	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR); +} -	rspi->dma_callbacked = 1; -	wake_up_interruptible(&rspi->wait); +static void rspi_disable_irq(const struct rspi_data *rspi, u8 disable) +{ +	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~disable, RSPI_SPCR);  } -static int rspi_dma_map_sg(struct scatterlist *sg, void *buf, unsigned len, -			   struct dma_chan *chan, -			   enum dma_transfer_direction dir) +static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask, +				   u8 enable_bit)  { -	sg_init_table(sg, 1); -	sg_set_buf(sg, buf, len); -	sg_dma_len(sg) = len; -	return dma_map_sg(chan->device->dev, sg, 1, dir); +	int ret; + +	rspi->spsr = rspi_read8(rspi, RSPI_SPSR); +	if (rspi->spsr & wait_mask) +		return 0; + +	rspi_enable_irq(rspi, enable_bit); +	ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ); +	if (ret == 0 && !(rspi->spsr & wait_mask)) +		return -ETIMEDOUT; + +	return 0;  } -static void rspi_dma_unmap_sg(struct scatterlist *sg, struct dma_chan *chan, -			      enum dma_transfer_direction dir) +static inline int rspi_wait_for_tx_empty(struct rspi_data *rspi)  { -	dma_unmap_sg(chan->device->dev, sg, 1, dir); +	return rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);  } -static void rspi_memory_to_8bit(void *buf, const void *data, unsigned len) +static inline int rspi_wait_for_rx_full(struct rspi_data *rspi)  { -	u16 *dst = buf; -	const u8 *src = data; +	return rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE); +} -	while (len) { -		*dst++ = (u16)(*src++); -		len--; +static int rspi_data_out(struct rspi_data *rspi, u8 data) +{ +	int error = rspi_wait_for_tx_empty(rspi); +	if (error < 0) { +		dev_err(&rspi->master->dev, "transmit timeout\n"); +		return error;  	} +	rspi_write_data(rspi, data); +	return 0;  } -static void rspi_memory_from_8bit(void *buf, const void *data, unsigned len) +static int rspi_data_in(struct rspi_data *rspi)  { -	u8 *dst = buf; -	const u16 *src = data; +	int error; +	u8 data; -	while (len) { -		*dst++ = (u8)*src++; -		len--; +	error = rspi_wait_for_rx_full(rspi); +	if (error < 0) { +		dev_err(&rspi->master->dev, "receive timeout\n"); +		return error;  	} +	data = rspi_read_data(rspi); +	return data;  } -static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) -{ -	struct scatterlist sg; -	void *buf = NULL; -	struct dma_async_tx_descriptor *desc; -	unsigned len; -	int ret = 0; - -	if (rspi->dma_width_16bit) { -		/* -		 * If DMAC bus width is 16-bit, the driver allocates a dummy -		 * buffer. And, the driver converts original data into the -		 * DMAC data as the following format: -		 *  original data: 1st byte, 2nd byte ... -		 *  DMAC data:     1st byte, dummy, 2nd byte, dummy ... -		 */ -		len = t->len * 2; -		buf = kmalloc(len, GFP_KERNEL); -		if (!buf) -			return -ENOMEM; -		rspi_memory_to_8bit(buf, t->tx_buf, t->len); -	} else { -		len = t->len; -		buf = (void *)t->tx_buf; +static int rspi_pio_transfer(struct rspi_data *rspi, const u8 *tx, u8 *rx, +			     unsigned int n) +{ +	while (n-- > 0) { +		if (tx) { +			int ret = rspi_data_out(rspi, *tx++); +			if (ret < 0) +				return ret; +		} +		if (rx) { +			int ret = rspi_data_in(rspi); +			if (ret < 0) +				return ret; +			*rx++ = ret; +		}  	} -	if (!rspi_dma_map_sg(&sg, buf, len, rspi->chan_tx, DMA_TO_DEVICE)) { -		ret = -EFAULT; -		goto end_nomap; +	return 0; +} + +static void rspi_dma_complete(void *arg) +{ +	struct rspi_data *rspi = arg; + +	rspi->dma_callbacked = 1; +	wake_up_interruptible(&rspi->wait); +} + +static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, +			     struct sg_table *rx) +{ +	struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; +	u8 irq_mask = 0; +	unsigned int other_irq = 0; +	dma_cookie_t cookie; +	int ret; + +	if (tx) { +		desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, +					tx->sgl, tx->nents, DMA_TO_DEVICE, +					DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +		if (!desc_tx) +			return -EIO; + +		irq_mask |= SPCR_SPTIE;  	} -	desc = dmaengine_prep_slave_sg(rspi->chan_tx, &sg, 1, DMA_TO_DEVICE, -				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -	if (!desc) { -		ret = -EIO; -		goto end; +	if (rx) { +		desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx, +					rx->sgl, rx->nents, DMA_FROM_DEVICE, +					DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +		if (!desc_rx) +			return -EIO; + +		irq_mask |= SPCR_SPRIE;  	}  	/* -	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be +	 * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be  	 * called. So, this driver disables the IRQ while DMA transfer.  	 */ -	disable_irq(rspi->irq); +	if (tx) +		disable_irq(other_irq = rspi->tx_irq); +	if (rx && rspi->rx_irq != other_irq) +		disable_irq(rspi->rx_irq); -	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR); -	rspi_enable_irq(rspi, SPCR_SPTIE); +	rspi_enable_irq(rspi, irq_mask);  	rspi->dma_callbacked = 0; -	desc->callback = rspi_dma_complete; -	desc->callback_param = rspi; -	dmaengine_submit(desc); -	dma_async_issue_pending(rspi->chan_tx); +	if (rx) { +		desc_rx->callback = rspi_dma_complete; +		desc_rx->callback_param = rspi; +		cookie = dmaengine_submit(desc_rx); +		if (dma_submit_error(cookie)) +			return cookie; +		dma_async_issue_pending(rspi->master->dma_rx); +	} +	if (tx) { +		if (rx) { +			/* No callback */ +			desc_tx->callback = NULL; +		} else { +			desc_tx->callback = rspi_dma_complete; +			desc_tx->callback_param = rspi; +		} +		cookie = dmaengine_submit(desc_tx); +		if (dma_submit_error(cookie)) +			return cookie; +		dma_async_issue_pending(rspi->master->dma_tx); +	}  	ret = wait_event_interruptible_timeout(rspi->wait,  					       rspi->dma_callbacked, HZ); @@ -381,272 +531,290 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)  		ret = 0;  	else if (!ret)  		ret = -ETIMEDOUT; -	rspi_disable_irq(rspi, SPCR_SPTIE); -	enable_irq(rspi->irq); +	rspi_disable_irq(rspi, irq_mask); -end: -	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE); -end_nomap: -	if (rspi->dma_width_16bit) -		kfree(buf); +	if (tx) +		enable_irq(rspi->tx_irq); +	if (rx && rspi->rx_irq != other_irq) +		enable_irq(rspi->rx_irq);  	return ret;  } -static void rspi_receive_init(struct rspi_data *rspi) +static void rspi_receive_init(const struct rspi_data *rspi)  { -	unsigned char spsr; +	u8 spsr;  	spsr = rspi_read8(rspi, RSPI_SPSR);  	if (spsr & SPSR_SPRF) -		rspi_read16(rspi, RSPI_SPDR);	/* dummy read */ +		rspi_read_data(rspi);	/* dummy read */  	if (spsr & SPSR_OVRF)  		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF, -			    RSPI_SPCR); +			    RSPI_SPSR);  } -static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, -			    struct spi_transfer *t) +static void rspi_rz_receive_init(const struct rspi_data *rspi)  { -	int remain = t->len; -	u8 *data; -  	rspi_receive_init(rspi); +	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, RSPI_SPBFCR); +	rspi_write8(rspi, 0, RSPI_SPBFCR); +} -	data = (u8 *)t->rx_buf; -	while (remain > 0) { -		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, -			    RSPI_SPCR); +static void qspi_receive_init(const struct rspi_data *rspi) +{ +	u8 spsr; -		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { -			dev_err(&rspi->master->dev, -				"%s: tx empty timeout\n", __func__); -			return -ETIMEDOUT; -		} -		/* dummy write for generate clock */ -		rspi_write16(rspi, 0x00, RSPI_SPDR); +	spsr = rspi_read8(rspi, RSPI_SPSR); +	if (spsr & SPSR_SPRF) +		rspi_read_data(rspi);   /* dummy read */ +	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); +	rspi_write8(rspi, 0, QSPI_SPBFCR); +} -		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { -			dev_err(&rspi->master->dev, -				"%s: receive timeout\n", __func__); -			return -ETIMEDOUT; -		} -		/* SPDR allows 16 or 32-bit access only */ -		*data = (u8)rspi_read16(rspi, RSPI_SPDR); +static bool __rspi_can_dma(const struct rspi_data *rspi, +			   const struct spi_transfer *xfer) +{ +	return xfer->len > rspi->ops->fifo_size; +} -		data++; -		remain--; -	} +static bool rspi_can_dma(struct spi_master *master, struct spi_device *spi, +			 struct spi_transfer *xfer) +{ +	struct rspi_data *rspi = spi_master_get_devdata(master); -	return 0; +	return __rspi_can_dma(rspi, xfer);  } -static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) -{ -	struct scatterlist sg, sg_dummy; -	void *dummy = NULL, *rx_buf = NULL; -	struct dma_async_tx_descriptor *desc, *desc_dummy; -	unsigned len; -	int ret = 0; - -	if (rspi->dma_width_16bit) { -		/* -		 * If DMAC bus width is 16-bit, the driver allocates a dummy -		 * buffer. And, finally the driver converts the DMAC data into -		 * actual data as the following format: -		 *  DMAC data:   1st byte, dummy, 2nd byte, dummy ... -		 *  actual data: 1st byte, 2nd byte ... -		 */ -		len = t->len * 2; -		rx_buf = kmalloc(len, GFP_KERNEL); -		if (!rx_buf) -			return -ENOMEM; -	 } else { -		len = t->len; -		rx_buf = t->rx_buf; -	} +static int rspi_common_transfer(struct rspi_data *rspi, +				struct spi_transfer *xfer) +{ +	int ret; -	/* prepare dummy transfer to generate SPI clocks */ -	dummy = kzalloc(len, GFP_KERNEL); -	if (!dummy) { -		ret = -ENOMEM; -		goto end_nomap; -	} -	if (!rspi_dma_map_sg(&sg_dummy, dummy, len, rspi->chan_tx, -			     DMA_TO_DEVICE)) { -		ret = -EFAULT; -		goto end_nomap; -	} -	desc_dummy = dmaengine_prep_slave_sg(rspi->chan_tx, &sg_dummy, 1, -			DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -	if (!desc_dummy) { -		ret = -EIO; -		goto end_dummy_mapped; +	if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { +		/* rx_buf can be NULL on RSPI on SH in TX-only Mode */ +		return rspi_dma_transfer(rspi, &xfer->tx_sg, +					 xfer->rx_buf ? &xfer->rx_sg : NULL);  	} -	/* prepare receive transfer */ -	if (!rspi_dma_map_sg(&sg, rx_buf, len, rspi->chan_rx, -			     DMA_FROM_DEVICE)) { -		ret = -EFAULT; -		goto end_dummy_mapped; +	ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len); +	if (ret < 0) +		return ret; -	} -	desc = dmaengine_prep_slave_sg(rspi->chan_rx, &sg, 1, DMA_FROM_DEVICE, -				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -	if (!desc) { -		ret = -EIO; -		goto end; -	} +	/* Wait for the last transmission */ +	rspi_wait_for_tx_empty(rspi); -	rspi_receive_init(rspi); +	return 0; +} -	/* -	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be -	 * called. So, this driver disables the IRQ while DMA transfer. -	 */ -	disable_irq(rspi->irq); +static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi, +			     struct spi_transfer *xfer) +{ +	struct rspi_data *rspi = spi_master_get_devdata(master); +	u8 spcr; -	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR); -	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); -	rspi->dma_callbacked = 0; +	spcr = rspi_read8(rspi, RSPI_SPCR); +	if (xfer->rx_buf) { +		rspi_receive_init(rspi); +		spcr &= ~SPCR_TXMD; +	} else { +		spcr |= SPCR_TXMD; +	} +	rspi_write8(rspi, spcr, RSPI_SPCR); -	desc->callback = rspi_dma_complete; -	desc->callback_param = rspi; -	dmaengine_submit(desc); -	dma_async_issue_pending(rspi->chan_rx); +	return rspi_common_transfer(rspi, xfer); +} -	desc_dummy->callback = NULL;	/* No callback */ -	dmaengine_submit(desc_dummy); -	dma_async_issue_pending(rspi->chan_tx); +static int rspi_rz_transfer_one(struct spi_master *master, +				struct spi_device *spi, +				struct spi_transfer *xfer) +{ +	struct rspi_data *rspi = spi_master_get_devdata(master); +	int ret; -	ret = wait_event_interruptible_timeout(rspi->wait, -					       rspi->dma_callbacked, HZ); -	if (ret > 0 && rspi->dma_callbacked) -		ret = 0; -	else if (!ret) -		ret = -ETIMEDOUT; -	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); +	rspi_rz_receive_init(rspi); -	enable_irq(rspi->irq); +	return rspi_common_transfer(rspi, xfer); +} -end: -	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); -end_dummy_mapped: -	rspi_dma_unmap_sg(&sg_dummy, rspi->chan_tx, DMA_TO_DEVICE); -end_nomap: -	if (rspi->dma_width_16bit) { -		if (!ret) -			rspi_memory_from_8bit(t->rx_buf, rx_buf, t->len); -		kfree(rx_buf); -	} -	kfree(dummy); +static int qspi_transfer_out_in(struct rspi_data *rspi, +				struct spi_transfer *xfer) +{ +	qspi_receive_init(rspi); -	return ret; +	return rspi_common_transfer(rspi, xfer);  } -static int rspi_is_dma(struct rspi_data *rspi, struct spi_transfer *t) +static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)  { -	if (t->tx_buf && rspi->chan_tx) -		return 1; -	/* If the module receives data by DMAC, it also needs TX DMAC */ -	if (t->rx_buf && rspi->chan_tx && rspi->chan_rx) -		return 1; +	int ret; + +	if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) +		return rspi_dma_transfer(rspi, &xfer->tx_sg, NULL); + +	ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len); +	if (ret < 0) +		return ret; + +	/* Wait for the last transmission */ +	rspi_wait_for_tx_empty(rspi);  	return 0;  } -static void rspi_work(struct work_struct *work) +static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)  { -	struct rspi_data *rspi = container_of(work, struct rspi_data, ws); -	struct spi_message *mesg; -	struct spi_transfer *t; -	unsigned long flags; -	int ret; +	if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) +		return rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); -	while (1) { -		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); -		list_del_init(&mesg->queue); -		spin_unlock_irqrestore(&rspi->lock, flags); - -		rspi_assert_ssl(rspi); - -		list_for_each_entry(t, &mesg->transfers, transfer_list) { -			if (t->tx_buf) { -				if (rspi_is_dma(rspi, t)) -					ret = rspi_send_dma(rspi, t); -				else -					ret = rspi_send_pio(rspi, mesg, t); -				if (ret < 0) -					goto error; -			} -			if (t->rx_buf) { -				if (rspi_is_dma(rspi, t)) -					ret = rspi_receive_dma(rspi, t); -				else -					ret = rspi_receive_pio(rspi, mesg, t); -				if (ret < 0) -					goto error; -			} -			mesg->actual_length += t->len; -		} -		rspi_negate_ssl(rspi); +	return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len); +} -		mesg->status = 0; -		mesg->complete(mesg->context); +static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, +			     struct spi_transfer *xfer) +{ +	struct rspi_data *rspi = spi_master_get_devdata(master); + +	if (spi->mode & SPI_LOOP) { +		return qspi_transfer_out_in(rspi, xfer); +	} else if (xfer->tx_nbits > SPI_NBITS_SINGLE) { +		/* Quad or Dual SPI Write */ +		return qspi_transfer_out(rspi, xfer); +	} else if (xfer->rx_nbits > SPI_NBITS_SINGLE) { +		/* Quad or Dual SPI Read */ +		return qspi_transfer_in(rspi, xfer); +	} else { +		/* Single SPI Transfer */ +		return qspi_transfer_out_in(rspi, xfer);  	} - -	return; - -error: -	mesg->status = ret; -	mesg->complete(mesg->context);  }  static int rspi_setup(struct spi_device *spi)  {  	struct rspi_data *rspi = spi_master_get_devdata(spi->master); -	if (!spi->bits_per_word) -		spi->bits_per_word = 8;  	rspi->max_speed_hz = spi->max_speed_hz; -	rspi_set_config_register(rspi, 8); +	rspi->spcmd = SPCMD_SSLKP; +	if (spi->mode & SPI_CPOL) +		rspi->spcmd |= SPCMD_CPOL; +	if (spi->mode & SPI_CPHA) +		rspi->spcmd |= SPCMD_CPHA; + +	/* CMOS output mode and MOSI signal from previous transfer */ +	rspi->sppcr = 0; +	if (spi->mode & SPI_LOOP) +		rspi->sppcr |= SPPCR_SPLP; + +	set_config_register(rspi, 8);  	return 0;  } -static int rspi_transfer(struct spi_device *spi, struct spi_message *mesg) +static u16 qspi_transfer_mode(const struct spi_transfer *xfer)  { -	struct rspi_data *rspi = spi_master_get_devdata(spi->master); -	unsigned long flags; +	if (xfer->tx_buf) +		switch (xfer->tx_nbits) { +		case SPI_NBITS_QUAD: +			return SPCMD_SPIMOD_QUAD; +		case SPI_NBITS_DUAL: +			return SPCMD_SPIMOD_DUAL; +		default: +			return 0; +		} +	if (xfer->rx_buf) +		switch (xfer->rx_nbits) { +		case SPI_NBITS_QUAD: +			return SPCMD_SPIMOD_QUAD | SPCMD_SPRW; +		case SPI_NBITS_DUAL: +			return SPCMD_SPIMOD_DUAL | SPCMD_SPRW; +		default: +			return 0; +		} + +	return 0; +} + +static int qspi_setup_sequencer(struct rspi_data *rspi, +				const struct spi_message *msg) +{ +	const struct spi_transfer *xfer; +	unsigned int i = 0, len = 0; +	u16 current_mode = 0xffff, mode; + +	list_for_each_entry(xfer, &msg->transfers, transfer_list) { +		mode = qspi_transfer_mode(xfer); +		if (mode == current_mode) { +			len += xfer->len; +			continue; +		} + +		/* Transfer mode change */ +		if (i) { +			/* Set transfer data length of previous transfer */ +			rspi_write32(rspi, len, QSPI_SPBMUL(i - 1)); +		} -	mesg->actual_length = 0; -	mesg->status = -EINPROGRESS; +		if (i >= QSPI_NUM_SPCMD) { +			dev_err(&msg->spi->dev, +				"Too many different transfer modes"); +			return -EINVAL; +		} -	spin_lock_irqsave(&rspi->lock, flags); -	list_add_tail(&mesg->queue, &rspi->queue); -	schedule_work(&rspi->ws); -	spin_unlock_irqrestore(&rspi->lock, flags); +		/* Program transfer mode for this transfer */ +		rspi_write16(rspi, rspi->spcmd | mode, RSPI_SPCMD(i)); +		current_mode = mode; +		len = xfer->len; +		i++; +	} +	if (i) { +		/* Set final transfer data length and sequence length */ +		rspi_write32(rspi, len, QSPI_SPBMUL(i - 1)); +		rspi_write8(rspi, i - 1, RSPI_SPSCR); +	}  	return 0;  } -static void rspi_cleanup(struct spi_device *spi) +static int rspi_prepare_message(struct spi_master *master, +				struct spi_message *msg)  { +	struct rspi_data *rspi = spi_master_get_devdata(master); +	int ret; + +	if (msg->spi->mode & +	    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) { +		/* Setup sequencer for messages with multiple transfer modes */ +		ret = qspi_setup_sequencer(rspi, msg); +		if (ret < 0) +			return ret; +	} + +	/* Enable SPI function in master mode */ +	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR); +	return 0;  } -static irqreturn_t rspi_irq(int irq, void *_sr) +static int rspi_unprepare_message(struct spi_master *master, +				  struct spi_message *msg)  { -	struct rspi_data *rspi = (struct rspi_data *)_sr; -	unsigned long spsr; +	struct rspi_data *rspi = spi_master_get_devdata(master); + +	/* Disable SPI function */ +	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR); + +	/* Reset sequencer for Single SPI Transfers */ +	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); +	rspi_write8(rspi, 0, RSPI_SPSCR); +	return 0; +} + +static irqreturn_t rspi_irq_mux(int irq, void *_sr) +{ +	struct rspi_data *rspi = _sr; +	u8 spsr;  	irqreturn_t ret = IRQ_NONE; -	unsigned char disable_irq = 0; +	u8 disable_irq = 0;  	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);  	if (spsr & SPSR_SPRF) @@ -663,101 +831,204 @@ static irqreturn_t rspi_irq(int irq, void *_sr)  	return ret;  } -static int rspi_request_dma(struct rspi_data *rspi, -				      struct platform_device *pdev) +static irqreturn_t rspi_irq_rx(int irq, void *_sr) +{ +	struct rspi_data *rspi = _sr; +	u8 spsr; + +	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR); +	if (spsr & SPSR_SPRF) { +		rspi_disable_irq(rspi, SPCR_SPRIE); +		wake_up(&rspi->wait); +		return IRQ_HANDLED; +	} + +	return 0; +} + +static irqreturn_t rspi_irq_tx(int irq, void *_sr) +{ +	struct rspi_data *rspi = _sr; +	u8 spsr; + +	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR); +	if (spsr & SPSR_SPTEF) { +		rspi_disable_irq(rspi, SPCR_SPTIE); +		wake_up(&rspi->wait); +		return IRQ_HANDLED; +	} + +	return 0; +} + +static struct dma_chan *rspi_request_dma_chan(struct device *dev, +					      enum dma_transfer_direction dir, +					      unsigned int id, +					      dma_addr_t port_addr)  { -	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; +	struct dma_chan *chan;  	struct dma_slave_config cfg;  	int ret; -	if (!res || !rspi_pd) -		return 0;	/* The driver assumes no error. */ +	dma_cap_zero(mask); +	dma_cap_set(DMA_SLAVE, mask); -	rspi->dma_width_16bit = rspi_pd->dma_width_16bit; - -	/* If the module receives data by DMAC, it also needs TX DMAC */ -	if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { -		dma_cap_zero(mask); -		dma_cap_set(DMA_SLAVE, mask); -		rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter, -						    (void *)rspi_pd->dma_rx_id); -		if (rspi->chan_rx) { -			cfg.slave_id = rspi_pd->dma_rx_id; -			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); -			if (!ret) -				dev_info(&pdev->dev, "Use DMA when rx.\n"); -			else -				return ret; -		} +	chan = dma_request_channel(mask, shdma_chan_filter, +				   (void *)(unsigned long)id); +	if (!chan) { +		dev_warn(dev, "dma_request_channel failed\n"); +		return NULL;  	} -	if (rspi_pd->dma_tx_id) { -		dma_cap_zero(mask); -		dma_cap_set(DMA_SLAVE, mask); -		rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter, -						    (void *)rspi_pd->dma_tx_id); -		if (rspi->chan_tx) { -			cfg.slave_id = rspi_pd->dma_tx_id; -			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); -			if (!ret) -				dev_info(&pdev->dev, "Use DMA when tx\n"); -			else -				return ret; -		} + +	memset(&cfg, 0, sizeof(cfg)); +	cfg.slave_id = id; +	cfg.direction = dir; +	if (dir == DMA_MEM_TO_DEV) +		cfg.dst_addr = port_addr; +	else +		cfg.src_addr = port_addr; + +	ret = dmaengine_slave_config(chan, &cfg); +	if (ret) { +		dev_warn(dev, "dmaengine_slave_config failed %d\n", ret); +		dma_release_channel(chan); +		return NULL;  	} +	return chan; +} + +static int rspi_request_dma(struct device *dev, struct spi_master *master, +			    const struct resource *res) +{ +	const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev); + +	if (!rspi_pd || !rspi_pd->dma_rx_id || !rspi_pd->dma_tx_id) +		return 0;	/* The driver assumes no error. */ + +	master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, +					       rspi_pd->dma_rx_id, +					       res->start + RSPI_SPDR); +	if (!master->dma_rx) +		return -ENODEV; + +	master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, +					       rspi_pd->dma_tx_id, +					       res->start + RSPI_SPDR); +	if (!master->dma_tx) { +		dma_release_channel(master->dma_rx); +		master->dma_rx = NULL; +		return -ENODEV; +	} + +	master->can_dma = rspi_can_dma; +	dev_info(dev, "DMA available");  	return 0;  }  static void rspi_release_dma(struct rspi_data *rspi)  { -	if (rspi->chan_tx) -		dma_release_channel(rspi->chan_tx); -	if (rspi->chan_rx) -		dma_release_channel(rspi->chan_rx); +	if (rspi->master->dma_tx) +		dma_release_channel(rspi->master->dma_tx); +	if (rspi->master->dma_rx) +		dma_release_channel(rspi->master->dma_rx);  }  static int rspi_remove(struct platform_device *pdev)  { -	struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev)); +	struct rspi_data *rspi = platform_get_drvdata(pdev); -	spi_unregister_master(rspi->master);  	rspi_release_dma(rspi); -	free_irq(platform_get_irq(pdev, 0), rspi); -	clk_put(rspi->clk); -	iounmap(rspi->addr); -	spi_master_put(rspi->master); +	pm_runtime_disable(&pdev->dev);  	return 0;  } +static const struct spi_ops rspi_ops = { +	.set_config_register =	rspi_set_config_register, +	.transfer_one =		rspi_transfer_one, +	.mode_bits =		SPI_CPHA | SPI_CPOL | SPI_LOOP, +	.flags =		SPI_MASTER_MUST_TX, +	.fifo_size =		8, +}; + +static const struct spi_ops rspi_rz_ops = { +	.set_config_register =	rspi_rz_set_config_register, +	.transfer_one =		rspi_rz_transfer_one, +	.mode_bits =		SPI_CPHA | SPI_CPOL | SPI_LOOP, +	.flags =		SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX, +	.fifo_size =		8,	/* 8 for TX, 32 for RX */ +}; + +static const struct spi_ops qspi_ops = { +	.set_config_register =	qspi_set_config_register, +	.transfer_one =		qspi_transfer_one, +	.mode_bits =		SPI_CPHA | SPI_CPOL | SPI_LOOP | +				SPI_TX_DUAL | SPI_TX_QUAD | +				SPI_RX_DUAL | SPI_RX_QUAD, +	.flags =		SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX, +	.fifo_size =		32, +}; + +#ifdef CONFIG_OF +static const struct of_device_id rspi_of_match[] = { +	/* RSPI on legacy SH */ +	{ .compatible = "renesas,rspi", .data = &rspi_ops }, +	/* RSPI on RZ/A1H */ +	{ .compatible = "renesas,rspi-rz", .data = &rspi_rz_ops }, +	/* QSPI on R-Car Gen2 */ +	{ .compatible = "renesas,qspi", .data = &qspi_ops }, +	{ /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, rspi_of_match); + +static int rspi_parse_dt(struct device *dev, struct spi_master *master) +{ +	u32 num_cs; +	int error; + +	/* Parse DT properties */ +	error = of_property_read_u32(dev->of_node, "num-cs", &num_cs); +	if (error) { +		dev_err(dev, "of_property_read_u32 num-cs failed %d\n", error); +		return error; +	} + +	master->num_chipselect = num_cs; +	return 0; +} +#else +#define rspi_of_match	NULL +static inline int rspi_parse_dt(struct device *dev, struct spi_master *master) +{ +	return -EINVAL; +} +#endif /* CONFIG_OF */ + +static int rspi_request_irq(struct device *dev, unsigned int irq, +			    irq_handler_t handler, const char *suffix, +			    void *dev_id) +{ +	const char *base = dev_name(dev); +	size_t len = strlen(base) + strlen(suffix) + 2; +	char *name = devm_kzalloc(dev, len, GFP_KERNEL); +	if (!name) +		return -ENOMEM; +	snprintf(name, len, "%s:%s", base, suffix); +	return devm_request_irq(dev, irq, handler, 0, name, dev_id); +} +  static int rspi_probe(struct platform_device *pdev)  {  	struct resource *res;  	struct spi_master *master;  	struct rspi_data *rspi; -	int ret, irq; -	char clk_name[16]; - -	/* get base addr */ -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (unlikely(res == NULL)) { -		dev_err(&pdev->dev, "invalid resource\n"); -		return -EINVAL; -	} - -	irq = platform_get_irq(pdev, 0); -	if (irq < 0) { -		dev_err(&pdev->dev, "platform_get_irq error\n"); -		return -ENODEV; -	} +	int ret; +	const struct of_device_id *of_id; +	const struct rspi_plat_data *rspi_pd; +	const struct spi_ops *ops;  	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));  	if (master == NULL) { @@ -765,79 +1036,137 @@ static int rspi_probe(struct platform_device *pdev)  		return -ENOMEM;  	} +	of_id = of_match_device(rspi_of_match, &pdev->dev); +	if (of_id) { +		ops = of_id->data; +		ret = rspi_parse_dt(&pdev->dev, master); +		if (ret) +			goto error1; +	} else { +		ops = (struct spi_ops *)pdev->id_entry->driver_data; +		rspi_pd = dev_get_platdata(&pdev->dev); +		if (rspi_pd && rspi_pd->num_chipselect) +			master->num_chipselect = rspi_pd->num_chipselect; +		else +			master->num_chipselect = 2; /* default */ +	}; + +	/* ops parameter check */ +	if (!ops->set_config_register) { +		dev_err(&pdev->dev, "there is no set_config_register\n"); +		ret = -ENODEV; +		goto error1; +	} +  	rspi = spi_master_get_devdata(master);  	platform_set_drvdata(pdev, rspi); - +	rspi->ops = ops;  	rspi->master = master; -	rspi->addr = ioremap(res->start, resource_size(res)); -	if (rspi->addr == NULL) { -		dev_err(&pdev->dev, "ioremap error.\n"); -		ret = -ENOMEM; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	rspi->addr = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(rspi->addr)) { +		ret = PTR_ERR(rspi->addr);  		goto error1;  	} -	snprintf(clk_name, sizeof(clk_name), "rspi%d", pdev->id); -	rspi->clk = clk_get(&pdev->dev, clk_name); +	rspi->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(rspi->clk)) {  		dev_err(&pdev->dev, "cannot get clock\n");  		ret = PTR_ERR(rspi->clk); -		goto error2; +		goto error1;  	} -	clk_enable(rspi->clk); -	INIT_LIST_HEAD(&rspi->queue); -	spin_lock_init(&rspi->lock); -	INIT_WORK(&rspi->ws, rspi_work); +	pm_runtime_enable(&pdev->dev); +  	init_waitqueue_head(&rspi->wait); -	master->num_chipselect = 2;  	master->bus_num = pdev->id;  	master->setup = rspi_setup; -	master->transfer = rspi_transfer; -	master->cleanup = rspi_cleanup; - -	ret = request_irq(irq, rspi_irq, 0, dev_name(&pdev->dev), rspi); +	master->auto_runtime_pm = true; +	master->transfer_one = ops->transfer_one; +	master->prepare_message = rspi_prepare_message; +	master->unprepare_message = rspi_unprepare_message; +	master->mode_bits = ops->mode_bits; +	master->flags = ops->flags; +	master->dev.of_node = pdev->dev.of_node; + +	ret = platform_get_irq_byname(pdev, "rx");  	if (ret < 0) { -		dev_err(&pdev->dev, "request_irq error\n"); -		goto error3; +		ret = platform_get_irq_byname(pdev, "mux"); +		if (ret < 0) +			ret = platform_get_irq(pdev, 0); +		if (ret >= 0) +			rspi->rx_irq = rspi->tx_irq = ret; +	} else { +		rspi->rx_irq = ret; +		ret = platform_get_irq_byname(pdev, "tx"); +		if (ret >= 0) +			rspi->tx_irq = ret; +	} +	if (ret < 0) { +		dev_err(&pdev->dev, "platform_get_irq error\n"); +		goto error2;  	} -	rspi->irq = irq; -	ret = rspi_request_dma(rspi, pdev); +	if (rspi->rx_irq == rspi->tx_irq) { +		/* Single multiplexed interrupt */ +		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux, +				       "mux", rspi); +	} else { +		/* Multi-interrupt mode, only SPRI and SPTI are used */ +		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx, +				       "rx", rspi); +		if (!ret) +			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq, +					       rspi_irq_tx, "tx", rspi); +	}  	if (ret < 0) { -		dev_err(&pdev->dev, "rspi_request_dma failed.\n"); -		goto error4; +		dev_err(&pdev->dev, "request_irq error\n"); +		goto error2;  	} -	ret = spi_register_master(master); +	ret = rspi_request_dma(&pdev->dev, master, res); +	if (ret < 0) +		dev_warn(&pdev->dev, "DMA not available, using PIO\n"); + +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret < 0) {  		dev_err(&pdev->dev, "spi_register_master error.\n"); -		goto error4; +		goto error3;  	}  	dev_info(&pdev->dev, "probed\n");  	return 0; -error4: -	rspi_release_dma(rspi); -	free_irq(irq, rspi);  error3: -	clk_put(rspi->clk); +	rspi_release_dma(rspi);  error2: -	iounmap(rspi->addr); +	pm_runtime_disable(&pdev->dev);  error1:  	spi_master_put(master);  	return ret;  } +static struct platform_device_id spi_driver_ids[] = { +	{ "rspi",	(kernel_ulong_t)&rspi_ops }, +	{ "rspi-rz",	(kernel_ulong_t)&rspi_rz_ops }, +	{ "qspi",	(kernel_ulong_t)&qspi_ops }, +	{}, +}; + +MODULE_DEVICE_TABLE(platform, spi_driver_ids); +  static struct platform_driver rspi_driver = {  	.probe =	rspi_probe,  	.remove =	rspi_remove, +	.id_table =	spi_driver_ids,  	.driver		= { -		.name = "rspi", +		.name = "renesas_spi",  		.owner	= THIS_MODULE, +		.of_match_table = of_match_ptr(rspi_of_match),  	},  };  module_platform_driver(rspi_driver); diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index ce318d95a6e..e713737d784 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -9,9 +9,7 @@   *  */ -#include <linux/init.h>  #include <linux/spinlock.h> -#include <linux/workqueue.h>  #include <linux/interrupt.h>  #include <linux/delay.h>  #include <linux/errno.h> @@ -29,7 +27,6 @@  #include <plat/regs-spi.h> -#include <plat/fiq.h>  #include <asm/fiq.h>  #include "spi-s3c24xx-fiq.h" @@ -78,14 +75,12 @@ struct s3c24xx_spi {  	unsigned char		*rx;  	struct clk		*clk; -	struct resource		*ioarea;  	struct spi_master	*master;  	struct spi_device	*curdev;  	struct device		*dev;  	struct s3c2410_spi_info *pdata;  }; -  #define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)  #define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) @@ -126,25 +121,15 @@ static int s3c24xx_spi_update_state(struct spi_device *spi,  {  	struct s3c24xx_spi *hw = to_hw(spi);  	struct s3c24xx_spi_devstate *cs = spi->controller_state; -	unsigned int bpw;  	unsigned int hz;  	unsigned int div;  	unsigned long clk; -	bpw = t ? t->bits_per_word : spi->bits_per_word;  	hz  = t ? t->speed_hz : spi->max_speed_hz; -	if (!bpw) -		bpw = 8; -  	if (!hz)  		hz = spi->max_speed_hz; -	if (bpw != 8) { -		dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); -		return -EINVAL; -	} -  	if (spi->mode != cs->mode) {  		u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK; @@ -197,11 +182,11 @@ static int s3c24xx_spi_setup(struct spi_device *spi)  	/* allocate settings on the first call */  	if (!cs) { -		cs = kzalloc(sizeof(struct s3c24xx_spi_devstate), GFP_KERNEL); -		if (!cs) { -			dev_err(&spi->dev, "no memory for controller state\n"); +		cs = devm_kzalloc(&spi->dev, +				  sizeof(struct s3c24xx_spi_devstate), +				  GFP_KERNEL); +		if (!cs)  			return -ENOMEM; -		}  		cs->spcon = SPCON_DEFAULT;  		cs->hz = -1; @@ -223,11 +208,6 @@ static int s3c24xx_spi_setup(struct spi_device *spi)  	return 0;  } -static void s3c24xx_spi_cleanup(struct spi_device *spi) -{ -	kfree(spi->controller_state); -} -  static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)  {  	return hw->tx ? hw->tx[count] : 0; @@ -280,7 +260,7 @@ static inline u32 ack_bit(unsigned int irq)   * so the caller does not need to do anything more than start the transfer   * as normal, since the IRQ will have been re-routed to the FIQ handler.  */ -void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) +static void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)  {  	struct pt_regs regs;  	enum spi_fiq_mode mode; @@ -517,14 +497,13 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)  	master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));  	if (master == NULL) {  		dev_err(&pdev->dev, "No memory for spi_master\n"); -		err = -ENOMEM; -		goto err_nomem; +		return -ENOMEM;  	}  	hw = spi_master_get_devdata(master);  	memset(hw, 0, sizeof(struct s3c24xx_spi)); -	hw->master = spi_master_get(master); +	hw->master = master;  	hw->pdata = pdata = dev_get_platdata(&pdev->dev);  	hw->dev = &pdev->dev; @@ -548,6 +527,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)  	master->num_chipselect = hw->pdata->num_cs;  	master->bus_num = pdata->bus_num; +	master->bits_per_word_mask = SPI_BPW_MASK(8);  	/* setup the state for the bitbang driver */ @@ -557,53 +537,36 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)  	hw->bitbang.txrx_bufs      = s3c24xx_spi_txrx;  	hw->master->setup  = s3c24xx_spi_setup; -	hw->master->cleanup = s3c24xx_spi_cleanup;  	dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);  	/* find and map our resources */ -  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (res == NULL) { -		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); -		err = -ENOENT; -		goto err_no_iores; -	} - -	hw->ioarea = request_mem_region(res->start, resource_size(res), -					pdev->name); - -	if (hw->ioarea == NULL) { -		dev_err(&pdev->dev, "Cannot reserve region\n"); -		err = -ENXIO; -		goto err_no_iores; -	} - -	hw->regs = ioremap(res->start, resource_size(res)); -	if (hw->regs == NULL) { -		dev_err(&pdev->dev, "Cannot map IO\n"); -		err = -ENXIO; -		goto err_no_iomap; +	hw->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hw->regs)) { +		err = PTR_ERR(hw->regs); +		goto err_no_pdata;  	}  	hw->irq = platform_get_irq(pdev, 0);  	if (hw->irq < 0) {  		dev_err(&pdev->dev, "No IRQ specified\n");  		err = -ENOENT; -		goto err_no_irq; +		goto err_no_pdata;  	} -	err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); +	err = devm_request_irq(&pdev->dev, hw->irq, s3c24xx_spi_irq, 0, +				pdev->name, hw);  	if (err) {  		dev_err(&pdev->dev, "Cannot claim IRQ\n"); -		goto err_no_irq; +		goto err_no_pdata;  	} -	hw->clk = clk_get(&pdev->dev, "spi"); +	hw->clk = devm_clk_get(&pdev->dev, "spi");  	if (IS_ERR(hw->clk)) {  		dev_err(&pdev->dev, "No clock for device\n");  		err = PTR_ERR(hw->clk); -		goto err_no_clk; +		goto err_no_pdata;  	}  	/* setup any gpio we can */ @@ -615,7 +578,8 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)  			goto err_register;  		} -		err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); +		err = devm_gpio_request(&pdev->dev, pdata->pin_cs, +					dev_name(&pdev->dev));  		if (err) {  			dev_err(&pdev->dev, "Failed to get gpio for cs\n");  			goto err_register; @@ -639,27 +603,10 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)  	return 0;   err_register: -	if (hw->set_cs == s3c24xx_spi_gpiocs) -		gpio_free(pdata->pin_cs); -  	clk_disable(hw->clk); -	clk_put(hw->clk); - - err_no_clk: -	free_irq(hw->irq, hw); - - err_no_irq: -	iounmap(hw->regs); - err_no_iomap: -	release_resource(hw->ioarea); -	kfree(hw->ioarea); - - err_no_iores:   err_no_pdata:  	spi_master_put(hw->master); - - err_nomem:  	return err;  } @@ -668,19 +615,7 @@ static int s3c24xx_spi_remove(struct platform_device *dev)  	struct s3c24xx_spi *hw = platform_get_drvdata(dev);  	spi_bitbang_stop(&hw->bitbang); -  	clk_disable(hw->clk); -	clk_put(hw->clk); - -	free_irq(hw->irq, hw); -	iounmap(hw->regs); - -	if (hw->set_cs == s3c24xx_spi_gpiocs) -		gpio_free(hw->pdata->pin_cs); - -	release_resource(hw->ioarea); -	kfree(hw->ioarea); -  	spi_master_put(hw->master);  	return 0;  } @@ -691,6 +626,11 @@ static int s3c24xx_spi_remove(struct platform_device *dev)  static int s3c24xx_spi_suspend(struct device *dev)  {  	struct s3c24xx_spi *hw = dev_get_drvdata(dev); +	int ret; + +	ret = spi_master_suspend(hw->master); +	if (ret) +		return ret;  	if (hw->pdata && hw->pdata->gpio_setup)  		hw->pdata->gpio_setup(hw->pdata, 0); @@ -704,7 +644,7 @@ static int s3c24xx_spi_resume(struct device *dev)  	struct s3c24xx_spi *hw = dev_get_drvdata(dev);  	s3c24xx_spi_initialsetup(hw); -	return 0; +	return spi_master_resume(hw->master);  }  static const struct dev_pm_ops s3c24xx_spi_pmops = { diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 512b8893893..75a56968b14 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -19,7 +19,6 @@  #include <linux/init.h>  #include <linux/module.h> -#include <linux/workqueue.h>  #include <linux/interrupt.h>  #include <linux/delay.h>  #include <linux/clk.h> @@ -34,10 +33,6 @@  #include <linux/platform_data/spi-s3c64xx.h> -#ifdef CONFIG_S3C_DMA -#include <mach/dma.h> -#endif -  #define MAX_SPI_PORTS		3  #define S3C64XX_SPI_QUIRK_POLL		(1 << 0) @@ -200,12 +195,8 @@ struct s3c64xx_spi_driver_data {  	unsigned                        cur_speed;  	struct s3c64xx_spi_dma_data	rx_dma;  	struct s3c64xx_spi_dma_data	tx_dma; -#ifdef CONFIG_S3C_DMA -	struct samsung_dma_ops		*ops; -#endif  	struct s3c64xx_spi_port_config	*port_conf;  	unsigned int			port_id; -	unsigned long			gpios[4];  	bool				cs_gpio;  }; @@ -285,104 +276,8 @@ static void s3c64xx_spi_dmacb(void *data)  	spin_unlock_irqrestore(&sdd->lock, flags);  } -#ifdef CONFIG_S3C_DMA -/* FIXME: remove this section once arch/arm/mach-s3c64xx uses dmaengine */ - -static struct s3c2410_dma_client s3c64xx_spi_dma_client = { -	.name = "samsung-spi-dma", -}; -  static void prepare_dma(struct s3c64xx_spi_dma_data *dma, -					unsigned len, dma_addr_t buf) -{ -	struct s3c64xx_spi_driver_data *sdd; -	struct samsung_dma_prep info; -	struct samsung_dma_config config; - -	if (dma->direction == DMA_DEV_TO_MEM) { -		sdd = container_of((void *)dma, -			struct s3c64xx_spi_driver_data, rx_dma); -		config.direction = sdd->rx_dma.direction; -		config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; -		config.width = sdd->cur_bpw / 8; -		sdd->ops->config((enum dma_ch)sdd->rx_dma.ch, &config); -	} else { -		sdd = container_of((void *)dma, -			struct s3c64xx_spi_driver_data, tx_dma); -		config.direction =  sdd->tx_dma.direction; -		config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; -		config.width = sdd->cur_bpw / 8; -		sdd->ops->config((enum dma_ch)sdd->tx_dma.ch, &config); -	} - -	info.cap = DMA_SLAVE; -	info.len = len; -	info.fp = s3c64xx_spi_dmacb; -	info.fp_param = dma; -	info.direction = dma->direction; -	info.buf = buf; - -	sdd->ops->prepare((enum dma_ch)dma->ch, &info); -	sdd->ops->trigger((enum dma_ch)dma->ch); -} - -static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) -{ -	struct samsung_dma_req req; -	struct device *dev = &sdd->pdev->dev; - -	sdd->ops = samsung_dma_get_ops(); - -	req.cap = DMA_SLAVE; -	req.client = &s3c64xx_spi_dma_client; - -	sdd->rx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( -					sdd->rx_dma.dmach, &req, dev, "rx"); -	sdd->tx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( -					sdd->tx_dma.dmach, &req, dev, "tx"); - -	return 1; -} - -static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) -{ -	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); - -	/* -	 * If DMA resource was not available during -	 * probe, no need to continue with dma requests -	 * else Acquire DMA channels -	 */ -	while (!is_polling(sdd) && !acquire_dma(sdd)) -		usleep_range(10000, 11000); - -	return 0; -} - -static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) -{ -	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); - -	/* Free DMA channels */ -	if (!is_polling(sdd)) { -		sdd->ops->release((enum dma_ch)sdd->rx_dma.ch, -					&s3c64xx_spi_dma_client); -		sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, -					&s3c64xx_spi_dma_client); -	} - -	return 0; -} - -static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, -				 struct s3c64xx_spi_dma_data *dma) -{ -	sdd->ops->stop((enum dma_ch)dma->ch); -} -#else - -static void prepare_dma(struct s3c64xx_spi_dma_data *dma, -					unsigned len, dma_addr_t buf) +			struct sg_table *sgt)  {  	struct s3c64xx_spi_driver_data *sdd;  	struct dma_slave_config config; @@ -408,8 +303,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,  		dmaengine_slave_config(dma->ch, &config);  	} -	desc = dmaengine_prep_slave_single(dma->ch, buf, len, -					dma->direction, DMA_PREP_INTERRUPT); +	desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, +				       dma->direction, DMA_PREP_INTERRUPT);  	desc->callback = s3c64xx_spi_dmacb;  	desc->callback_param = dma; @@ -438,6 +333,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)  			ret = -EBUSY;  			goto out;  		} +		spi->dma_rx = sdd->rx_dma.ch;  		sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter,  				   (void *)sdd->tx_dma.dmach, dev, "tx"); @@ -446,6 +342,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)  			ret = -EBUSY;  			goto out_rx;  		} +		spi->dma_tx = sdd->tx_dma.ch;  	}  	ret = pm_runtime_get_sync(&sdd->pdev->dev); @@ -478,12 +375,14 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)  	return 0;  } -static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, -				 struct s3c64xx_spi_dma_data *dma) +static bool s3c64xx_spi_can_dma(struct spi_master *master, +				struct spi_device *spi, +				struct spi_transfer *xfer)  { -	dmaengine_terminate_all(dma->ch); +	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + +	return xfer->len > (FIFO_LVL_MASK(sdd) >> 1) + 1;  } -#endif  static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,  				struct spi_device *spi, @@ -516,7 +415,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,  		chcfg |= S3C64XX_SPI_CH_TXCH_ON;  		if (dma_mode) {  			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; -			prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma); +			prepare_dma(&sdd->tx_dma, &xfer->tx_sg);  		} else {  			switch (sdd->cur_bpw) {  			case 32: @@ -548,7 +447,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,  			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)  					| S3C64XX_SPI_PACKET_CNT_EN,  					regs + S3C64XX_SPI_PACKET_CNT); -			prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma); +			prepare_dma(&sdd->rx_dma, &xfer->rx_sg);  		}  	} @@ -556,30 +455,6 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,  	writel(chcfg, regs + S3C64XX_SPI_CH_CFG);  } -static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, -						struct spi_device *spi) -{ -	struct s3c64xx_spi_csinfo *cs; - -	if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ -		if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ -			/* Deselect the last toggled device */ -			cs = sdd->tgl_spi->controller_data; -			if (sdd->cs_gpio) -				gpio_set_value(cs->line, -					spi->mode & SPI_CS_HIGH ? 0 : 1); -		} -		sdd->tgl_spi = NULL; -	} - -	cs = spi->controller_data; -	if (sdd->cs_gpio) -		gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); - -	/* Start the signals */ -	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); -} -  static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,  					int timeout_ms)  { @@ -601,117 +476,111 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,  	return RX_FIFO_LVL(status, sdd);  } -static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, -				struct spi_transfer *xfer, int dma_mode) +static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd, +			struct spi_transfer *xfer)  {  	void __iomem *regs = sdd->regs;  	unsigned long val; +	u32 status;  	int ms;  	/* millisecs to xfer 'len' bytes @ 'cur_speed' */  	ms = xfer->len * 8 * 1000 / sdd->cur_speed;  	ms += 10; /* some tolerance */ -	if (dma_mode) { -		val = msecs_to_jiffies(ms) + 10; -		val = wait_for_completion_timeout(&sdd->xfer_completion, val); -	} else { -		u32 status; -		val = msecs_to_loops(ms); -		do { -			status = readl(regs + S3C64XX_SPI_STATUS); -		} while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); -	} +	val = msecs_to_jiffies(ms) + 10; +	val = wait_for_completion_timeout(&sdd->xfer_completion, val); -	if (dma_mode) { -		u32 status; - -		/* -		 * If the previous xfer was completed within timeout, then -		 * proceed further else return -EIO. -		 * DmaTx returns after simply writing data in the FIFO, -		 * w/o waiting for real transmission on the bus to finish. -		 * DmaRx returns only after Dma read data from FIFO which -		 * needs bus transmission to finish, so we don't worry if -		 * Xfer involved Rx(with or without Tx). -		 */ -		if (val && !xfer->rx_buf) { -			val = msecs_to_loops(10); +	/* +	 * If the previous xfer was completed within timeout, then +	 * proceed further else return -EIO. +	 * DmaTx returns after simply writing data in the FIFO, +	 * w/o waiting for real transmission on the bus to finish. +	 * DmaRx returns only after Dma read data from FIFO which +	 * needs bus transmission to finish, so we don't worry if +	 * Xfer involved Rx(with or without Tx). +	 */ +	if (val && !xfer->rx_buf) { +		val = msecs_to_loops(10); +		status = readl(regs + S3C64XX_SPI_STATUS); +		while ((TX_FIFO_LVL(status, sdd) +			|| !S3C64XX_SPI_ST_TX_DONE(status, sdd)) +		       && --val) { +			cpu_relax();  			status = readl(regs + S3C64XX_SPI_STATUS); -			while ((TX_FIFO_LVL(status, sdd) -				|| !S3C64XX_SPI_ST_TX_DONE(status, sdd)) -					&& --val) { -				cpu_relax(); -				status = readl(regs + S3C64XX_SPI_STATUS); -			} - -		} - -		/* If timed out while checking rx/tx status return error */ -		if (!val) -			return -EIO; -	} else { -		int loops; -		u32 cpy_len; -		u8 *buf; - -		/* If it was only Tx */ -		if (!xfer->rx_buf) { -			sdd->state &= ~TXBUSY; -			return 0;  		} -		/* -		 * If the receive length is bigger than the controller fifo -		 * size, calculate the loops and read the fifo as many times. -		 * loops = length / max fifo size (calculated by using the -		 * fifo mask). -		 * For any size less than the fifo size the below code is -		 * executed atleast once. -		 */ -		loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1); -		buf = xfer->rx_buf; -		do { -			/* wait for data to be received in the fifo */ -			cpy_len = s3c64xx_spi_wait_for_timeout(sdd, -						(loops ? ms : 0)); - -			switch (sdd->cur_bpw) { -			case 32: -				ioread32_rep(regs + S3C64XX_SPI_RX_DATA, -					buf, cpy_len / 4); -				break; -			case 16: -				ioread16_rep(regs + S3C64XX_SPI_RX_DATA, -					buf, cpy_len / 2); -				break; -			default: -				ioread8_rep(regs + S3C64XX_SPI_RX_DATA, -					buf, cpy_len); -				break; -			} - -			buf = buf + cpy_len; -		} while (loops--); -		sdd->state &= ~RXBUSY;  	} +	/* If timed out while checking rx/tx status return error */ +	if (!val) +		return -EIO; +  	return 0;  } -static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, -						struct spi_device *spi) +static int wait_for_pio(struct s3c64xx_spi_driver_data *sdd, +			struct spi_transfer *xfer)  { -	struct s3c64xx_spi_csinfo *cs = spi->controller_data; +	void __iomem *regs = sdd->regs; +	unsigned long val; +	u32 status; +	int loops; +	u32 cpy_len; +	u8 *buf; +	int ms; -	if (sdd->tgl_spi == spi) -		sdd->tgl_spi = NULL; +	/* millisecs to xfer 'len' bytes @ 'cur_speed' */ +	ms = xfer->len * 8 * 1000 / sdd->cur_speed; +	ms += 10; /* some tolerance */ -	if (sdd->cs_gpio) -		gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); +	val = msecs_to_loops(ms); +	do { +		status = readl(regs + S3C64XX_SPI_STATUS); +	} while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); -	/* Quiese the signals */ -	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); + +	/* If it was only Tx */ +	if (!xfer->rx_buf) { +		sdd->state &= ~TXBUSY; +		return 0; +	} + +	/* +	 * If the receive length is bigger than the controller fifo +	 * size, calculate the loops and read the fifo as many times. +	 * loops = length / max fifo size (calculated by using the +	 * fifo mask). +	 * For any size less than the fifo size the below code is +	 * executed atleast once. +	 */ +	loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1); +	buf = xfer->rx_buf; +	do { +		/* wait for data to be received in the fifo */ +		cpy_len = s3c64xx_spi_wait_for_timeout(sdd, +						       (loops ? ms : 0)); + +		switch (sdd->cur_bpw) { +		case 32: +			ioread32_rep(regs + S3C64XX_SPI_RX_DATA, +				     buf, cpy_len / 4); +			break; +		case 16: +			ioread16_rep(regs + S3C64XX_SPI_RX_DATA, +				     buf, cpy_len / 2); +			break; +		default: +			ioread8_rep(regs + S3C64XX_SPI_RX_DATA, +				    buf, cpy_len); +			break; +		} + +		buf = buf + cpy_len; +	} while (loops--); +	sdd->state &= ~RXBUSY; + +	return 0;  }  static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) @@ -787,91 +656,12 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)  #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) -static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, -						struct spi_message *msg) -{ -	struct device *dev = &sdd->pdev->dev; -	struct spi_transfer *xfer; - -	if (is_polling(sdd) || msg->is_dma_mapped) -		return 0; - -	/* First mark all xfer unmapped */ -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		xfer->rx_dma = XFER_DMAADDR_INVALID; -		xfer->tx_dma = XFER_DMAADDR_INVALID; -	} - -	/* Map until end or first fail */ -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { - -		if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) -			continue; - -		if (xfer->tx_buf != NULL) { -			xfer->tx_dma = dma_map_single(dev, -					(void *)xfer->tx_buf, xfer->len, -					DMA_TO_DEVICE); -			if (dma_mapping_error(dev, xfer->tx_dma)) { -				dev_err(dev, "dma_map_single Tx failed\n"); -				xfer->tx_dma = XFER_DMAADDR_INVALID; -				return -ENOMEM; -			} -		} - -		if (xfer->rx_buf != NULL) { -			xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, -						xfer->len, DMA_FROM_DEVICE); -			if (dma_mapping_error(dev, xfer->rx_dma)) { -				dev_err(dev, "dma_map_single Rx failed\n"); -				dma_unmap_single(dev, xfer->tx_dma, -						xfer->len, DMA_TO_DEVICE); -				xfer->tx_dma = XFER_DMAADDR_INVALID; -				xfer->rx_dma = XFER_DMAADDR_INVALID; -				return -ENOMEM; -			} -		} -	} - -	return 0; -} - -static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, -						struct spi_message *msg) -{ -	struct device *dev = &sdd->pdev->dev; -	struct spi_transfer *xfer; - -	if (is_polling(sdd) || msg->is_dma_mapped) -		return; - -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { - -		if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) -			continue; - -		if (xfer->rx_buf != NULL -				&& xfer->rx_dma != XFER_DMAADDR_INVALID) -			dma_unmap_single(dev, xfer->rx_dma, -						xfer->len, DMA_FROM_DEVICE); - -		if (xfer->tx_buf != NULL -				&& xfer->tx_dma != XFER_DMAADDR_INVALID) -			dma_unmap_single(dev, xfer->tx_dma, -						xfer->len, DMA_TO_DEVICE); -	} -} - -static int s3c64xx_spi_transfer_one_message(struct spi_master *master, -					    struct spi_message *msg) +static int s3c64xx_spi_prepare_message(struct spi_master *master, +				       struct spi_message *msg)  {  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);  	struct spi_device *spi = msg->spi;  	struct s3c64xx_spi_csinfo *cs = spi->controller_data; -	struct spi_transfer *xfer; -	int status = 0, cs_toggle = 0; -	u32 speed; -	u8 bpw;  	/* If Master's(controller) state differs from that needed by Slave */  	if (sdd->cur_speed != spi->max_speed_hz @@ -883,112 +673,80 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,  		s3c64xx_spi_config(sdd);  	} -	/* Map all the transfers if needed */ -	if (s3c64xx_spi_map_mssg(sdd, msg)) { -		dev_err(&spi->dev, -			"Xfer: Unable to map message buffers!\n"); -		status = -ENOMEM; -		goto out; -	} -  	/* Configure feedback delay */  	writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { - -		unsigned long flags; -		int use_dma; - -		INIT_COMPLETION(sdd->xfer_completion); - -		/* Only BPW and Speed may change across transfers */ -		bpw = xfer->bits_per_word; -		speed = xfer->speed_hz ? : spi->max_speed_hz; - -		if (xfer->len % (bpw / 8)) { -			dev_err(&spi->dev, -				"Xfer length(%u) not a multiple of word size(%u)\n", -				xfer->len, bpw / 8); -			status = -EIO; -			goto out; -		} - -		if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { -			sdd->cur_bpw = bpw; -			sdd->cur_speed = speed; -			s3c64xx_spi_config(sdd); -		} +	return 0; +} -		/* Polling method for xfers not bigger than FIFO capacity */ -		use_dma = 0; -		if (!is_polling(sdd) && -			(sdd->rx_dma.ch && sdd->tx_dma.ch && -			(xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))) -			use_dma = 1; +static int s3c64xx_spi_transfer_one(struct spi_master *master, +				    struct spi_device *spi, +				    struct spi_transfer *xfer) +{ +	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); +	int status; +	u32 speed; +	u8 bpw; +	unsigned long flags; +	int use_dma; -		spin_lock_irqsave(&sdd->lock, flags); +	reinit_completion(&sdd->xfer_completion); -		/* Pending only which is to be done */ -		sdd->state &= ~RXBUSY; -		sdd->state &= ~TXBUSY; +	/* Only BPW and Speed may change across transfers */ +	bpw = xfer->bits_per_word; +	speed = xfer->speed_hz ? : spi->max_speed_hz; -		enable_datapath(sdd, spi, xfer, use_dma); - -		/* Slave Select */ -		enable_cs(sdd, spi); +	if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { +		sdd->cur_bpw = bpw; +		sdd->cur_speed = speed; +		s3c64xx_spi_config(sdd); +	} -		spin_unlock_irqrestore(&sdd->lock, flags); +	/* Polling method for xfers not bigger than FIFO capacity */ +	use_dma = 0; +	if (!is_polling(sdd) && +	    (sdd->rx_dma.ch && sdd->tx_dma.ch && +	     (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))) +		use_dma = 1; -		status = wait_for_xfer(sdd, xfer, use_dma); +	spin_lock_irqsave(&sdd->lock, flags); -		if (status) { -			dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", -				xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, -				(sdd->state & RXBUSY) ? 'f' : 'p', -				(sdd->state & TXBUSY) ? 'f' : 'p', -				xfer->len); +	/* Pending only which is to be done */ +	sdd->state &= ~RXBUSY; +	sdd->state &= ~TXBUSY; -			if (use_dma) { -				if (xfer->tx_buf != NULL -						&& (sdd->state & TXBUSY)) -					s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma); -				if (xfer->rx_buf != NULL -						&& (sdd->state & RXBUSY)) -					s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma); -			} +	enable_datapath(sdd, spi, xfer, use_dma); -			goto out; -		} +	/* Start the signals */ +	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); -		if (xfer->delay_usecs) -			udelay(xfer->delay_usecs); +	spin_unlock_irqrestore(&sdd->lock, flags); -		if (xfer->cs_change) { -			/* Hint that the next mssg is gonna be -			   for the same device */ -			if (list_is_last(&xfer->transfer_list, -						&msg->transfers)) -				cs_toggle = 1; +	if (use_dma) +		status = wait_for_dma(sdd, xfer); +	else +		status = wait_for_pio(sdd, xfer); + +	if (status) { +		dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", +			xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, +			(sdd->state & RXBUSY) ? 'f' : 'p', +			(sdd->state & TXBUSY) ? 'f' : 'p', +			xfer->len); + +		if (use_dma) { +			if (xfer->tx_buf != NULL +			    && (sdd->state & TXBUSY)) +				dmaengine_terminate_all(sdd->tx_dma.ch); +			if (xfer->rx_buf != NULL +			    && (sdd->state & RXBUSY)) +				dmaengine_terminate_all(sdd->rx_dma.ch);  		} - -		msg->actual_length += xfer->len; - +	} else {  		flush_fifo(sdd);  	} -out: -	if (!cs_toggle || status) -		disable_cs(sdd, spi); -	else -		sdd->tgl_spi = spi; - -	s3c64xx_spi_unmap_mssg(sdd, msg); - -	msg->status = status; - -	spi_finalize_current_message(master); - -	return 0; +	return status;  }  static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( @@ -1014,7 +772,6 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(  	cs = kzalloc(sizeof(*cs), GFP_KERNEL);  	if (!cs) { -		dev_err(&spi->dev, "could not allocate memory for controller data\n");  		of_node_put(data_np);  		return ERR_PTR(-ENOMEM);  	} @@ -1071,6 +828,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)  					cs->line, err);  				goto err_gpio_req;  			} + +			spi->cs_gpio = cs->line;  		}  		spi_set_ctldata(spi, cs); @@ -1117,12 +876,13 @@ static int s3c64xx_spi_setup(struct spi_device *spi)  	}  	pm_runtime_put(&sdd->pdev->dev); -	disable_cs(sdd, spi); +	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);  	return 0;  setup_exit: +	pm_runtime_put(&sdd->pdev->dev);  	/* setup() returns with device de-selected */ -	disable_cs(sdd, spi); +	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);  	gpio_free(cs->line);  	spi_set_ctldata(spi, NULL); @@ -1140,8 +900,8 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi)  	struct s3c64xx_spi_driver_data *sdd;  	sdd = spi_master_get_devdata(spi->master); -	if (cs && sdd->cs_gpio) { -		gpio_free(cs->line); +	if (spi->cs_gpio) { +		gpio_free(spi->cs_gpio);  		if (spi->dev.of_node)  			kfree(cs);  	} @@ -1225,10 +985,8 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)  	u32 temp;  	sci = devm_kzalloc(dev, sizeof(*sci), GFP_KERNEL); -	if (!sci) { -		dev_err(dev, "memory allocation for spi_info failed\n"); +	if (!sci)  		return ERR_PTR(-ENOMEM); -	}  	if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {  		dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n"); @@ -1359,7 +1117,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  	master->setup = s3c64xx_spi_setup;  	master->cleanup = s3c64xx_spi_cleanup;  	master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; -	master->transfer_one_message = s3c64xx_spi_transfer_one_message; +	master->prepare_message = s3c64xx_spi_prepare_message; +	master->transfer_one = s3c64xx_spi_transfer_one;  	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;  	master->num_chipselect = sci->num_cs;  	master->dma_alignment = 8; @@ -1368,6 +1127,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  	/* the spi->mode bits understood by this driver: */  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;  	master->auto_runtime_pm = true; +	if (!is_polling(sdd)) +		master->can_dma = s3c64xx_spi_can_dma;  	sdd->regs = devm_ioremap_resource(&pdev->dev, mem_res);  	if (IS_ERR(sdd->regs)) { @@ -1428,9 +1189,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  	       S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,  	       sdd->regs + S3C64XX_SPI_INT_EN); -	if (spi_register_master(master)) { -		dev_err(&pdev->dev, "cannot register SPI master\n"); -		ret = -EBUSY; +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_enable(&pdev->dev); + +	ret = devm_spi_register_master(&pdev->dev, master); +	if (ret != 0) { +		dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret);  		goto err3;  	} @@ -1440,8 +1204,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  					mem_res,  					sdd->rx_dma.dmach, sdd->tx_dma.dmach); -	pm_runtime_enable(&pdev->dev); -  	return 0;  err3: @@ -1461,16 +1223,12 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)  	pm_runtime_disable(&pdev->dev); -	spi_unregister_master(master); -  	writel(0, sdd->regs + S3C64XX_SPI_INT_EN);  	clk_disable_unprepare(sdd->src_clk);  	clk_disable_unprepare(sdd->clk); -	spi_master_put(master); -  	return 0;  } @@ -1480,11 +1238,14 @@ static int s3c64xx_spi_suspend(struct device *dev)  	struct spi_master *master = dev_get_drvdata(dev);  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); -	spi_master_suspend(master); +	int ret = spi_master_suspend(master); +	if (ret) +		return ret; -	/* Disable the clock */ -	clk_disable_unprepare(sdd->src_clk); -	clk_disable_unprepare(sdd->clk); +	if (!pm_runtime_suspended(dev)) { +		clk_disable_unprepare(sdd->clk); +		clk_disable_unprepare(sdd->src_clk); +	}  	sdd->cur_speed = 0; /* Output Clock is stopped */ @@ -1500,15 +1261,14 @@ static int s3c64xx_spi_resume(struct device *dev)  	if (sci->cfg_gpio)  		sci->cfg_gpio(); -	/* Enable the clock */ -	clk_prepare_enable(sdd->src_clk); -	clk_prepare_enable(sdd->clk); +	if (!pm_runtime_suspended(dev)) { +		clk_prepare_enable(sdd->src_clk); +		clk_prepare_enable(sdd->clk); +	}  	s3c64xx_spi_hwinit(sdd, sdd->port_id); -	spi_master_resume(master); - -	return 0; +	return spi_master_resume(master);  }  #endif /* CONFIG_PM_SLEEP */ @@ -1528,9 +1288,17 @@ static int s3c64xx_spi_runtime_resume(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev);  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); +	int ret; -	clk_prepare_enable(sdd->src_clk); -	clk_prepare_enable(sdd->clk); +	ret = clk_prepare_enable(sdd->src_clk); +	if (ret != 0) +		return ret; + +	ret = clk_prepare_enable(sdd->clk); +	if (ret != 0) { +		clk_disable_unprepare(sdd->src_clk); +		return ret; +	}  	return 0;  } @@ -1616,6 +1384,18 @@ static struct platform_device_id s3c64xx_spi_driver_ids[] = {  };  static const struct of_device_id s3c64xx_spi_dt_match[] = { +	{ .compatible = "samsung,s3c2443-spi", +			.data = (void *)&s3c2443_spi_port_config, +	}, +	{ .compatible = "samsung,s3c6410-spi", +			.data = (void *)&s3c6410_spi_port_config, +	}, +	{ .compatible = "samsung,s5pc100-spi", +			.data = (void *)&s5pc100_spi_port_config, +	}, +	{ .compatible = "samsung,s5pv210-spi", +			.data = (void *)&s5pv210_spi_port_config, +	},  	{ .compatible = "samsung,exynos4210-spi",  			.data = (void *)&exynos4_spi_port_config,  	}, @@ -1633,22 +1413,13 @@ static struct platform_driver s3c64xx_spi_driver = {  		.pm = &s3c64xx_spi_pm,  		.of_match_table = of_match_ptr(s3c64xx_spi_dt_match),  	}, +	.probe = s3c64xx_spi_probe,  	.remove = s3c64xx_spi_remove,  	.id_table = s3c64xx_spi_driver_ids,  };  MODULE_ALIAS("platform:s3c64xx-spi"); -static int __init s3c64xx_spi_init(void) -{ -	return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); -} -subsys_initcall(s3c64xx_spi_init); - -static void __exit s3c64xx_spi_exit(void) -{ -	platform_driver_unregister(&s3c64xx_spi_driver); -} -module_exit(s3c64xx_spi_exit); +module_platform_driver(s3c64xx_spi_driver);  MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");  MODULE_DESCRIPTION("S3C64XX SPI Controller Driver"); diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c index 9eda21d739c..237f2e7a717 100644 --- a/drivers/spi/spi-sc18is602.c +++ b/drivers/spi/spi-sc18is602.c @@ -183,24 +183,9 @@ static int sc18is602_setup_transfer(struct sc18is602 *hw, u32 hz, u8 mode)  static int sc18is602_check_transfer(struct spi_device *spi,  				    struct spi_transfer *t, int tlen)  { -	int bpw; -	uint32_t hz; -  	if (t && t->len + tlen > SC18IS602_BUFSIZ)  		return -EINVAL; -	bpw = spi->bits_per_word; -	if (t && t->bits_per_word) -		bpw = t->bits_per_word; -	if (bpw != 8) -		return -EINVAL; - -	hz = spi->max_speed_hz; -	if (t && t->speed_hz) -		hz = t->speed_hz; -	if (hz == 0) -		return -EINVAL; -  	return 0;  } @@ -212,22 +197,15 @@ static int sc18is602_transfer_one(struct spi_master *master,  	struct spi_transfer *t;  	int status = 0; -	/* SC18IS602 does not support CS2 */ -	if (hw->id == sc18is602 && spi->chip_select == 2) { -		status = -ENXIO; -		goto error; -	} -  	hw->tlen = 0;  	list_for_each_entry(t, &m->transfers, transfer_list) { -		u32 hz = t->speed_hz ? : spi->max_speed_hz;  		bool do_transfer;  		status = sc18is602_check_transfer(spi, t, hw->tlen);  		if (status < 0)  			break; -		status = sc18is602_setup_transfer(hw, hz, spi->mode); +		status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode);  		if (status < 0)  			break; @@ -245,7 +223,6 @@ static int sc18is602_transfer_one(struct spi_master *master,  		if (t->delay_usecs)  			udelay(t->delay_usecs);  	} -error:  	m->status = status;  	spi_finalize_current_message(master); @@ -254,13 +231,13 @@ error:  static int sc18is602_setup(struct spi_device *spi)  { -	if (!spi->bits_per_word) -		spi->bits_per_word = 8; +	struct sc18is602 *hw = spi_master_get_devdata(spi->master); -	if (spi->mode & ~(SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST)) -		return -EINVAL; +	/* SC18IS602 does not support CS2 */ +	if (hw->id == sc18is602 && spi->chip_select == 2) +		return -ENXIO; -	return sc18is602_check_transfer(spi, NULL, 0); +	return 0;  }  static int sc18is602_probe(struct i2c_client *client, @@ -315,11 +292,14 @@ static int sc18is602_probe(struct i2c_client *client,  	}  	master->bus_num = client->adapter->nr;  	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; +	master->bits_per_word_mask = SPI_BPW_MASK(8);  	master->setup = sc18is602_setup;  	master->transfer_one_message = sc18is602_transfer_one;  	master->dev.of_node = np; +	master->min_speed_hz = hw->freq / 128; +	master->max_speed_hz = hw->freq / 4; -	error = spi_register_master(master); +	error = devm_spi_register_master(dev, master);  	if (error)  		goto error_reg; @@ -330,16 +310,6 @@ error_reg:  	return error;  } -static int sc18is602_remove(struct i2c_client *client) -{ -	struct sc18is602 *hw = i2c_get_clientdata(client); -	struct spi_master *master = hw->master; - -	spi_unregister_master(master); - -	return 0; -} -  static const struct i2c_device_id sc18is602_id[] = {  	{ "sc18is602", sc18is602 },  	{ "sc18is602b", sc18is602b }, @@ -353,7 +323,6 @@ static struct i2c_driver sc18is602_driver = {  		.name = "sc18is602",  	},  	.probe = sc18is602_probe, -	.remove = sc18is602_remove,  	.id_table = sc18is602_id,  }; diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 0b68cb592fa..c8e795ef2e1 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -46,8 +46,6 @@  /* SPSR */  #define RXFL	(1 << 2) -#define hspi2info(h)	(h->dev->platform_data) -  struct hspi_priv {  	void __iomem *addr;  	struct spi_master *master; @@ -113,14 +111,9 @@ static void hspi_hw_setup(struct hspi_priv *hspi,  {  	struct spi_device *spi = msg->spi;  	struct device *dev = hspi->dev; -	u32 target_rate;  	u32 spcr, idiv_clk;  	u32 rate, best_rate, min, tmp; -	target_rate = t ? t->speed_hz : 0; -	if (!target_rate) -		target_rate = spi->max_speed_hz; -  	/*  	 * find best IDIV/CLKCx settings  	 */ @@ -137,10 +130,10 @@ static void hspi_hw_setup(struct hspi_priv *hspi,  			rate /= 16;  		/* CLKCx calculation */ -		rate /= (((idiv_clk & 0x1F) + 1) * 2) ; +		rate /= (((idiv_clk & 0x1F) + 1) * 2);  		/* save best settings */ -		tmp = abs(target_rate - rate); +		tmp = abs(t->speed_hz - rate);  		if (tmp < min) {  			min = tmp;  			spcr = idiv_clk; @@ -153,7 +146,7 @@ static void hspi_hw_setup(struct hspi_priv *hspi,  	if (spi->mode & SPI_CPOL)  		spcr |= 1 << 6; -	dev_dbg(dev, "speed %d/%d\n", target_rate, best_rate); +	dev_dbg(dev, "speed %d/%d\n", t->speed_hz, best_rate);  	hspi_write(hspi, SPCR, spcr);  	hspi_write(hspi, SPSR, 0x0); @@ -197,7 +190,7 @@ static int hspi_transfer_one_message(struct spi_master *master,  			hspi_write(hspi, SPTBR, tx); -			/* wait recive */ +			/* wait receive */  			ret = hspi_status_check_timeout(hspi, 0x4, 0x4);  			if (ret < 0)  				break; @@ -230,29 +223,6 @@ static int hspi_transfer_one_message(struct spi_master *master,  	return ret;  } -static int hspi_setup(struct spi_device *spi) -{ -	struct hspi_priv *hspi = spi_master_get_devdata(spi->master); -	struct device *dev = hspi->dev; - -	if (8 != spi->bits_per_word) { -		dev_err(dev, "bits_per_word should be 8\n"); -		return -EIO; -	} - -	dev_dbg(dev, "%s setup\n", spi->modalias); - -	return 0; -} - -static void hspi_cleanup(struct spi_device *spi) -{ -	struct hspi_priv *hspi = spi_master_get_devdata(spi->master); -	struct device *dev = hspi->dev; - -	dev_dbg(dev, "%s cleanup\n", spi->modalias); -} -  static int hspi_probe(struct platform_device *pdev)  {  	struct resource *res; @@ -274,9 +244,9 @@ static int hspi_probe(struct platform_device *pdev)  		return -ENOMEM;  	} -	clk = clk_get(NULL, "shyway_clk"); +	clk = clk_get(&pdev->dev, NULL);  	if (IS_ERR(clk)) { -		dev_err(&pdev->dev, "shyway_clk is required\n"); +		dev_err(&pdev->dev, "couldn't get clock\n");  		ret = -EINVAL;  		goto error0;  	} @@ -296,23 +266,25 @@ static int hspi_probe(struct platform_device *pdev)  		goto error1;  	} -	master->num_chipselect	= 1; +	pm_runtime_enable(&pdev->dev); +  	master->bus_num		= pdev->id; -	master->setup		= hspi_setup; -	master->cleanup		= hspi_cleanup;  	master->mode_bits	= SPI_CPOL | SPI_CPHA; +	master->dev.of_node	= pdev->dev.of_node;  	master->auto_runtime_pm = true;  	master->transfer_one_message		= hspi_transfer_one_message; -	ret = spi_register_master(master); +	master->bits_per_word_mask = SPI_BPW_MASK(8); + +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret < 0) {  		dev_err(&pdev->dev, "spi_register_master error.\n"); -		goto error1; +		goto error2;  	} -	pm_runtime_enable(&pdev->dev); -  	return 0; + error2: +	pm_runtime_disable(&pdev->dev);   error1:  	clk_put(clk);   error0: @@ -328,17 +300,23 @@ static int hspi_remove(struct platform_device *pdev)  	pm_runtime_disable(&pdev->dev);  	clk_put(hspi->clk); -	spi_unregister_master(hspi->master);  	return 0;  } +static struct of_device_id hspi_of_match[] = { +	{ .compatible = "renesas,hspi", }, +	{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, hspi_of_match); +  static struct platform_driver hspi_driver = {  	.probe = hspi_probe,  	.remove = hspi_remove,  	.driver = {  		.name = "sh-hspi",  		.owner = THIS_MODULE, +		.of_match_table = hspi_of_match,  	},  };  module_platform_driver(hspi_driver); @@ -346,4 +324,4 @@ module_platform_driver(hspi_driver);  MODULE_DESCRIPTION("SuperH HSPI bus driver");  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); -MODULE_ALIAS("platform:sh_spi"); +MODULE_ALIAS("platform:sh-hspi"); diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 2a95435a6a1..45b09142afe 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -15,59 +15,108 @@  #include <linux/delay.h>  #include <linux/err.h>  #include <linux/gpio.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/of.h> +#include <linux/of_device.h>  #include <linux/platform_device.h>  #include <linux/pm_runtime.h>  #include <linux/spi/sh_msiof.h>  #include <linux/spi/spi.h> -#include <linux/spi/spi_bitbang.h>  #include <asm/unaligned.h> + +struct sh_msiof_chipdata { +	u16 tx_fifo_size; +	u16 rx_fifo_size; +	u16 master_flags; +}; +  struct sh_msiof_spi_priv { -	struct spi_bitbang bitbang; /* must be first for spi_bitbang.c */  	void __iomem *mapbase;  	struct clk *clk;  	struct platform_device *pdev; +	const struct sh_msiof_chipdata *chipdata;  	struct sh_msiof_spi_info *info;  	struct completion done; -	unsigned long flags;  	int tx_fifo_size;  	int rx_fifo_size;  }; -#define TMDR1	0x00 -#define TMDR2	0x04 -#define TMDR3	0x08 -#define RMDR1	0x10 -#define RMDR2	0x14 -#define RMDR3	0x18 -#define TSCR	0x20 -#define RSCR	0x22 -#define CTR	0x28 -#define FCTR	0x30 -#define STR	0x40 -#define IER	0x44 -#define TDR1	0x48 -#define TDR2	0x4c -#define TFDR	0x50 -#define RDR1	0x58 -#define RDR2	0x5c -#define RFDR	0x60 - -#define CTR_TSCKE (1 << 15) -#define CTR_TFSE  (1 << 14) -#define CTR_TXE   (1 << 9) -#define CTR_RXE   (1 << 8) - -#define STR_TEOF  (1 << 23) -#define STR_REOF  (1 << 7) +#define TMDR1	0x00	/* Transmit Mode Register 1 */ +#define TMDR2	0x04	/* Transmit Mode Register 2 */ +#define TMDR3	0x08	/* Transmit Mode Register 3 */ +#define RMDR1	0x10	/* Receive Mode Register 1 */ +#define RMDR2	0x14	/* Receive Mode Register 2 */ +#define RMDR3	0x18	/* Receive Mode Register 3 */ +#define TSCR	0x20	/* Transmit Clock Select Register */ +#define RSCR	0x22	/* Receive Clock Select Register (SH, A1, APE6) */ +#define CTR	0x28	/* Control Register */ +#define FCTR	0x30	/* FIFO Control Register */ +#define STR	0x40	/* Status Register */ +#define IER	0x44	/* Interrupt Enable Register */ +#define TDR1	0x48	/* Transmit Control Data Register 1 (SH, A1) */ +#define TDR2	0x4c	/* Transmit Control Data Register 2 (SH, A1) */ +#define TFDR	0x50	/* Transmit FIFO Data Register */ +#define RDR1	0x58	/* Receive Control Data Register 1 (SH, A1) */ +#define RDR2	0x5c	/* Receive Control Data Register 2 (SH, A1) */ +#define RFDR	0x60	/* Receive FIFO Data Register */ + +/* TMDR1 and RMDR1 */ +#define MDR1_TRMD	 0x80000000 /* Transfer Mode (1 = Master mode) */ +#define MDR1_SYNCMD_MASK 0x30000000 /* SYNC Mode */ +#define MDR1_SYNCMD_SPI	 0x20000000 /*   Level mode/SPI */ +#define MDR1_SYNCMD_LR	 0x30000000 /*   L/R mode */ +#define MDR1_SYNCAC_SHIFT	 25 /* Sync Polarity (1 = Active-low) */ +#define MDR1_BITLSB_SHIFT	 24 /* MSB/LSB First (1 = LSB first) */ +#define MDR1_FLD_MASK	 0x000000c0 /* Frame Sync Signal Interval (0-3) */ +#define MDR1_FLD_SHIFT		  2 +#define MDR1_XXSTP	 0x00000001 /* Transmission/Reception Stop on FIFO */ +/* TMDR1 */ +#define TMDR1_PCON	 0x40000000 /* Transfer Signal Connection */ + +/* TMDR2 and RMDR2 */ +#define MDR2_BITLEN1(i)	(((i) - 1) << 24) /* Data Size (8-32 bits) */ +#define MDR2_WDLEN1(i)	(((i) - 1) << 16) /* Word Count (1-64/256 (SH, A1))) */ +#define MDR2_GRPMASK1	0x00000001 /* Group Output Mask 1 (SH, A1) */ + +/* TSCR and RSCR */ +#define SCR_BRPS_MASK	    0x1f00 /* Prescaler Setting (1-32) */ +#define SCR_BRPS(i)	(((i) - 1) << 8) +#define SCR_BRDV_MASK	    0x0007 /* Baud Rate Generator's Division Ratio */ +#define SCR_BRDV_DIV_2	    0x0000 +#define SCR_BRDV_DIV_4	    0x0001 +#define SCR_BRDV_DIV_8	    0x0002 +#define SCR_BRDV_DIV_16	    0x0003 +#define SCR_BRDV_DIV_32	    0x0004 +#define SCR_BRDV_DIV_1	    0x0007 + +/* CTR */ +#define CTR_TSCKIZ_MASK	0xc0000000 /* Transmit Clock I/O Polarity Select */ +#define CTR_TSCKIZ_SCK	0x80000000 /*   Disable SCK when TX disabled */ +#define CTR_TSCKIZ_POL_SHIFT	30 /*   Transmit Clock Polarity */ +#define CTR_RSCKIZ_MASK	0x30000000 /* Receive Clock Polarity Select */ +#define CTR_RSCKIZ_SCK	0x20000000 /*   Must match CTR_TSCKIZ_SCK */ +#define CTR_RSCKIZ_POL_SHIFT	28 /*   Receive Clock Polarity */ +#define CTR_TEDG_SHIFT		27 /* Transmit Timing (1 = falling edge) */ +#define CTR_REDG_SHIFT		26 /* Receive Timing (1 = falling edge) */ +#define CTR_TXDIZ_MASK	0x00c00000 /* Pin Output When TX is Disabled */ +#define CTR_TXDIZ_LOW	0x00000000 /*   0 */ +#define CTR_TXDIZ_HIGH	0x00400000 /*   1 */ +#define CTR_TXDIZ_HIZ	0x00800000 /*   High-impedance */ +#define CTR_TSCKE	0x00008000 /* Transmit Serial Clock Output Enable */ +#define CTR_TFSE	0x00004000 /* Transmit Frame Sync Signal Output Enable */ +#define CTR_TXE		0x00000200 /* Transmit Enable */ +#define CTR_RXE		0x00000100 /* Receive Enable */ + +/* STR and IER */ +#define STR_TEOF	0x00800000 /* Frame Transmission End */ +#define STR_REOF	0x00000080 /* Frame Reception End */ +  static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)  { @@ -131,28 +180,27 @@ static struct {  	unsigned short div;  	unsigned short scr;  } const sh_msiof_spi_clk_table[] = { -	{ 1, 0x0007 }, -	{ 2, 0x0000 }, -	{ 4, 0x0001 }, -	{ 8, 0x0002 }, -	{ 16, 0x0003 }, -	{ 32, 0x0004 }, -	{ 64, 0x1f00 }, -	{ 128, 0x1f01 }, -	{ 256, 0x1f02 }, -	{ 512, 0x1f03 }, -	{ 1024, 0x1f04 }, +	{ 1,	SCR_BRPS( 1) | SCR_BRDV_DIV_1 }, +	{ 2,	SCR_BRPS( 1) | SCR_BRDV_DIV_2 }, +	{ 4,	SCR_BRPS( 1) | SCR_BRDV_DIV_4 }, +	{ 8,	SCR_BRPS( 1) | SCR_BRDV_DIV_8 }, +	{ 16,	SCR_BRPS( 1) | SCR_BRDV_DIV_16 }, +	{ 32,	SCR_BRPS( 1) | SCR_BRDV_DIV_32 }, +	{ 64,	SCR_BRPS(32) | SCR_BRDV_DIV_2 }, +	{ 128,	SCR_BRPS(32) | SCR_BRDV_DIV_4 }, +	{ 256,	SCR_BRPS(32) | SCR_BRDV_DIV_8 }, +	{ 512,	SCR_BRPS(32) | SCR_BRDV_DIV_16 }, +	{ 1024,	SCR_BRPS(32) | SCR_BRDV_DIV_32 },  };  static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, -				      unsigned long parent_rate, -				      unsigned long spi_hz) +				      unsigned long parent_rate, u32 spi_hz)  {  	unsigned long div = 1024;  	size_t k;  	if (!WARN_ON(!spi_hz || !parent_rate)) -		div = parent_rate / spi_hz; +		div = DIV_ROUND_UP(parent_rate, spi_hz);  	/* TODO: make more fine grained */ @@ -164,12 +212,13 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,  	k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_clk_table) - 1);  	sh_msiof_write(p, TSCR, sh_msiof_spi_clk_table[k].scr); -	sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr); +	if (!(p->chipdata->master_flags & SPI_MASTER_MUST_TX)) +		sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr);  }  static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,  				      u32 cpol, u32 cpha, -				      u32 tx_hi_z, u32 lsb_first) +				      u32 tx_hi_z, u32 lsb_first, u32 cs_high)  {  	u32 tmp;  	int edge; @@ -182,18 +231,26 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,  	 *    1    1         11     11    1    1  	 */  	sh_msiof_write(p, FCTR, 0); -	sh_msiof_write(p, TMDR1, 0xe2000005 | (lsb_first << 24)); -	sh_msiof_write(p, RMDR1, 0x22000005 | (lsb_first << 24)); -	tmp = 0xa0000000; -	tmp |= cpol << 30; /* TSCKIZ */ -	tmp |= cpol << 28; /* RSCKIZ */ +	tmp = MDR1_SYNCMD_SPI | 1 << MDR1_FLD_SHIFT | MDR1_XXSTP; +	tmp |= !cs_high << MDR1_SYNCAC_SHIFT; +	tmp |= lsb_first << MDR1_BITLSB_SHIFT; +	sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); +	if (p->chipdata->master_flags & SPI_MASTER_MUST_TX) { +		/* These bits are reserved if RX needs TX */ +		tmp &= ~0x0000ffff; +	} +	sh_msiof_write(p, RMDR1, tmp); + +	tmp = 0; +	tmp |= CTR_TSCKIZ_SCK | cpol << CTR_TSCKIZ_POL_SHIFT; +	tmp |= CTR_RSCKIZ_SCK | cpol << CTR_RSCKIZ_POL_SHIFT;  	edge = cpol ^ !cpha; -	tmp |= edge << 27; /* TEDG */ -	tmp |= edge << 26; /* REDG */ -	tmp |= (tx_hi_z ? 2 : 0) << 22; /* TXDIZ */ +	tmp |= edge << CTR_TEDG_SHIFT; +	tmp |= edge << CTR_REDG_SHIFT; +	tmp |= tx_hi_z ? CTR_TXDIZ_HIZ : CTR_TXDIZ_LOW;  	sh_msiof_write(p, CTR, tmp);  } @@ -201,12 +258,12 @@ static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,  				       const void *tx_buf, void *rx_buf,  				       u32 bits, u32 words)  { -	u32 dr2 = ((bits - 1) << 24) | ((words - 1) << 16); +	u32 dr2 = MDR2_BITLEN1(bits) | MDR2_WDLEN1(words); -	if (tx_buf) +	if (tx_buf || (p->chipdata->master_flags & SPI_MASTER_MUST_TX))  		sh_msiof_write(p, TMDR2, dr2);  	else -		sh_msiof_write(p, TMDR2, dr2 | 1); +		sh_msiof_write(p, TMDR2, dr2 | MDR2_GRPMASK1);  	if (rx_buf)  		sh_msiof_write(p, RMDR2, dr2); @@ -359,76 +416,45 @@ static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p,  		put_unaligned(swab32(sh_msiof_read(p, RFDR) >> fs), &buf_32[k]);  } -static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) -{ -	int bits; - -	bits = t ? t->bits_per_word : 0; -	if (!bits) -		bits = spi->bits_per_word; -	return bits; -} - -static unsigned long sh_msiof_spi_hz(struct spi_device *spi, -				     struct spi_transfer *t) +static int sh_msiof_spi_setup(struct spi_device *spi)  { -	unsigned long hz; - -	hz = t ? t->speed_hz : 0; -	if (!hz) -		hz = spi->max_speed_hz; -	return hz; -} +	struct device_node	*np = spi->master->dev.of_node; +	struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); -static int sh_msiof_spi_setup_transfer(struct spi_device *spi, -				       struct spi_transfer *t) -{ -	int bits; +	if (!np) { +		/* +		 * Use spi->controller_data for CS (same strategy as spi_gpio), +		 * if any. otherwise let HW control CS +		 */ +		spi->cs_gpio = (uintptr_t)spi->controller_data; +	} -	/* noting to check hz values against since parent clock is disabled */ +	/* Configure pins before deasserting CS */ +	sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL), +				  !!(spi->mode & SPI_CPHA), +				  !!(spi->mode & SPI_3WIRE), +				  !!(spi->mode & SPI_LSB_FIRST), +				  !!(spi->mode & SPI_CS_HIGH)); -	bits = sh_msiof_spi_bits(spi, t); -	if (bits < 8) -		return -EINVAL; -	if (bits > 32) -		return -EINVAL; +	if (spi->cs_gpio >= 0) +		gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); -	return spi_bitbang_setup_transfer(spi, t); +	return 0;  } -static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on) +static int sh_msiof_prepare_message(struct spi_master *master, +				    struct spi_message *msg)  { -	struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); -	int value; - -	/* chip select is active low unless SPI_CS_HIGH is set */ -	if (spi->mode & SPI_CS_HIGH) -		value = (is_on == BITBANG_CS_ACTIVE) ? 1 : 0; -	else -		value = (is_on == BITBANG_CS_ACTIVE) ? 0 : 1; - -	if (is_on == BITBANG_CS_ACTIVE) { -		if (!test_and_set_bit(0, &p->flags)) { -			pm_runtime_get_sync(&p->pdev->dev); -			clk_enable(p->clk); -		} - -		/* Configure pins before asserting CS */ -		sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL), -					  !!(spi->mode & SPI_CPHA), -					  !!(spi->mode & SPI_3WIRE), -					  !!(spi->mode & SPI_LSB_FIRST)); -	} +	struct sh_msiof_spi_priv *p = spi_master_get_devdata(master); +	const struct spi_device *spi = msg->spi; -	/* use spi->controller data for CS (same strategy as spi_gpio) */ -	gpio_set_value((unsigned)spi->controller_data, value); - -	if (is_on == BITBANG_CS_INACTIVE) { -		if (test_and_clear_bit(0, &p->flags)) { -			clk_disable(p->clk); -			pm_runtime_put(&p->pdev->dev); -		} -	} +	/* Configure pins before asserting CS */ +	sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL), +				  !!(spi->mode & SPI_CPHA), +				  !!(spi->mode & SPI_3WIRE), +				  !!(spi->mode & SPI_LSB_FIRST), +				  !!(spi->mode & SPI_CS_HIGH)); +	return 0;  }  static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, @@ -465,7 +491,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,  	ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);  	/* start by setting frame bit */ -	INIT_COMPLETION(p->done); +	reinit_completion(&p->done);  	ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);  	if (ret) {  		dev_err(&p->pdev->dev, "failed to start hardware\n"); @@ -482,7 +508,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,  	/* clear status bits */  	sh_msiof_reset_str(p); -	/* shut down frame, tx/tx and clock signals */ +	/* shut down frame, rx/tx and clock signals */  	ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);  	ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);  	if (rx_buf) @@ -500,9 +526,11 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,  	return ret;  } -static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) +static int sh_msiof_transfer_one(struct spi_master *master, +				 struct spi_device *spi, +				 struct spi_transfer *t)  { -	struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); +	struct sh_msiof_spi_priv *p = spi_master_get_devdata(master);  	void (*tx_fifo)(struct sh_msiof_spi_priv *, const void *, int, int);  	void (*rx_fifo)(struct sh_msiof_spi_priv *, void *, int, int);  	int bits; @@ -512,7 +540,7 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)  	int n;  	bool swab; -	bits = sh_msiof_spi_bits(spi, t); +	bits = t->bits_per_word;  	if (bits <= 8 && t->len > 15 && !(t->len & 3)) {  		bits = 32; @@ -562,8 +590,7 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)  	}  	/* setup clocks (clock already enabled in chipselect()) */ -	sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), -				  sh_msiof_spi_hz(spi, t)); +	sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz);  	/* transfer in fifo sized chunks */  	words = t->len / bytes_per_word; @@ -583,28 +610,40 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)  		words -= n;  	} -	return bytes_done; -} - -static u32 sh_msiof_spi_txrx_word(struct spi_device *spi, unsigned nsecs, -				  u32 word, u8 bits) -{ -	BUG(); /* unused but needed by bitbang code */  	return 0;  } +static const struct sh_msiof_chipdata sh_data = { +	.tx_fifo_size = 64, +	.rx_fifo_size = 64, +	.master_flags = 0, +}; + +static const struct sh_msiof_chipdata r8a779x_data = { +	.tx_fifo_size = 64, +	.rx_fifo_size = 256, +	.master_flags = SPI_MASTER_MUST_TX, +}; + +static const struct of_device_id sh_msiof_match[] = { +	{ .compatible = "renesas,sh-msiof",        .data = &sh_data }, +	{ .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, +	{ .compatible = "renesas,msiof-r8a7790",   .data = &r8a779x_data }, +	{ .compatible = "renesas,msiof-r8a7791",   .data = &r8a779x_data }, +	{}, +}; +MODULE_DEVICE_TABLE(of, sh_msiof_match); +  #ifdef CONFIG_OF  static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)  {  	struct sh_msiof_spi_info *info;  	struct device_node *np = dev->of_node; -	u32 num_cs = 0; +	u32 num_cs = 1;  	info = devm_kzalloc(dev, sizeof(struct sh_msiof_spi_info), GFP_KERNEL); -	if (!info) { -		dev_err(dev, "failed to allocate setup data\n"); +	if (!info)  		return NULL; -	}  	/* Parse the MSIOF properties */  	of_property_read_u32(np, "num-cs", &num_cs); @@ -628,6 +667,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)  {  	struct resource	*r;  	struct spi_master *master; +	const struct of_device_id *of_id;  	struct sh_msiof_spi_priv *p;  	int i;  	int ret; @@ -635,17 +675,21 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)  	master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));  	if (master == NULL) {  		dev_err(&pdev->dev, "failed to allocate spi master\n"); -		ret = -ENOMEM; -		goto err0; +		return -ENOMEM;  	}  	p = spi_master_get_devdata(master);  	platform_set_drvdata(pdev, p); -	if (pdev->dev.of_node) + +	of_id = of_match_device(sh_msiof_match, &pdev->dev); +	if (of_id) { +		p->chipdata = of_id->data;  		p->info = sh_msiof_spi_parse_dt(&pdev->dev); -	else +	} else { +		p->chipdata = (const void *)pdev->id_entry->driver_data;  		p->info = dev_get_platdata(&pdev->dev); +	}  	if (!p->info) {  		dev_err(&pdev->dev, "failed to obtain device info\n"); @@ -655,108 +699,91 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)  	init_completion(&p->done); -	p->clk = clk_get(&pdev->dev, NULL); +	p->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(p->clk)) {  		dev_err(&pdev->dev, "cannot get clock\n");  		ret = PTR_ERR(p->clk);  		goto err1;  	} -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	i = platform_get_irq(pdev, 0); -	if (!r || i < 0) { -		dev_err(&pdev->dev, "cannot get platform resources\n"); +	if (i < 0) { +		dev_err(&pdev->dev, "cannot get platform IRQ\n");  		ret = -ENOENT; -		goto err2; +		goto err1;  	} -	p->mapbase = ioremap_nocache(r->start, resource_size(r)); -	if (!p->mapbase) { -		dev_err(&pdev->dev, "unable to ioremap\n"); -		ret = -ENXIO; -		goto err2; + +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	p->mapbase = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(p->mapbase)) { +		ret = PTR_ERR(p->mapbase); +		goto err1;  	} -	ret = request_irq(i, sh_msiof_spi_irq, 0, -			  dev_name(&pdev->dev), p); +	ret = devm_request_irq(&pdev->dev, i, sh_msiof_spi_irq, 0, +			       dev_name(&pdev->dev), p);  	if (ret) {  		dev_err(&pdev->dev, "unable to request irq\n"); -		goto err3; +		goto err1;  	}  	p->pdev = pdev;  	pm_runtime_enable(&pdev->dev); -	/* The standard version of MSIOF use 64 word FIFOs */ -	p->tx_fifo_size = 64; -	p->rx_fifo_size = 64; -  	/* Platform data may override FIFO sizes */ +	p->tx_fifo_size = p->chipdata->tx_fifo_size; +	p->rx_fifo_size = p->chipdata->rx_fifo_size;  	if (p->info->tx_fifo_override)  		p->tx_fifo_size = p->info->tx_fifo_override;  	if (p->info->rx_fifo_override)  		p->rx_fifo_size = p->info->rx_fifo_override; -	/* init master and bitbang code */ +	/* init master code */  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;  	master->mode_bits |= SPI_LSB_FIRST | SPI_3WIRE; -	master->flags = 0; +	master->flags = p->chipdata->master_flags;  	master->bus_num = pdev->id; +	master->dev.of_node = pdev->dev.of_node;  	master->num_chipselect = p->info->num_chipselect; -	master->setup = spi_bitbang_setup; -	master->cleanup = spi_bitbang_cleanup; - -	p->bitbang.master = master; -	p->bitbang.chipselect = sh_msiof_spi_chipselect; -	p->bitbang.setup_transfer = sh_msiof_spi_setup_transfer; -	p->bitbang.txrx_bufs = sh_msiof_spi_txrx; -	p->bitbang.txrx_word[SPI_MODE_0] = sh_msiof_spi_txrx_word; -	p->bitbang.txrx_word[SPI_MODE_1] = sh_msiof_spi_txrx_word; -	p->bitbang.txrx_word[SPI_MODE_2] = sh_msiof_spi_txrx_word; -	p->bitbang.txrx_word[SPI_MODE_3] = sh_msiof_spi_txrx_word; - -	ret = spi_bitbang_start(&p->bitbang); -	if (ret == 0) -		return 0; +	master->setup = sh_msiof_spi_setup; +	master->prepare_message = sh_msiof_prepare_message; +	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); +	master->auto_runtime_pm = true; +	master->transfer_one = sh_msiof_transfer_one; + +	ret = devm_spi_register_master(&pdev->dev, master); +	if (ret < 0) { +		dev_err(&pdev->dev, "spi_register_master error.\n"); +		goto err2; +	} + +	return 0; -	pm_runtime_disable(&pdev->dev); - err3: -	iounmap(p->mapbase);   err2: -	clk_put(p->clk); +	pm_runtime_disable(&pdev->dev);   err1:  	spi_master_put(master); - err0:  	return ret;  }  static int sh_msiof_spi_remove(struct platform_device *pdev)  { -	struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev); -	int ret; - -	ret = spi_bitbang_stop(&p->bitbang); -	if (!ret) { -		pm_runtime_disable(&pdev->dev); -		free_irq(platform_get_irq(pdev, 0), p); -		iounmap(p->mapbase); -		clk_put(p->clk); -		spi_master_put(p->bitbang.master); -	} -	return ret; +	pm_runtime_disable(&pdev->dev); +	return 0;  } -#ifdef CONFIG_OF -static const struct of_device_id sh_msiof_match[] = { -	{ .compatible = "renesas,sh-msiof", }, -	{ .compatible = "renesas,sh-mobile-msiof", }, +static struct platform_device_id spi_driver_ids[] = { +	{ "spi_sh_msiof",	(kernel_ulong_t)&sh_data }, +	{ "spi_r8a7790_msiof",	(kernel_ulong_t)&r8a779x_data }, +	{ "spi_r8a7791_msiof",	(kernel_ulong_t)&r8a779x_data },  	{},  }; -MODULE_DEVICE_TABLE(of, sh_msiof_match); -#endif +MODULE_DEVICE_TABLE(platform, spi_driver_ids);  static struct platform_driver sh_msiof_spi_drv = {  	.probe		= sh_msiof_spi_probe,  	.remove		= sh_msiof_spi_remove, +	.id_table	= spi_driver_ids,  	.driver		= {  		.name		= "spi_sh_msiof",  		.owner		= THIS_MODULE, diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index 8eefeb6007d..b83dd733684 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c @@ -14,10 +14,8 @@   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/delay.h>  #include <linux/spinlock.h> -#include <linux/workqueue.h>  #include <linux/platform_device.h>  #include <linux/spi/spi.h> @@ -109,7 +107,7 @@ static void sh_sci_spi_chipselect(struct spi_device *dev, int value)  {  	struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); -	if (sp->info && sp->info->chip_select) +	if (sp->info->chip_select)  		(sp->info->chip_select)(sp->info, dev->chip_select, value);  } @@ -131,9 +129,14 @@ static int sh_sci_spi_probe(struct platform_device *dev)  	platform_set_drvdata(dev, sp);  	sp->info = dev_get_platdata(&dev->dev); +	if (!sp->info) { +		dev_err(&dev->dev, "platform data is missing\n"); +		ret = -ENOENT; +		goto err1; +	}  	/* setup spi bitbang adaptor */ -	sp->bitbang.master = spi_master_get(master); +	sp->bitbang.master = master;  	sp->bitbang.master->bus_num = sp->info->bus_num;  	sp->bitbang.master->num_chipselect = sp->info->num_chipselect;  	sp->bitbang.chipselect = sh_sci_spi_chipselect; @@ -172,9 +175,9 @@ static int sh_sci_spi_remove(struct platform_device *dev)  {  	struct sh_sci_spi *sp = platform_get_drvdata(dev); -	iounmap(sp->membase); -	setbits(sp, PIN_INIT, 0);  	spi_bitbang_stop(&sp->bitbang); +	setbits(sp, PIN_INIT, 0); +	iounmap(sp->membase);  	spi_master_put(sp->bitbang.master);  	return 0;  } diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c index c120a70094f..03edf5ed0e9 100644 --- a/drivers/spi/spi-sh.c +++ b/drivers/spi/spi-sh.c @@ -171,7 +171,6 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg,  	int remain = t->len;  	int cur_len;  	unsigned char *data; -	unsigned long tmp;  	long ret;  	if (t->len) @@ -213,9 +212,7 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg,  	}  	if (list_is_last(&t->transfer_list, &mesg->transfers)) { -		tmp = spi_sh_read(ss, SPI_SH_CR1); -		tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB); -		spi_sh_write(ss, tmp, SPI_SH_CR1); +		spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1);  		spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1);  		ss->cr1 &= ~SPI_SH_TBE; @@ -239,7 +236,6 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg,  	int remain = t->len;  	int cur_len;  	unsigned char *data; -	unsigned long tmp;  	long ret;  	if (t->len > SPI_SH_MAX_BYTE) @@ -247,9 +243,7 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg,  	else  		spi_sh_write(ss, t->len, SPI_SH_CR3); -	tmp = spi_sh_read(ss, SPI_SH_CR1); -	tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB); -	spi_sh_write(ss, tmp, SPI_SH_CR1); +	spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1);  	spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1);  	spi_sh_wait_write_buffer_empty(ss); @@ -328,7 +322,8 @@ static void spi_sh_work(struct work_struct *work)  		spin_lock_irqsave(&ss->lock, flags);  		mesg->status = 0; -		mesg->complete(mesg->context); +		if (mesg->complete) +			mesg->complete(mesg->context);  	}  	clear_fifo(ss); @@ -346,7 +341,8 @@ static void spi_sh_work(struct work_struct *work)   error:  	mesg->status = ret; -	mesg->complete(mesg->context); +	if (mesg->complete) +		mesg->complete(mesg->context);  	spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD,  			 SPI_SH_CR1); @@ -358,9 +354,6 @@ static int spi_sh_setup(struct spi_device *spi)  {  	struct spi_sh_data *ss = spi_master_get_devdata(spi->master); -	if (!spi->bits_per_word) -		spi->bits_per_word = 8; -  	pr_debug("%s: enter\n", __func__);  	spi_sh_write(ss, 0xfe, SPI_SH_CR1);	/* SPI sycle stop */ diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index a1f21b74773..95ac276eaaf 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -10,6 +10,7 @@  #include <linux/kernel.h>  #include <linux/slab.h>  #include <linux/clk.h> +#include <linux/completion.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/of.h> @@ -22,7 +23,6 @@  #include <linux/dmaengine.h>  #include <linux/dma-direction.h>  #include <linux/dma-mapping.h> -#include <linux/sirfsoc_dma.h>  #define DRIVER_NAME "sirfsoc_spi" @@ -86,6 +86,7 @@  #define SIRFSOC_SPI_TX_DONE		BIT(1)  #define SIRFSOC_SPI_RX_OFLOW		BIT(2)  #define SIRFSOC_SPI_TX_UFLOW		BIT(3) +#define SIRFSOC_SPI_RX_IO_DMA		BIT(4)  #define SIRFSOC_SPI_RX_FIFO_FULL	BIT(6)  #define SIRFSOC_SPI_TXFIFO_EMPTY	BIT(7)  #define SIRFSOC_SPI_RXFIFO_THD_REACH	BIT(8) @@ -132,6 +133,8 @@  #define IS_DMA_VALID(x) (x && ALIGNED(x->tx_buf) && ALIGNED(x->rx_buf) && \  	ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE)) +#define SIRFSOC_MAX_CMD_BYTES	4 +  struct sirfsoc_spi {  	struct spi_bitbang bitbang;  	struct completion rx_done; @@ -162,6 +165,12 @@ struct sirfsoc_spi {  	void *dummypage;  	int word_width; /* in bytes */ +	/* +	 * if tx size is not more than 4 and rx size is NULL, use +	 * command model +	 */ +	bool	tx_by_cmd; +  	int chipselect[0];  }; @@ -257,35 +266,34 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)  {  	struct sirfsoc_spi *sspi = dev_id;  	u32 spi_stat = readl(sspi->base + SIRFSOC_SPI_INT_STATUS); - -	writel(spi_stat, sspi->base + SIRFSOC_SPI_INT_STATUS); +	if (sspi->tx_by_cmd && (spi_stat & SIRFSOC_SPI_FRM_END)) { +		complete(&sspi->tx_done); +		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); +		writel(SIRFSOC_SPI_INT_MASK_ALL, +				sspi->base + SIRFSOC_SPI_INT_STATUS); +		return IRQ_HANDLED; +	}  	/* Error Conditions */  	if (spi_stat & SIRFSOC_SPI_RX_OFLOW ||  			spi_stat & SIRFSOC_SPI_TX_UFLOW) { +		complete(&sspi->tx_done);  		complete(&sspi->rx_done);  		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); +		writel(SIRFSOC_SPI_INT_MASK_ALL, +				sspi->base + SIRFSOC_SPI_INT_STATUS); +		return IRQ_HANDLED;  	} +	if (spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY) +		complete(&sspi->tx_done); +	while (!(readl(sspi->base + SIRFSOC_SPI_INT_STATUS) & +		SIRFSOC_SPI_RX_IO_DMA)) +		cpu_relax(); +	complete(&sspi->rx_done); +	writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); +	writel(SIRFSOC_SPI_INT_MASK_ALL, +			sspi->base + SIRFSOC_SPI_INT_STATUS); -	if (spi_stat & (SIRFSOC_SPI_FRM_END -			| SIRFSOC_SPI_RXFIFO_THD_REACH)) -		while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS) -				& SIRFSOC_SPI_FIFO_EMPTY)) && -				sspi->left_rx_word) -			sspi->rx_word(sspi); - -	if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY -			| SIRFSOC_SPI_TXFIFO_THD_REACH)) -		while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) -				& SIRFSOC_SPI_FIFO_FULL)) && -				sspi->left_tx_word) -			sspi->tx_word(sspi); - -	/* Received all words */ -	if ((sspi->left_rx_word == 0) && (sspi->left_tx_word == 0)) { -		complete(&sspi->rx_done); -		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); -	}  	return IRQ_HANDLED;  } @@ -296,31 +304,51 @@ static void spi_sirfsoc_dma_fini_callback(void *data)  	complete(dma_complete);  } -static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t) +static int spi_sirfsoc_cmd_transfer(struct spi_device *spi, +	struct spi_transfer *t)  {  	struct sirfsoc_spi *sspi;  	int timeout = t->len * 10; +	u32 cmd; +  	sspi = spi_master_get_devdata(spi->master); +	memcpy(&cmd, sspi->tx, t->len); +	if (sspi->word_width == 1 && !(spi->mode & SPI_LSB_FIRST)) +		cmd = cpu_to_be32(cmd) >> +			((SIRFSOC_MAX_CMD_BYTES - t->len) * 8); +	if (sspi->word_width == 2 && t->len == 4 && +			(!(spi->mode & SPI_LSB_FIRST))) +		cmd = ((cmd & 0xffff) << 16) | (cmd >> 16); +	writel(cmd, sspi->base + SIRFSOC_SPI_CMD); +	writel(SIRFSOC_SPI_FRM_END_INT_EN, +		sspi->base + SIRFSOC_SPI_INT_EN); +	writel(SIRFSOC_SPI_CMD_TX_EN, +		sspi->base + SIRFSOC_SPI_TX_RX_EN); +	if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { +		dev_err(&spi->dev, "cmd transfer timeout\n"); +		return 0; +	} -	sspi->tx = t->tx_buf ? t->tx_buf : sspi->dummypage; -	sspi->rx = t->rx_buf ? t->rx_buf : sspi->dummypage; -	sspi->left_tx_word = sspi->left_rx_word = t->len / sspi->word_width; -	INIT_COMPLETION(sspi->rx_done); -	INIT_COMPLETION(sspi->tx_done); +	return t->len; +} -	writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS); +static void spi_sirfsoc_dma_transfer(struct spi_device *spi, +	struct spi_transfer *t) +{ +	struct sirfsoc_spi *sspi; +	struct dma_async_tx_descriptor *rx_desc, *tx_desc; +	int timeout = t->len * 10; -	if (sspi->left_tx_word == 1) { -		writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | -			SIRFSOC_SPI_ENA_AUTO_CLR, -			sspi->base + SIRFSOC_SPI_CTRL); -		writel(0, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN); -		writel(0, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN); -	} else if ((sspi->left_tx_word > 1) && (sspi->left_tx_word < -				SIRFSOC_SPI_DAT_FRM_LEN_MAX)) { +	sspi = spi_master_get_devdata(spi->master); +	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP); +	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP); +	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP); +	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP); +	writel(0, sspi->base + SIRFSOC_SPI_INT_EN); +	writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS); +	if (sspi->left_tx_word < SIRFSOC_SPI_DAT_FRM_LEN_MAX) {  		writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | -				SIRFSOC_SPI_MUL_DAT_MODE | -				SIRFSOC_SPI_ENA_AUTO_CLR, +			SIRFSOC_SPI_ENA_AUTO_CLR | SIRFSOC_SPI_MUL_DAT_MODE,  			sspi->base + SIRFSOC_SPI_CTRL);  		writel(sspi->left_tx_word - 1,  				sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN); @@ -332,76 +360,122 @@ static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t)  		writel(0, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN);  		writel(0, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN);  	} - -	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP); -	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP); -	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP); -	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP); - -	if (IS_DMA_VALID(t)) { -		struct dma_async_tx_descriptor *rx_desc, *tx_desc; - -		sspi->dst_start = dma_map_single(&spi->dev, sspi->rx, t->len, DMA_FROM_DEVICE); -		rx_desc = dmaengine_prep_slave_single(sspi->rx_chan, -			sspi->dst_start, t->len, DMA_DEV_TO_MEM, -			DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -		rx_desc->callback = spi_sirfsoc_dma_fini_callback; -		rx_desc->callback_param = &sspi->rx_done; - -		sspi->src_start = dma_map_single(&spi->dev, (void *)sspi->tx, t->len, DMA_TO_DEVICE); -		tx_desc = dmaengine_prep_slave_single(sspi->tx_chan, -			sspi->src_start, t->len, DMA_MEM_TO_DEV, -			DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -		tx_desc->callback = spi_sirfsoc_dma_fini_callback; -		tx_desc->callback_param = &sspi->tx_done; - -		dmaengine_submit(tx_desc); -		dmaengine_submit(rx_desc); -		dma_async_issue_pending(sspi->tx_chan); -		dma_async_issue_pending(sspi->rx_chan); -	} else { -		/* Send the first word to trigger the whole tx/rx process */ -		sspi->tx_word(sspi); - -		writel(SIRFSOC_SPI_RX_OFLOW_INT_EN | SIRFSOC_SPI_TX_UFLOW_INT_EN | -			SIRFSOC_SPI_RXFIFO_THD_INT_EN | SIRFSOC_SPI_TXFIFO_THD_INT_EN | -			SIRFSOC_SPI_FRM_END_INT_EN | SIRFSOC_SPI_RXFIFO_FULL_INT_EN | -			SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN, sspi->base + SIRFSOC_SPI_INT_EN); -	} - -	writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN, sspi->base + SIRFSOC_SPI_TX_RX_EN); - -	if (!IS_DMA_VALID(t)) { /* for PIO */ -		if (wait_for_completion_timeout(&sspi->rx_done, timeout) == 0) -			dev_err(&spi->dev, "transfer timeout\n"); -	} else if (wait_for_completion_timeout(&sspi->rx_done, timeout) == 0) { +	sspi->dst_start = dma_map_single(&spi->dev, sspi->rx, t->len, +					(t->tx_buf != t->rx_buf) ? +					DMA_FROM_DEVICE : DMA_BIDIRECTIONAL); +	rx_desc = dmaengine_prep_slave_single(sspi->rx_chan, +		sspi->dst_start, t->len, DMA_DEV_TO_MEM, +		DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +	rx_desc->callback = spi_sirfsoc_dma_fini_callback; +	rx_desc->callback_param = &sspi->rx_done; + +	sspi->src_start = dma_map_single(&spi->dev, (void *)sspi->tx, t->len, +					(t->tx_buf != t->rx_buf) ? +					DMA_TO_DEVICE : DMA_BIDIRECTIONAL); +	tx_desc = dmaengine_prep_slave_single(sspi->tx_chan, +		sspi->src_start, t->len, DMA_MEM_TO_DEV, +		DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +	tx_desc->callback = spi_sirfsoc_dma_fini_callback; +	tx_desc->callback_param = &sspi->tx_done; + +	dmaengine_submit(tx_desc); +	dmaengine_submit(rx_desc); +	dma_async_issue_pending(sspi->tx_chan); +	dma_async_issue_pending(sspi->rx_chan); +	writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN, +			sspi->base + SIRFSOC_SPI_TX_RX_EN); +	if (wait_for_completion_timeout(&sspi->rx_done, timeout) == 0) {  		dev_err(&spi->dev, "transfer timeout\n");  		dmaengine_terminate_all(sspi->rx_chan);  	} else  		sspi->left_rx_word = 0; -  	/*  	 * we only wait tx-done event if transferring by DMA. for PIO,  	 * we get rx data by writing tx data, so if rx is done, tx has  	 * done earlier  	 */ -	if (IS_DMA_VALID(t)) { -		if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { -			dev_err(&spi->dev, "transfer timeout\n"); -			dmaengine_terminate_all(sspi->tx_chan); -		} -	} - -	if (IS_DMA_VALID(t)) { -		dma_unmap_single(&spi->dev, sspi->src_start, t->len, DMA_TO_DEVICE); -		dma_unmap_single(&spi->dev, sspi->dst_start, t->len, DMA_FROM_DEVICE); +	if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { +		dev_err(&spi->dev, "transfer timeout\n"); +		dmaengine_terminate_all(sspi->tx_chan);  	} - +	dma_unmap_single(&spi->dev, sspi->src_start, t->len, DMA_TO_DEVICE); +	dma_unmap_single(&spi->dev, sspi->dst_start, t->len, DMA_FROM_DEVICE);  	/* TX, RX FIFO stop */  	writel(0, sspi->base + SIRFSOC_SPI_RXFIFO_OP);  	writel(0, sspi->base + SIRFSOC_SPI_TXFIFO_OP); -	writel(0, sspi->base + SIRFSOC_SPI_TX_RX_EN); -	writel(0, sspi->base + SIRFSOC_SPI_INT_EN); +	if (sspi->left_tx_word >= SIRFSOC_SPI_DAT_FRM_LEN_MAX) +		writel(0, sspi->base + SIRFSOC_SPI_TX_RX_EN); +} + +static void spi_sirfsoc_pio_transfer(struct spi_device *spi, +		struct spi_transfer *t) +{ +	struct sirfsoc_spi *sspi; +	int timeout = t->len * 10; + +	sspi = spi_master_get_devdata(spi->master); +	do { +		writel(SIRFSOC_SPI_FIFO_RESET, +			sspi->base + SIRFSOC_SPI_RXFIFO_OP); +		writel(SIRFSOC_SPI_FIFO_RESET, +			sspi->base + SIRFSOC_SPI_TXFIFO_OP); +		writel(SIRFSOC_SPI_FIFO_START, +			sspi->base + SIRFSOC_SPI_RXFIFO_OP); +		writel(SIRFSOC_SPI_FIFO_START, +			sspi->base + SIRFSOC_SPI_TXFIFO_OP); +		writel(0, sspi->base + SIRFSOC_SPI_INT_EN); +		writel(SIRFSOC_SPI_INT_MASK_ALL, +			sspi->base + SIRFSOC_SPI_INT_STATUS); +		writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | +			SIRFSOC_SPI_MUL_DAT_MODE | SIRFSOC_SPI_ENA_AUTO_CLR, +			sspi->base + SIRFSOC_SPI_CTRL); +		writel(min(sspi->left_tx_word, (u32)(256 / sspi->word_width)) +				- 1, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN); +		writel(min(sspi->left_rx_word, (u32)(256 / sspi->word_width)) +				- 1, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN); +		while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) +			& SIRFSOC_SPI_FIFO_FULL)) && sspi->left_tx_word) +			sspi->tx_word(sspi); +		writel(SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN | +			SIRFSOC_SPI_TX_UFLOW_INT_EN | +			SIRFSOC_SPI_RX_OFLOW_INT_EN, +			sspi->base + SIRFSOC_SPI_INT_EN); +		writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN, +			sspi->base + SIRFSOC_SPI_TX_RX_EN); +		if (!wait_for_completion_timeout(&sspi->tx_done, timeout) || +			!wait_for_completion_timeout(&sspi->rx_done, timeout)) { +			dev_err(&spi->dev, "transfer timeout\n"); +			break; +		} +		while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS) +			& SIRFSOC_SPI_FIFO_EMPTY)) && sspi->left_rx_word) +			sspi->rx_word(sspi); +		writel(0, sspi->base + SIRFSOC_SPI_RXFIFO_OP); +		writel(0, sspi->base + SIRFSOC_SPI_TXFIFO_OP); +	} while (sspi->left_tx_word != 0 || sspi->left_rx_word != 0); +} + +static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t) +{ +	struct sirfsoc_spi *sspi; +	sspi = spi_master_get_devdata(spi->master); + +	sspi->tx = t->tx_buf ? t->tx_buf : sspi->dummypage; +	sspi->rx = t->rx_buf ? t->rx_buf : sspi->dummypage; +	sspi->left_tx_word = sspi->left_rx_word = t->len / sspi->word_width; +	reinit_completion(&sspi->rx_done); +	reinit_completion(&sspi->tx_done); +	/* +	 * in the transfer, if transfer data using command register with rx_buf +	 * null, just fill command data into command register and wait for its +	 * completion. +	 */ +	if (sspi->tx_by_cmd) +		spi_sirfsoc_cmd_transfer(spi, t); +	else if (IS_DMA_VALID(t)) +		spi_sirfsoc_dma_transfer(spi, t); +	else +		spi_sirfsoc_pio_transfer(spi, t);  	return t->len - sspi->left_rx_word * sspi->word_width;  } @@ -429,7 +503,16 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value)  		writel(regval, sspi->base + SIRFSOC_SPI_CTRL);  	} else {  		int gpio = sspi->chipselect[spi->chip_select]; -		gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); +		switch (value) { +		case BITBANG_CS_ACTIVE: +			gpio_direction_output(gpio, +					spi->mode & SPI_CS_HIGH ? 1 : 0); +			break; +		case BITBANG_CS_INACTIVE: +			gpio_direction_output(gpio, +					spi->mode & SPI_CS_HIGH ? 0 : 1); +			break; +		}  	}  } @@ -459,38 +542,30 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  		regval |= SIRFSOC_SPI_TRAN_DAT_FORMAT_8;  		sspi->rx_word = spi_sirfsoc_rx_word_u8;  		sspi->tx_word = spi_sirfsoc_tx_word_u8; -		txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | -					SIRFSOC_SPI_FIFO_WIDTH_BYTE; -		rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | -					SIRFSOC_SPI_FIFO_WIDTH_BYTE; -		sspi->word_width = 1;  		break;  	case 12:  	case 16: -		regval |= (bits_per_word ==  12) ? SIRFSOC_SPI_TRAN_DAT_FORMAT_12 : +		regval |= (bits_per_word ==  12) ? +			SIRFSOC_SPI_TRAN_DAT_FORMAT_12 :  			SIRFSOC_SPI_TRAN_DAT_FORMAT_16;  		sspi->rx_word = spi_sirfsoc_rx_word_u16;  		sspi->tx_word = spi_sirfsoc_tx_word_u16; -		txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | -					SIRFSOC_SPI_FIFO_WIDTH_WORD; -		rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | -					SIRFSOC_SPI_FIFO_WIDTH_WORD; -		sspi->word_width = 2;  		break;  	case 32:  		regval |= SIRFSOC_SPI_TRAN_DAT_FORMAT_32;  		sspi->rx_word = spi_sirfsoc_rx_word_u32;  		sspi->tx_word = spi_sirfsoc_tx_word_u32; -		txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | -					SIRFSOC_SPI_FIFO_WIDTH_DWORD; -		rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | -					SIRFSOC_SPI_FIFO_WIDTH_DWORD; -		sspi->word_width = 4;  		break;  	default:  		BUG();  	} +	sspi->word_width = DIV_ROUND_UP(bits_per_word, 8); +	txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | +					   sspi->word_width; +	rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | +					   sspi->word_width; +  	if (!(spi->mode & SPI_CS_HIGH))  		regval |= SIRFSOC_SPI_CS_IDLE_STAT;  	if (!(spi->mode & SPI_LSB_FIRST)) @@ -499,8 +574,8 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  		regval |= SIRFSOC_SPI_CLK_IDLE_STAT;  	/* -	 * Data should be driven at least 1/2 cycle before the fetch edge to make -	 * sure that data gets stable at the fetch edge. +	 * Data should be driven at least 1/2 cycle before the fetch edge +	 * to make sure that data gets stable at the fetch edge.  	 */  	if (((spi->mode & SPI_CPOL) && (spi->mode & SPI_CPHA)) ||  	    (!(spi->mode & SPI_CPOL) && !(spi->mode & SPI_CPHA))) @@ -519,16 +594,32 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  	writel(txfifo_ctrl, sspi->base + SIRFSOC_SPI_TXFIFO_CTRL);  	writel(rxfifo_ctrl, sspi->base + SIRFSOC_SPI_RXFIFO_CTRL); +	if (t && t->tx_buf && !t->rx_buf && (t->len <= SIRFSOC_MAX_CMD_BYTES)) { +		regval |= (SIRFSOC_SPI_CMD_BYTE_NUM((t->len - 1)) | +				SIRFSOC_SPI_CMD_MODE); +		sspi->tx_by_cmd = true; +	} else { +		regval &= ~SIRFSOC_SPI_CMD_MODE; +		sspi->tx_by_cmd = false; +	} +	/* +	 * set spi controller in RISC chipselect mode, we are controlling CS by +	 * software BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE. +	 */ +	regval |= SIRFSOC_SPI_CS_IO_MODE;  	writel(regval, sspi->base + SIRFSOC_SPI_CTRL);  	if (IS_DMA_VALID(t)) {  		/* Enable DMA mode for RX, TX */  		writel(0, sspi->base + SIRFSOC_SPI_TX_DMA_IO_CTRL); -		writel(SIRFSOC_SPI_RX_DMA_FLUSH, sspi->base + SIRFSOC_SPI_RX_DMA_IO_CTRL); +		writel(SIRFSOC_SPI_RX_DMA_FLUSH, +			sspi->base + SIRFSOC_SPI_RX_DMA_IO_CTRL);  	} else {  		/* Enable IO mode for RX, TX */ -		writel(SIRFSOC_SPI_IO_MODE_SEL, sspi->base + SIRFSOC_SPI_TX_DMA_IO_CTRL); -		writel(SIRFSOC_SPI_IO_MODE_SEL, sspi->base + SIRFSOC_SPI_RX_DMA_IO_CTRL); +		writel(SIRFSOC_SPI_IO_MODE_SEL, +			sspi->base + SIRFSOC_SPI_TX_DMA_IO_CTRL); +		writel(SIRFSOC_SPI_IO_MODE_SEL, +			sspi->base + SIRFSOC_SPI_RX_DMA_IO_CTRL);  	}  	return 0; @@ -536,16 +627,9 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  static int spi_sirfsoc_setup(struct spi_device *spi)  { -	struct sirfsoc_spi *sspi; -  	if (!spi->max_speed_hz)  		return -EINVAL; -	sspi = spi_master_get_devdata(spi->master); - -	if (!spi->bits_per_word) -		spi->bits_per_word = 8; -  	return spi_sirfsoc_setup_transfer(spi, NULL);  } @@ -555,8 +639,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)  	struct spi_master *master;  	struct resource *mem_res;  	int num_cs, cs_gpio, irq; -	u32 rx_dma_ch, tx_dma_ch; -	dma_cap_mask_t dma_cap_mask;  	int i;  	int ret; @@ -567,21 +649,8 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)  		goto err_cs;  	} -	ret = of_property_read_u32(pdev->dev.of_node, -			"sirf,spi-dma-rx-channel", &rx_dma_ch); -	if (ret < 0) { -		dev_err(&pdev->dev, "Unable to get rx dma channel\n"); -		goto err_cs; -	} - -	ret = of_property_read_u32(pdev->dev.of_node, -			"sirf,spi-dma-tx-channel", &tx_dma_ch); -	if (ret < 0) { -		dev_err(&pdev->dev, "Unable to get tx dma channel\n"); -		goto err_cs; -	} - -	master = spi_alloc_master(&pdev->dev, sizeof(*sspi) + sizeof(int) * num_cs); +	master = spi_alloc_master(&pdev->dev, +			sizeof(*sspi) + sizeof(int) * num_cs);  	if (!master) {  		dev_err(&pdev->dev, "Unable to allocate SPI master\n");  		return -ENOMEM; @@ -632,7 +701,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)  	if (ret)  		goto free_master; -	sspi->bitbang.master = spi_master_get(master); +	sspi->bitbang.master = master;  	sspi->bitbang.chipselect = spi_sirfsoc_chipselect;  	sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer;  	sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; @@ -644,18 +713,13 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)  	sspi->bitbang.master->dev.of_node = pdev->dev.of_node;  	/* request DMA channels */ -	dma_cap_zero(dma_cap_mask); -	dma_cap_set(DMA_INTERLEAVE, dma_cap_mask); - -	sspi->rx_chan = dma_request_channel(dma_cap_mask, (dma_filter_fn)sirfsoc_dma_filter_id, -		(void *)rx_dma_ch); +	sspi->rx_chan = dma_request_slave_channel(&pdev->dev, "rx");  	if (!sspi->rx_chan) {  		dev_err(&pdev->dev, "can not allocate rx dma channel\n");  		ret = -ENODEV;  		goto free_master;  	} -	sspi->tx_chan = dma_request_channel(dma_cap_mask, (dma_filter_fn)sirfsoc_dma_filter_id, -		(void *)tx_dma_ch); +	sspi->tx_chan = dma_request_slave_channel(&pdev->dev, "tx");  	if (!sspi->tx_chan) {  		dev_err(&pdev->dev, "can not allocate tx dma channel\n");  		ret = -ENODEV; @@ -731,11 +795,16 @@ static int  spi_sirfsoc_remove(struct platform_device *pdev)  	return 0;  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int spi_sirfsoc_suspend(struct device *dev)  {  	struct spi_master *master = dev_get_drvdata(dev);  	struct sirfsoc_spi *sspi = spi_master_get_devdata(master); +	int ret; + +	ret = spi_master_suspend(master); +	if (ret) +		return ret;  	clk_disable(sspi->clk);  	return 0; @@ -752,15 +821,13 @@ static int spi_sirfsoc_resume(struct device *dev)  	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP);  	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP); -	return 0; +	return spi_master_resume(master);  } - -static const struct dev_pm_ops spi_sirfsoc_pm_ops = { -	.suspend = spi_sirfsoc_suspend, -	.resume = spi_sirfsoc_resume, -};  #endif +static SIMPLE_DEV_PM_OPS(spi_sirfsoc_pm_ops, spi_sirfsoc_suspend, +			 spi_sirfsoc_resume); +  static const struct of_device_id spi_sirfsoc_of_match[] = {  	{ .compatible = "sirf,prima2-spi", },  	{ .compatible = "sirf,marco-spi", }, @@ -772,17 +839,14 @@ static struct platform_driver spi_sirfsoc_driver = {  	.driver = {  		.name = DRIVER_NAME,  		.owner = THIS_MODULE, -#ifdef CONFIG_PM  		.pm     = &spi_sirfsoc_pm_ops, -#endif  		.of_match_table = spi_sirfsoc_of_match,  	},  	.probe = spi_sirfsoc_probe,  	.remove = spi_sirfsoc_remove,  };  module_platform_driver(spi_sirfsoc_driver); -  MODULE_DESCRIPTION("SiRF SoC SPI master driver"); -MODULE_AUTHOR("Zhiwu Song <Zhiwu.Song@csr.com>, " -		"Barry Song <Baohua.Song@csr.com>"); +MODULE_AUTHOR("Zhiwu Song <Zhiwu.Song@csr.com>"); +MODULE_AUTHOR("Barry Song <Baohua.Song@csr.com>");  MODULE_LICENSE("GPL v2"); diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c new file mode 100644 index 00000000000..85204c93f3d --- /dev/null +++ b/drivers/spi/spi-sun4i.c @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2012 - 2014 Allwinner Tech + * Pan Nan <pannan@allwinnertech.com> + * + * Copyright (C) 2014 Maxime Ripard + * Maxime Ripard <maxime.ripard@free-electrons.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +#include <linux/spi/spi.h> + +#define SUN4I_FIFO_DEPTH		64 + +#define SUN4I_RXDATA_REG		0x00 + +#define SUN4I_TXDATA_REG		0x04 + +#define SUN4I_CTL_REG			0x08 +#define SUN4I_CTL_ENABLE			BIT(0) +#define SUN4I_CTL_MASTER			BIT(1) +#define SUN4I_CTL_CPHA				BIT(2) +#define SUN4I_CTL_CPOL				BIT(3) +#define SUN4I_CTL_CS_ACTIVE_LOW			BIT(4) +#define SUN4I_CTL_LMTF				BIT(6) +#define SUN4I_CTL_TF_RST			BIT(8) +#define SUN4I_CTL_RF_RST			BIT(9) +#define SUN4I_CTL_XCH				BIT(10) +#define SUN4I_CTL_CS_MASK			0x3000 +#define SUN4I_CTL_CS(cs)			(((cs) << 12) & SUN4I_CTL_CS_MASK) +#define SUN4I_CTL_DHB				BIT(15) +#define SUN4I_CTL_CS_MANUAL			BIT(16) +#define SUN4I_CTL_CS_LEVEL			BIT(17) +#define SUN4I_CTL_TP				BIT(18) + +#define SUN4I_INT_CTL_REG		0x0c +#define SUN4I_INT_CTL_TC			BIT(16) + +#define SUN4I_INT_STA_REG		0x10 + +#define SUN4I_DMA_CTL_REG		0x14 + +#define SUN4I_WAIT_REG			0x18 + +#define SUN4I_CLK_CTL_REG		0x1c +#define SUN4I_CLK_CTL_CDR2_MASK			0xff +#define SUN4I_CLK_CTL_CDR2(div)			((div) & SUN4I_CLK_CTL_CDR2_MASK) +#define SUN4I_CLK_CTL_CDR1_MASK			0xf +#define SUN4I_CLK_CTL_CDR1(div)			(((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8) +#define SUN4I_CLK_CTL_DRS			BIT(12) + +#define SUN4I_BURST_CNT_REG		0x20 +#define SUN4I_BURST_CNT(cnt)			((cnt) & 0xffffff) + +#define SUN4I_XMIT_CNT_REG		0x24 +#define SUN4I_XMIT_CNT(cnt)			((cnt) & 0xffffff) + +#define SUN4I_FIFO_STA_REG		0x28 +#define SUN4I_FIFO_STA_RF_CNT_MASK		0x7f +#define SUN4I_FIFO_STA_RF_CNT_BITS		0 +#define SUN4I_FIFO_STA_TF_CNT_MASK		0x7f +#define SUN4I_FIFO_STA_TF_CNT_BITS		16 + +struct sun4i_spi { +	struct spi_master	*master; +	void __iomem		*base_addr; +	struct clk		*hclk; +	struct clk		*mclk; + +	struct completion	done; + +	const u8		*tx_buf; +	u8			*rx_buf; +	int			len; +}; + +static inline u32 sun4i_spi_read(struct sun4i_spi *sspi, u32 reg) +{ +	return readl(sspi->base_addr + reg); +} + +static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value) +{ +	writel(value, sspi->base_addr + reg); +} + +static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) +{ +	u32 reg, cnt; +	u8 byte; + +	/* See how much data is available */ +	reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG); +	reg &= SUN4I_FIFO_STA_RF_CNT_MASK; +	cnt = reg >> SUN4I_FIFO_STA_RF_CNT_BITS; + +	if (len > cnt) +		len = cnt; + +	while (len--) { +		byte = readb(sspi->base_addr + SUN4I_RXDATA_REG); +		if (sspi->rx_buf) +			*sspi->rx_buf++ = byte; +	} +} + +static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) +{ +	u8 byte; + +	if (len > sspi->len) +		len = sspi->len; + +	while (len--) { +		byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; +		writeb(byte, sspi->base_addr + SUN4I_TXDATA_REG); +		sspi->len--; +	} +} + +static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) +{ +	struct sun4i_spi *sspi = spi_master_get_devdata(spi->master); +	u32 reg; + +	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); + +	reg &= ~SUN4I_CTL_CS_MASK; +	reg |= SUN4I_CTL_CS(spi->chip_select); + +	if (enable) +		reg |= SUN4I_CTL_CS_LEVEL; +	else +		reg &= ~SUN4I_CTL_CS_LEVEL; + +	/* +	 * Even though this looks irrelevant since we are supposed to +	 * be controlling the chip select manually, this bit also +	 * controls the levels of the chip select for inactive +	 * devices. +	 * +	 * If we don't set it, the chip select level will go low by +	 * default when the device is idle, which is not really +	 * expected in the common case where the chip select is active +	 * low. +	 */ +	if (spi->mode & SPI_CS_HIGH) +		reg &= ~SUN4I_CTL_CS_ACTIVE_LOW; +	else +		reg |= SUN4I_CTL_CS_ACTIVE_LOW; + +	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); +} + +static int sun4i_spi_transfer_one(struct spi_master *master, +				  struct spi_device *spi, +				  struct spi_transfer *tfr) +{ +	struct sun4i_spi *sspi = spi_master_get_devdata(master); +	unsigned int mclk_rate, div, timeout; +	unsigned int tx_len = 0; +	int ret = 0; +	u32 reg; + +	/* We don't support transfer larger than the FIFO */ +	if (tfr->len > SUN4I_FIFO_DEPTH) +		return -EINVAL; + +	reinit_completion(&sspi->done); +	sspi->tx_buf = tfr->tx_buf; +	sspi->rx_buf = tfr->rx_buf; +	sspi->len = tfr->len; + +	/* Clear pending interrupts */ +	sun4i_spi_write(sspi, SUN4I_INT_STA_REG, ~0); + + +	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); + +	/* Reset FIFOs */ +	sun4i_spi_write(sspi, SUN4I_CTL_REG, +			reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST); + +	/* +	 * Setup the transfer control register: Chip Select, +	 * polarities, etc. +	 */ +	if (spi->mode & SPI_CPOL) +		reg |= SUN4I_CTL_CPOL; +	else +		reg &= ~SUN4I_CTL_CPOL; + +	if (spi->mode & SPI_CPHA) +		reg |= SUN4I_CTL_CPHA; +	else +		reg &= ~SUN4I_CTL_CPHA; + +	if (spi->mode & SPI_LSB_FIRST) +		reg |= SUN4I_CTL_LMTF; +	else +		reg &= ~SUN4I_CTL_LMTF; + + +	/* +	 * If it's a TX only transfer, we don't want to fill the RX +	 * FIFO with bogus data +	 */ +	if (sspi->rx_buf) +		reg &= ~SUN4I_CTL_DHB; +	else +		reg |= SUN4I_CTL_DHB; + +	/* We want to control the chip select manually */ +	reg |= SUN4I_CTL_CS_MANUAL; + +	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); + +	/* Ensure that we have a parent clock fast enough */ +	mclk_rate = clk_get_rate(sspi->mclk); +	if (mclk_rate < (2 * spi->max_speed_hz)) { +		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz); +		mclk_rate = clk_get_rate(sspi->mclk); +	} + +	/* +	 * Setup clock divider. +	 * +	 * We have two choices there. Either we can use the clock +	 * divide rate 1, which is calculated thanks to this formula: +	 * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1)) +	 * Or we can use CDR2, which is calculated with the formula: +	 * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) +	 * Wether we use the former or the latter is set through the +	 * DRS bit. +	 * +	 * First try CDR2, and if we can't reach the expected +	 * frequency, fall back to CDR1. +	 */ +	div = mclk_rate / (2 * spi->max_speed_hz); +	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { +		if (div > 0) +			div--; + +		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; +	} else { +		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz); +		reg = SUN4I_CLK_CTL_CDR1(div); +	} + +	sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg); + +	/* Setup the transfer now... */ +	if (sspi->tx_buf) +		tx_len = tfr->len; + +	/* Setup the counters */ +	sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); +	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); + +	/* Fill the TX FIFO */ +	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); + +	/* Enable the interrupts */ +	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); + +	/* Start the transfer */ +	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); +	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH); + +	timeout = wait_for_completion_timeout(&sspi->done, +					      msecs_to_jiffies(1000)); +	if (!timeout) { +		ret = -ETIMEDOUT; +		goto out; +	} + +	sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); + +out: +	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); + +	return ret; +} + +static irqreturn_t sun4i_spi_handler(int irq, void *dev_id) +{ +	struct sun4i_spi *sspi = dev_id; +	u32 status = sun4i_spi_read(sspi, SUN4I_INT_STA_REG); + +	/* Transfer complete */ +	if (status & SUN4I_INT_CTL_TC) { +		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC); +		complete(&sspi->done); +		return IRQ_HANDLED; +	} + +	return IRQ_NONE; +} + +static int sun4i_spi_runtime_resume(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct sun4i_spi *sspi = spi_master_get_devdata(master); +	int ret; + +	ret = clk_prepare_enable(sspi->hclk); +	if (ret) { +		dev_err(dev, "Couldn't enable AHB clock\n"); +		goto out; +	} + +	ret = clk_prepare_enable(sspi->mclk); +	if (ret) { +		dev_err(dev, "Couldn't enable module clock\n"); +		goto err; +	} + +	sun4i_spi_write(sspi, SUN4I_CTL_REG, +			SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP); + +	return 0; + +err: +	clk_disable_unprepare(sspi->hclk); +out: +	return ret; +} + +static int sun4i_spi_runtime_suspend(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct sun4i_spi *sspi = spi_master_get_devdata(master); + +	clk_disable_unprepare(sspi->mclk); +	clk_disable_unprepare(sspi->hclk); + +	return 0; +} + +static int sun4i_spi_probe(struct platform_device *pdev) +{ +	struct spi_master *master; +	struct sun4i_spi *sspi; +	struct resource	*res; +	int ret = 0, irq; + +	master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi)); +	if (!master) { +		dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); +		return -ENOMEM; +	} + +	platform_set_drvdata(pdev, master); +	sspi = spi_master_get_devdata(master); + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	sspi->base_addr = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(sspi->base_addr)) { +		ret = PTR_ERR(sspi->base_addr); +		goto err_free_master; +	} + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(&pdev->dev, "No spi IRQ specified\n"); +		ret = -ENXIO; +		goto err_free_master; +	} + +	ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler, +			       0, "sun4i-spi", sspi); +	if (ret) { +		dev_err(&pdev->dev, "Cannot request IRQ\n"); +		goto err_free_master; +	} + +	sspi->master = master; +	master->set_cs = sun4i_spi_set_cs; +	master->transfer_one = sun4i_spi_transfer_one; +	master->num_chipselect = 4; +	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; +	master->bits_per_word_mask = SPI_BPW_MASK(8); +	master->dev.of_node = pdev->dev.of_node; +	master->auto_runtime_pm = true; + +	sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); +	if (IS_ERR(sspi->hclk)) { +		dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); +		ret = PTR_ERR(sspi->hclk); +		goto err_free_master; +	} + +	sspi->mclk = devm_clk_get(&pdev->dev, "mod"); +	if (IS_ERR(sspi->mclk)) { +		dev_err(&pdev->dev, "Unable to acquire module clock\n"); +		ret = PTR_ERR(sspi->mclk); +		goto err_free_master; +	} + +	init_completion(&sspi->done); + +	/* +	 * This wake-up/shutdown pattern is to be able to have the +	 * device woken up, even if runtime_pm is disabled +	 */ +	ret = sun4i_spi_runtime_resume(&pdev->dev); +	if (ret) { +		dev_err(&pdev->dev, "Couldn't resume the device\n"); +		goto err_free_master; +	} + +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_enable(&pdev->dev); +	pm_runtime_idle(&pdev->dev); + +	ret = devm_spi_register_master(&pdev->dev, master); +	if (ret) { +		dev_err(&pdev->dev, "cannot register SPI master\n"); +		goto err_pm_disable; +	} + +	return 0; + +err_pm_disable: +	pm_runtime_disable(&pdev->dev); +	sun4i_spi_runtime_suspend(&pdev->dev); +err_free_master: +	spi_master_put(master); +	return ret; +} + +static int sun4i_spi_remove(struct platform_device *pdev) +{ +	pm_runtime_disable(&pdev->dev); + +	return 0; +} + +static const struct of_device_id sun4i_spi_match[] = { +	{ .compatible = "allwinner,sun4i-a10-spi", }, +	{} +}; +MODULE_DEVICE_TABLE(of, sun4i_spi_match); + +static const struct dev_pm_ops sun4i_spi_pm_ops = { +	.runtime_resume		= sun4i_spi_runtime_resume, +	.runtime_suspend	= sun4i_spi_runtime_suspend, +}; + +static struct platform_driver sun4i_spi_driver = { +	.probe	= sun4i_spi_probe, +	.remove	= sun4i_spi_remove, +	.driver	= { +		.name		= "sun4i-spi", +		.owner		= THIS_MODULE, +		.of_match_table	= sun4i_spi_match, +		.pm		= &sun4i_spi_pm_ops, +	}, +}; +module_platform_driver(sun4i_spi_driver); + +MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>"); +MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); +MODULE_DESCRIPTION("Allwinner A1X/A20 SPI controller driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c new file mode 100644 index 00000000000..bd24093f403 --- /dev/null +++ b/drivers/spi/spi-sun6i.c @@ -0,0 +1,483 @@ +/* + * Copyright (C) 2012 - 2014 Allwinner Tech + * Pan Nan <pannan@allwinnertech.com> + * + * Copyright (C) 2014 Maxime Ripard + * Maxime Ripard <maxime.ripard@free-electrons.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> + +#include <linux/spi/spi.h> + +#define SUN6I_FIFO_DEPTH		128 + +#define SUN6I_GBL_CTL_REG		0x04 +#define SUN6I_GBL_CTL_BUS_ENABLE		BIT(0) +#define SUN6I_GBL_CTL_MASTER			BIT(1) +#define SUN6I_GBL_CTL_TP			BIT(7) +#define SUN6I_GBL_CTL_RST			BIT(31) + +#define SUN6I_TFR_CTL_REG		0x08 +#define SUN6I_TFR_CTL_CPHA			BIT(0) +#define SUN6I_TFR_CTL_CPOL			BIT(1) +#define SUN6I_TFR_CTL_SPOL			BIT(2) +#define SUN6I_TFR_CTL_CS_MASK			0x30 +#define SUN6I_TFR_CTL_CS(cs)			(((cs) << 4) & SUN6I_TFR_CTL_CS_MASK) +#define SUN6I_TFR_CTL_CS_MANUAL			BIT(6) +#define SUN6I_TFR_CTL_CS_LEVEL			BIT(7) +#define SUN6I_TFR_CTL_DHB			BIT(8) +#define SUN6I_TFR_CTL_FBS			BIT(12) +#define SUN6I_TFR_CTL_XCH			BIT(31) + +#define SUN6I_INT_CTL_REG		0x10 +#define SUN6I_INT_CTL_RF_OVF			BIT(8) +#define SUN6I_INT_CTL_TC			BIT(12) + +#define SUN6I_INT_STA_REG		0x14 + +#define SUN6I_FIFO_CTL_REG		0x18 +#define SUN6I_FIFO_CTL_RF_RST			BIT(15) +#define SUN6I_FIFO_CTL_TF_RST			BIT(31) + +#define SUN6I_FIFO_STA_REG		0x1c +#define SUN6I_FIFO_STA_RF_CNT_MASK		0x7f +#define SUN6I_FIFO_STA_RF_CNT_BITS		0 +#define SUN6I_FIFO_STA_TF_CNT_MASK		0x7f +#define SUN6I_FIFO_STA_TF_CNT_BITS		16 + +#define SUN6I_CLK_CTL_REG		0x24 +#define SUN6I_CLK_CTL_CDR2_MASK			0xff +#define SUN6I_CLK_CTL_CDR2(div)			(((div) & SUN6I_CLK_CTL_CDR2_MASK) << 0) +#define SUN6I_CLK_CTL_CDR1_MASK			0xf +#define SUN6I_CLK_CTL_CDR1(div)			(((div) & SUN6I_CLK_CTL_CDR1_MASK) << 8) +#define SUN6I_CLK_CTL_DRS			BIT(12) + +#define SUN6I_BURST_CNT_REG		0x30 +#define SUN6I_BURST_CNT(cnt)			((cnt) & 0xffffff) + +#define SUN6I_XMIT_CNT_REG		0x34 +#define SUN6I_XMIT_CNT(cnt)			((cnt) & 0xffffff) + +#define SUN6I_BURST_CTL_CNT_REG		0x38 +#define SUN6I_BURST_CTL_CNT_STC(cnt)		((cnt) & 0xffffff) + +#define SUN6I_TXDATA_REG		0x200 +#define SUN6I_RXDATA_REG		0x300 + +struct sun6i_spi { +	struct spi_master	*master; +	void __iomem		*base_addr; +	struct clk		*hclk; +	struct clk		*mclk; +	struct reset_control	*rstc; + +	struct completion	done; + +	const u8		*tx_buf; +	u8			*rx_buf; +	int			len; +}; + +static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) +{ +	return readl(sspi->base_addr + reg); +} + +static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value) +{ +	writel(value, sspi->base_addr + reg); +} + +static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len) +{ +	u32 reg, cnt; +	u8 byte; + +	/* See how much data is available */ +	reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); +	reg &= SUN6I_FIFO_STA_RF_CNT_MASK; +	cnt = reg >> SUN6I_FIFO_STA_RF_CNT_BITS; + +	if (len > cnt) +		len = cnt; + +	while (len--) { +		byte = readb(sspi->base_addr + SUN6I_RXDATA_REG); +		if (sspi->rx_buf) +			*sspi->rx_buf++ = byte; +	} +} + +static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi, int len) +{ +	u8 byte; + +	if (len > sspi->len) +		len = sspi->len; + +	while (len--) { +		byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; +		writeb(byte, sspi->base_addr + SUN6I_TXDATA_REG); +		sspi->len--; +	} +} + +static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) +{ +	struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); +	u32 reg; + +	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); +	reg &= ~SUN6I_TFR_CTL_CS_MASK; +	reg |= SUN6I_TFR_CTL_CS(spi->chip_select); + +	if (enable) +		reg |= SUN6I_TFR_CTL_CS_LEVEL; +	else +		reg &= ~SUN6I_TFR_CTL_CS_LEVEL; + +	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); +} + + +static int sun6i_spi_transfer_one(struct spi_master *master, +				  struct spi_device *spi, +				  struct spi_transfer *tfr) +{ +	struct sun6i_spi *sspi = spi_master_get_devdata(master); +	unsigned int mclk_rate, div, timeout; +	unsigned int tx_len = 0; +	int ret = 0; +	u32 reg; + +	/* We don't support transfer larger than the FIFO */ +	if (tfr->len > SUN6I_FIFO_DEPTH) +		return -EINVAL; + +	reinit_completion(&sspi->done); +	sspi->tx_buf = tfr->tx_buf; +	sspi->rx_buf = tfr->rx_buf; +	sspi->len = tfr->len; + +	/* Clear pending interrupts */ +	sun6i_spi_write(sspi, SUN6I_INT_STA_REG, ~0); + +	/* Reset FIFO */ +	sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, +			SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST); + +	/* +	 * Setup the transfer control register: Chip Select, +	 * polarities, etc. +	 */ +	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); + +	if (spi->mode & SPI_CPOL) +		reg |= SUN6I_TFR_CTL_CPOL; +	else +		reg &= ~SUN6I_TFR_CTL_CPOL; + +	if (spi->mode & SPI_CPHA) +		reg |= SUN6I_TFR_CTL_CPHA; +	else +		reg &= ~SUN6I_TFR_CTL_CPHA; + +	if (spi->mode & SPI_LSB_FIRST) +		reg |= SUN6I_TFR_CTL_FBS; +	else +		reg &= ~SUN6I_TFR_CTL_FBS; + +	/* +	 * If it's a TX only transfer, we don't want to fill the RX +	 * FIFO with bogus data +	 */ +	if (sspi->rx_buf) +		reg &= ~SUN6I_TFR_CTL_DHB; +	else +		reg |= SUN6I_TFR_CTL_DHB; + +	/* We want to control the chip select manually */ +	reg |= SUN6I_TFR_CTL_CS_MANUAL; + +	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); + +	/* Ensure that we have a parent clock fast enough */ +	mclk_rate = clk_get_rate(sspi->mclk); +	if (mclk_rate < (2 * spi->max_speed_hz)) { +		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz); +		mclk_rate = clk_get_rate(sspi->mclk); +	} + +	/* +	 * Setup clock divider. +	 * +	 * We have two choices there. Either we can use the clock +	 * divide rate 1, which is calculated thanks to this formula: +	 * SPI_CLK = MOD_CLK / (2 ^ cdr) +	 * Or we can use CDR2, which is calculated with the formula: +	 * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) +	 * Wether we use the former or the latter is set through the +	 * DRS bit. +	 * +	 * First try CDR2, and if we can't reach the expected +	 * frequency, fall back to CDR1. +	 */ +	div = mclk_rate / (2 * spi->max_speed_hz); +	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { +		if (div > 0) +			div--; + +		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS; +	} else { +		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz); +		reg = SUN6I_CLK_CTL_CDR1(div); +	} + +	sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); + +	/* Setup the transfer now... */ +	if (sspi->tx_buf) +		tx_len = tfr->len; + +	/* Setup the counters */ +	sun6i_spi_write(sspi, SUN6I_BURST_CNT_REG, SUN6I_BURST_CNT(tfr->len)); +	sun6i_spi_write(sspi, SUN6I_XMIT_CNT_REG, SUN6I_XMIT_CNT(tx_len)); +	sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG, +			SUN6I_BURST_CTL_CNT_STC(tx_len)); + +	/* Fill the TX FIFO */ +	sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); + +	/* Enable the interrupts */ +	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); + +	/* Start the transfer */ +	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); +	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); + +	timeout = wait_for_completion_timeout(&sspi->done, +					      msecs_to_jiffies(1000)); +	if (!timeout) { +		ret = -ETIMEDOUT; +		goto out; +	} + +	sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); + +out: +	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); + +	return ret; +} + +static irqreturn_t sun6i_spi_handler(int irq, void *dev_id) +{ +	struct sun6i_spi *sspi = dev_id; +	u32 status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG); + +	/* Transfer complete */ +	if (status & SUN6I_INT_CTL_TC) { +		sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); +		complete(&sspi->done); +		return IRQ_HANDLED; +	} + +	return IRQ_NONE; +} + +static int sun6i_spi_runtime_resume(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct sun6i_spi *sspi = spi_master_get_devdata(master); +	int ret; + +	ret = clk_prepare_enable(sspi->hclk); +	if (ret) { +		dev_err(dev, "Couldn't enable AHB clock\n"); +		goto out; +	} + +	ret = clk_prepare_enable(sspi->mclk); +	if (ret) { +		dev_err(dev, "Couldn't enable module clock\n"); +		goto err; +	} + +	ret = reset_control_deassert(sspi->rstc); +	if (ret) { +		dev_err(dev, "Couldn't deassert the device from reset\n"); +		goto err2; +	} + +	sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, +			SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); + +	return 0; + +err2: +	clk_disable_unprepare(sspi->mclk); +err: +	clk_disable_unprepare(sspi->hclk); +out: +	return ret; +} + +static int sun6i_spi_runtime_suspend(struct device *dev) +{ +	struct spi_master *master = dev_get_drvdata(dev); +	struct sun6i_spi *sspi = spi_master_get_devdata(master); + +	reset_control_assert(sspi->rstc); +	clk_disable_unprepare(sspi->mclk); +	clk_disable_unprepare(sspi->hclk); + +	return 0; +} + +static int sun6i_spi_probe(struct platform_device *pdev) +{ +	struct spi_master *master; +	struct sun6i_spi *sspi; +	struct resource	*res; +	int ret = 0, irq; + +	master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi)); +	if (!master) { +		dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); +		return -ENOMEM; +	} + +	platform_set_drvdata(pdev, master); +	sspi = spi_master_get_devdata(master); + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	sspi->base_addr = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(sspi->base_addr)) { +		ret = PTR_ERR(sspi->base_addr); +		goto err_free_master; +	} + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(&pdev->dev, "No spi IRQ specified\n"); +		ret = -ENXIO; +		goto err_free_master; +	} + +	ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler, +			       0, "sun6i-spi", sspi); +	if (ret) { +		dev_err(&pdev->dev, "Cannot request IRQ\n"); +		goto err_free_master; +	} + +	sspi->master = master; +	master->set_cs = sun6i_spi_set_cs; +	master->transfer_one = sun6i_spi_transfer_one; +	master->num_chipselect = 4; +	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; +	master->bits_per_word_mask = SPI_BPW_MASK(8); +	master->dev.of_node = pdev->dev.of_node; +	master->auto_runtime_pm = true; + +	sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); +	if (IS_ERR(sspi->hclk)) { +		dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); +		ret = PTR_ERR(sspi->hclk); +		goto err_free_master; +	} + +	sspi->mclk = devm_clk_get(&pdev->dev, "mod"); +	if (IS_ERR(sspi->mclk)) { +		dev_err(&pdev->dev, "Unable to acquire module clock\n"); +		ret = PTR_ERR(sspi->mclk); +		goto err_free_master; +	} + +	init_completion(&sspi->done); + +	sspi->rstc = devm_reset_control_get(&pdev->dev, NULL); +	if (IS_ERR(sspi->rstc)) { +		dev_err(&pdev->dev, "Couldn't get reset controller\n"); +		ret = PTR_ERR(sspi->rstc); +		goto err_free_master; +	} + +	/* +	 * This wake-up/shutdown pattern is to be able to have the +	 * device woken up, even if runtime_pm is disabled +	 */ +	ret = sun6i_spi_runtime_resume(&pdev->dev); +	if (ret) { +		dev_err(&pdev->dev, "Couldn't resume the device\n"); +		goto err_free_master; +	} + +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_enable(&pdev->dev); +	pm_runtime_idle(&pdev->dev); + +	ret = devm_spi_register_master(&pdev->dev, master); +	if (ret) { +		dev_err(&pdev->dev, "cannot register SPI master\n"); +		goto err_pm_disable; +	} + +	return 0; + +err_pm_disable: +	pm_runtime_disable(&pdev->dev); +	sun6i_spi_runtime_suspend(&pdev->dev); +err_free_master: +	spi_master_put(master); +	return ret; +} + +static int sun6i_spi_remove(struct platform_device *pdev) +{ +	pm_runtime_disable(&pdev->dev); + +	return 0; +} + +static const struct of_device_id sun6i_spi_match[] = { +	{ .compatible = "allwinner,sun6i-a31-spi", }, +	{} +}; +MODULE_DEVICE_TABLE(of, sun6i_spi_match); + +static const struct dev_pm_ops sun6i_spi_pm_ops = { +	.runtime_resume		= sun6i_spi_runtime_resume, +	.runtime_suspend	= sun6i_spi_runtime_suspend, +}; + +static struct platform_driver sun6i_spi_driver = { +	.probe	= sun6i_spi_probe, +	.remove	= sun6i_spi_remove, +	.driver	= { +		.name		= "sun6i-spi", +		.owner		= THIS_MODULE, +		.of_match_table	= sun6i_spi_match, +		.pm		= &sun6i_spi_pm_ops, +	}, +}; +module_platform_driver(sun6i_spi_driver); + +MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>"); +MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); +MODULE_DESCRIPTION("Allwinner A31 SPI controller driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 145dd435483..e4a85ada861 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -17,14 +17,12 @@   */  #include <linux/clk.h> -#include <linux/clk/tegra.h>  #include <linux/completion.h>  #include <linux/delay.h>  #include <linux/dmaengine.h>  #include <linux/dma-mapping.h>  #include <linux/dmapool.h>  #include <linux/err.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/kernel.h> @@ -34,6 +32,7 @@  #include <linux/pm_runtime.h>  #include <linux/of.h>  #include <linux/of_device.h> +#include <linux/reset.h>  #include <linux/spi/spi.h>  #define SPI_COMMAND1				0x000 @@ -54,11 +53,8 @@  #define SPI_CS_SS_VAL				(1 << 20)  #define SPI_CS_SW_HW				(1 << 21)  /* SPI_CS_POL_INACTIVE bits are default high */ -#define SPI_CS_POL_INACTIVE			22 -#define SPI_CS_POL_INACTIVE_0			(1 << 22) -#define SPI_CS_POL_INACTIVE_1			(1 << 23) -#define SPI_CS_POL_INACTIVE_2			(1 << 24) -#define SPI_CS_POL_INACTIVE_3			(1 << 25) +						/* n from 0 to 3 */ +#define SPI_CS_POL_INACTIVE(n)			(1 << (22 + (n)))  #define SPI_CS_POL_INACTIVE_MASK		(0xF << 22)  #define SPI_CS_SEL_0				(0 << 26) @@ -165,25 +161,21 @@  #define MAX_HOLD_CYCLES				16  #define SPI_DEFAULT_SPEED			25000000 -#define MAX_CHIP_SELECT				4 -#define SPI_FIFO_DEPTH				64 -  struct tegra_spi_data {  	struct device				*dev;  	struct spi_master			*master;  	spinlock_t				lock;  	struct clk				*clk; +	struct reset_control			*rst;  	void __iomem				*base;  	phys_addr_t				phys;  	unsigned				irq; -	int					dma_req_sel; -	u32					spi_max_frequency;  	u32					cur_speed;  	struct spi_device			*cur_spi; +	struct spi_device			*cs_control;  	unsigned				cur_pos; -	unsigned				cur_len;  	unsigned				words_per_32bit;  	unsigned				bytes_per_word;  	unsigned				curr_dma_words; @@ -203,12 +195,10 @@ struct tegra_spi_data {  	u32					rx_status;  	u32					status_reg;  	bool					is_packed; -	unsigned long				packed_size;  	u32					command1_reg;  	u32					dma_control_reg;  	u32					def_command1_reg; -	u32					spi_cs_timing;  	struct completion			xfer_completion;  	struct spi_transfer			*curr_xfer; @@ -226,14 +216,14 @@ struct tegra_spi_data {  static int tegra_spi_runtime_suspend(struct device *dev);  static int tegra_spi_runtime_resume(struct device *dev); -static inline unsigned long tegra_spi_readl(struct tegra_spi_data *tspi, +static inline u32 tegra_spi_readl(struct tegra_spi_data *tspi,  		unsigned long reg)  {  	return readl(tspi->base + reg);  }  static inline void tegra_spi_writel(struct tegra_spi_data *tspi, -		unsigned long val, unsigned long reg) +		u32 val, unsigned long reg)  {  	writel(val, tspi->base + reg); @@ -244,7 +234,7 @@ static inline void tegra_spi_writel(struct tegra_spi_data *tspi,  static void tegra_spi_clear_status(struct tegra_spi_data *tspi)  { -	unsigned long val; +	u32 val;  	/* Write 1 to clear status register */  	val = tegra_spi_readl(tspi, SPI_TRANS_STATUS); @@ -267,7 +257,7 @@ static unsigned tegra_spi_calculate_curr_xfer_param(  	unsigned max_len;  	unsigned total_fifo_words; -	tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1; +	tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);  	if (bits_per_word == 8 || bits_per_word == 16) {  		tspi->is_packed = 1; @@ -295,10 +285,9 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(  {  	unsigned nbytes;  	unsigned tx_empty_count; -	unsigned long fifo_status; +	u32 fifo_status;  	unsigned max_n_32bit;  	unsigned i, count; -	unsigned long x;  	unsigned int written_words;  	unsigned fifo_words_left;  	u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos; @@ -312,9 +301,9 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(  		nbytes = written_words * tspi->bytes_per_word;  		max_n_32bit = DIV_ROUND_UP(nbytes, 4);  		for (count = 0; count < max_n_32bit; count++) { -			x = 0; +			u32 x = 0;  			for (i = 0; (i < 4) && nbytes; i++, nbytes--) -				x |= (*tx_buf++) << (i*8); +				x |= (u32)(*tx_buf++) << (i * 8);  			tegra_spi_writel(tspi, x, SPI_TX_FIFO);  		}  	} else { @@ -322,10 +311,10 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(  		written_words = max_n_32bit;  		nbytes = written_words * tspi->bytes_per_word;  		for (count = 0; count < max_n_32bit; count++) { -			x = 0; +			u32 x = 0;  			for (i = 0; nbytes && (i < tspi->bytes_per_word);  							i++, nbytes--) -				x |= ((*tx_buf++) << i*8); +				x |= (u32)(*tx_buf++) << (i * 8);  			tegra_spi_writel(tspi, x, SPI_TX_FIFO);  		}  	} @@ -337,9 +326,8 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(  		struct tegra_spi_data *tspi, struct spi_transfer *t)  {  	unsigned rx_full_count; -	unsigned long fifo_status; +	u32 fifo_status;  	unsigned i, count; -	unsigned long x;  	unsigned int read_words = 0;  	unsigned len;  	u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_rx_pos; @@ -349,20 +337,16 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(  	if (tspi->is_packed) {  		len = tspi->curr_dma_words * tspi->bytes_per_word;  		for (count = 0; count < rx_full_count; count++) { -			x = tegra_spi_readl(tspi, SPI_RX_FIFO); +			u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO);  			for (i = 0; len && (i < 4); i++, len--)  				*rx_buf++ = (x >> i*8) & 0xFF;  		}  		tspi->cur_rx_pos += tspi->curr_dma_words * tspi->bytes_per_word;  		read_words += tspi->curr_dma_words;  	} else { -		unsigned int rx_mask; -		unsigned int bits_per_word = t->bits_per_word; - -		rx_mask = (1 << bits_per_word) - 1; +		u32 rx_mask = ((u32)1 << t->bits_per_word) - 1;  		for (count = 0; count < rx_full_count; count++) { -			x = tegra_spi_readl(tspi, SPI_RX_FIFO); -			x &= rx_mask; +			u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO) & rx_mask;  			for (i = 0; (i < tspi->bytes_per_word); i++)  				*rx_buf++ = (x >> (i*8)) & 0xFF;  		} @@ -375,27 +359,24 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(  static void tegra_spi_copy_client_txbuf_to_spi_txbuf(  		struct tegra_spi_data *tspi, struct spi_transfer *t)  { -	unsigned len; -  	/* Make the dma buffer to read by cpu */  	dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys,  				tspi->dma_buf_size, DMA_TO_DEVICE);  	if (tspi->is_packed) { -		len = tspi->curr_dma_words * tspi->bytes_per_word; +		unsigned len = tspi->curr_dma_words * tspi->bytes_per_word;  		memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len);  	} else {  		unsigned int i;  		unsigned int count;  		u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos;  		unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word; -		unsigned int x;  		for (count = 0; count < tspi->curr_dma_words; count++) { -			x = 0; +			u32 x = 0;  			for (i = 0; consume && (i < tspi->bytes_per_word);  							i++, consume--) -				x |= ((*tx_buf++) << i * 8); +				x |= (u32)(*tx_buf++) << (i * 8);  			tspi->tx_dma_buf[count] = x;  		}  	} @@ -409,27 +390,21 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf(  static void tegra_spi_copy_spi_rxbuf_to_client_rxbuf(  		struct tegra_spi_data *tspi, struct spi_transfer *t)  { -	unsigned len; -  	/* Make the dma buffer to read by cpu */  	dma_sync_single_for_cpu(tspi->dev, tspi->rx_dma_phys,  		tspi->dma_buf_size, DMA_FROM_DEVICE);  	if (tspi->is_packed) { -		len = tspi->curr_dma_words * tspi->bytes_per_word; +		unsigned len = tspi->curr_dma_words * tspi->bytes_per_word;  		memcpy(t->rx_buf + tspi->cur_rx_pos, tspi->rx_dma_buf, len);  	} else {  		unsigned int i;  		unsigned int count;  		unsigned char *rx_buf = t->rx_buf + tspi->cur_rx_pos; -		unsigned int x; -		unsigned int rx_mask; -		unsigned int bits_per_word = t->bits_per_word; +		u32 rx_mask = ((u32)1 << t->bits_per_word) - 1; -		rx_mask = (1 << bits_per_word) - 1;  		for (count = 0; count < tspi->curr_dma_words; count++) { -			x = tspi->rx_dma_buf[count]; -			x &= rx_mask; +			u32 x = tspi->rx_dma_buf[count] & rx_mask;  			for (i = 0; (i < tspi->bytes_per_word); i++)  				*rx_buf++ = (x >> (i*8)) & 0xFF;  		} @@ -450,7 +425,7 @@ static void tegra_spi_dma_complete(void *args)  static int tegra_spi_start_tx_dma(struct tegra_spi_data *tspi, int len)  { -	INIT_COMPLETION(tspi->tx_dma_complete); +	reinit_completion(&tspi->tx_dma_complete);  	tspi->tx_dma_desc = dmaengine_prep_slave_single(tspi->tx_dma_chan,  				tspi->tx_dma_phys, len, DMA_MEM_TO_DEV,  				DMA_PREP_INTERRUPT |  DMA_CTRL_ACK); @@ -469,7 +444,7 @@ static int tegra_spi_start_tx_dma(struct tegra_spi_data *tspi, int len)  static int tegra_spi_start_rx_dma(struct tegra_spi_data *tspi, int len)  { -	INIT_COMPLETION(tspi->rx_dma_complete); +	reinit_completion(&tspi->rx_dma_complete);  	tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma_chan,  				tspi->rx_dma_phys, len, DMA_DEV_TO_MEM,  				DMA_PREP_INTERRUPT |  DMA_CTRL_ACK); @@ -489,16 +464,16 @@ static int tegra_spi_start_rx_dma(struct tegra_spi_data *tspi, int len)  static int tegra_spi_start_dma_based_transfer(  		struct tegra_spi_data *tspi, struct spi_transfer *t)  { -	unsigned long val; +	u32 val;  	unsigned int len;  	int ret = 0; -	unsigned long status; +	u32 status;  	/* Make sure that Rx and Tx fifo are empty */  	status = tegra_spi_readl(tspi, SPI_FIFO_STATUS);  	if ((status & SPI_FIFO_EMPTY) != SPI_FIFO_EMPTY) { -		dev_err(tspi->dev, -			"Rx/Tx fifo are not empty status 0x%08lx\n", status); +		dev_err(tspi->dev, "Rx/Tx fifo are not empty status 0x%08x\n", +			(unsigned)status);  		return -EIO;  	} @@ -563,7 +538,7 @@ static int tegra_spi_start_dma_based_transfer(  static int tegra_spi_start_cpu_based_transfer(  		struct tegra_spi_data *tspi, struct spi_transfer *t)  { -	unsigned long val; +	u32 val;  	unsigned cur_words;  	if (tspi->cur_direction & DATA_DIR_TX) @@ -599,15 +574,15 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,  	dma_addr_t dma_phys;  	int ret;  	struct dma_slave_config dma_sconfig; -	dma_cap_mask_t mask; - -	dma_cap_zero(mask); -	dma_cap_set(DMA_SLAVE, mask); -	dma_chan = dma_request_channel(mask, NULL, NULL); -	if (!dma_chan) { -		dev_err(tspi->dev, -			"Dma channel is not available, will try later\n"); -		return -EPROBE_DEFER; + +	dma_chan = dma_request_slave_channel_reason(tspi->dev, +					dma_to_memory ? "rx" : "tx"); +	if (IS_ERR(dma_chan)) { +		ret = PTR_ERR(dma_chan); +		if (ret != -EPROBE_DEFER) +			dev_err(tspi->dev, +				"Dma channel is not available: %d\n", ret); +		return ret;  	}  	dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, @@ -618,7 +593,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,  		return -ENOMEM;  	} -	dma_sconfig.slave_id = tspi->dma_req_sel;  	if (dma_to_memory) {  		dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO;  		dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -676,16 +650,13 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,  	dma_release_channel(dma_chan);  } -static int tegra_spi_start_transfer_one(struct spi_device *spi, -		struct spi_transfer *t, bool is_first_of_msg, -		bool is_single_xfer) +static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, +		struct spi_transfer *t, bool is_first_of_msg)  {  	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);  	u32 speed = t->speed_hz;  	u8 bits_per_word = t->bits_per_word; -	unsigned total_fifo_words; -	int ret; -	unsigned long command1; +	u32 command1;  	int req_mode;  	if (speed != tspi->cur_speed) { @@ -698,7 +669,6 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,  	tspi->cur_rx_pos = 0;  	tspi->cur_tx_pos = 0;  	tspi->curr_xfer = t; -	total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t);  	if (is_first_of_msg) {  		tegra_spi_clear_status(tspi); @@ -717,7 +687,12 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,  		else if (req_mode == SPI_MODE_3)  			command1 |= SPI_CONTROL_MODE_3; -		tegra_spi_writel(tspi, command1, SPI_COMMAND1); +		if (tspi->cs_control) { +			if (tspi->cs_control != spi) +				tegra_spi_writel(tspi, command1, SPI_COMMAND1); +			tspi->cs_control = NULL; +		} else +			tegra_spi_writel(tspi, command1, SPI_COMMAND1);  		command1 |= SPI_CS_SW_HW;  		if (spi->mode & SPI_CS_HIGH) @@ -732,6 +707,18 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,  		command1 |= SPI_BIT_LENGTH(bits_per_word - 1);  	} +	return command1; +} + +static int tegra_spi_start_transfer_one(struct spi_device *spi, +		struct spi_transfer *t, u32 command1) +{ +	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); +	unsigned total_fifo_words; +	int ret; + +	total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t); +  	if (tspi->is_packed)  		command1 |= SPI_PACKED; @@ -749,8 +736,8 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,  	tegra_spi_writel(tspi, command1, SPI_COMMAND1);  	tspi->command1_reg = command1; -	dev_dbg(tspi->dev, "The def 0x%x and written 0x%lx\n", -				tspi->def_command1_reg, command1); +	dev_dbg(tspi->dev, "The def 0x%x and written 0x%x\n", +		tspi->def_command1_reg, (unsigned)command1);  	if (total_fifo_words > SPI_FIFO_DEPTH)  		ret = tegra_spi_start_dma_based_transfer(tspi, t); @@ -762,15 +749,9 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,  static int tegra_spi_setup(struct spi_device *spi)  {  	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); -	unsigned long val; +	u32 val;  	unsigned long flags;  	int ret; -	unsigned int cs_pol_bit[MAX_CHIP_SELECT] = { -			SPI_CS_POL_INACTIVE_0, -			SPI_CS_POL_INACTIVE_1, -			SPI_CS_POL_INACTIVE_2, -			SPI_CS_POL_INACTIVE_3, -	};  	dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n",  		spi->bits_per_word, @@ -778,11 +759,6 @@ static int tegra_spi_setup(struct spi_device *spi)  		spi->mode & SPI_CPHA ? "" : "~",  		spi->max_speed_hz); -	BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - -	/* Set speed to the spi max fequency if spi device has not set */ -	spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency; -  	ret = pm_runtime_get_sync(tspi->dev);  	if (ret < 0) {  		dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); @@ -792,9 +768,9 @@ static int tegra_spi_setup(struct spi_device *spi)  	spin_lock_irqsave(&tspi->lock, flags);  	val = tspi->def_command1_reg;  	if (spi->mode & SPI_CS_HIGH) -		val &= ~cs_pol_bit[spi->chip_select]; +		val &= ~SPI_CS_POL_INACTIVE(spi->chip_select);  	else -		val |= cs_pol_bit[spi->chip_select]; +		val |= SPI_CS_POL_INACTIVE(spi->chip_select);  	tspi->def_command1_reg = val;  	tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);  	spin_unlock_irqrestore(&tspi->lock, flags); @@ -803,29 +779,50 @@ static int tegra_spi_setup(struct spi_device *spi)  	return 0;  } +static void tegra_spi_transfer_delay(int delay) +{ +	if (!delay) +		return; + +	if (delay >= 1000) +		mdelay(delay / 1000); + +	udelay(delay % 1000); +} +  static int tegra_spi_transfer_one_message(struct spi_master *master,  			struct spi_message *msg)  {  	bool is_first_msg = true; -	int single_xfer;  	struct tegra_spi_data *tspi = spi_master_get_devdata(master);  	struct spi_transfer *xfer;  	struct spi_device *spi = msg->spi;  	int ret; +	bool skip = false;  	msg->status = 0;  	msg->actual_length = 0; -	single_xfer = list_is_singular(&msg->transfers);  	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		INIT_COMPLETION(tspi->xfer_completion); -		ret = tegra_spi_start_transfer_one(spi, xfer, -					is_first_msg, single_xfer); +		u32 cmd1; + +		reinit_completion(&tspi->xfer_completion); + +		cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg); + +		if (!xfer->len) { +			ret = 0; +			skip = true; +			goto complete_xfer; +		} + +		ret = tegra_spi_start_transfer_one(spi, xfer, cmd1);  		if (ret < 0) {  			dev_err(tspi->dev,  				"spi can not start transfer, err %d\n", ret); -			goto exit; +			goto complete_xfer;  		} +  		is_first_msg = false;  		ret = wait_for_completion_timeout(&tspi->xfer_completion,  						SPI_DMA_TIMEOUT); @@ -833,24 +830,40 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,  			dev_err(tspi->dev,  				"spi trasfer timeout, err %d\n", ret);  			ret = -EIO; -			goto exit; +			goto complete_xfer;  		}  		if (tspi->tx_status ||  tspi->rx_status) {  			dev_err(tspi->dev, "Error in Transfer\n");  			ret = -EIO; -			goto exit; +			goto complete_xfer;  		}  		msg->actual_length += xfer->len; -		if (xfer->cs_change && xfer->delay_usecs) { + +complete_xfer: +		if (ret < 0 || skip) { +			tegra_spi_writel(tspi, tspi->def_command1_reg, +					SPI_COMMAND1); +			tegra_spi_transfer_delay(xfer->delay_usecs); +			goto exit; +		} else if (list_is_last(&xfer->transfer_list, +					&msg->transfers)) { +			if (xfer->cs_change) +				tspi->cs_control = spi; +			else { +				tegra_spi_writel(tspi, tspi->def_command1_reg, +						SPI_COMMAND1); +				tegra_spi_transfer_delay(xfer->delay_usecs); +			} +		} else if (xfer->cs_change) {  			tegra_spi_writel(tspi, tspi->def_command1_reg,  					SPI_COMMAND1); -			udelay(xfer->delay_usecs); +			tegra_spi_transfer_delay(xfer->delay_usecs);  		} +  	}  	ret = 0;  exit: -	tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);  	msg->status = ret;  	spi_finalize_current_message(master);  	return ret; @@ -867,9 +880,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi)  			tspi->status_reg);  		dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n",  			tspi->command1_reg, tspi->dma_control_reg); -		tegra_periph_reset_assert(tspi->clk); +		reset_control_assert(tspi->rst);  		udelay(2); -		tegra_periph_reset_deassert(tspi->clk); +		reset_control_deassert(tspi->rst);  		complete(&tspi->xfer_completion);  		goto exit;  	} @@ -939,9 +952,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi)  			tspi->status_reg);  		dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n",  			tspi->command1_reg, tspi->dma_control_reg); -		tegra_periph_reset_assert(tspi->clk); +		reset_control_assert(tspi->rst);  		udelay(2); -		tegra_periph_reset_deassert(tspi->clk); +		reset_control_deassert(tspi->rst);  		complete(&tspi->xfer_completion);  		spin_unlock_irqrestore(&tspi->lock, flags);  		return IRQ_HANDLED; @@ -999,22 +1012,7 @@ static irqreturn_t tegra_spi_isr(int irq, void *context_data)  	return IRQ_WAKE_THREAD;  } -static void tegra_spi_parse_dt(struct platform_device *pdev, -	struct tegra_spi_data *tspi) -{ -	struct device_node *np = pdev->dev.of_node; -	u32 of_dma[2]; - -	if (of_property_read_u32_array(np, "nvidia,dma-request-selector", -				of_dma, 2) >= 0) -		tspi->dma_req_sel = of_dma[1]; - -	if (of_property_read_u32(np, "spi-max-frequency", -				&tspi->spi_max_frequency)) -		tspi->spi_max_frequency = 25000000; /* 25MHz */ -} - -static struct of_device_id tegra_spi_of_match[] = { +static const struct of_device_id tegra_spi_of_match[] = {  	{ .compatible = "nvidia,tegra114-spi", },  	{}  }; @@ -1035,15 +1033,15 @@ static int tegra_spi_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, master);  	tspi = spi_master_get_devdata(master); -	/* Parse DT */ -	tegra_spi_parse_dt(pdev, tspi); +	if (of_property_read_u32(pdev->dev.of_node, "spi-max-frequency", +				 &master->max_speed_hz)) +		master->max_speed_hz = 25000000; /* 25MHz */  	/* the spi->mode bits understood by this driver: */  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;  	master->setup = tegra_spi_setup;  	master->transfer_one_message = tegra_spi_transfer_one_message;  	master->num_chipselect = MAX_CHIP_SELECT; -	master->bus_num = -1;  	master->auto_runtime_pm = true;  	tspi->master = master; @@ -1076,25 +1074,25 @@ static int tegra_spi_probe(struct platform_device *pdev)  		goto exit_free_irq;  	} +	tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); +	if (IS_ERR(tspi->rst)) { +		dev_err(&pdev->dev, "can not get reset\n"); +		ret = PTR_ERR(tspi->rst); +		goto exit_free_irq; +	} +  	tspi->max_buf_size = SPI_FIFO_DEPTH << 2;  	tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; -	if (tspi->dma_req_sel) { -		ret = tegra_spi_init_dma_param(tspi, true); -		if (ret < 0) { -			dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); -			goto exit_free_irq; -		} - -		ret = tegra_spi_init_dma_param(tspi, false); -		if (ret < 0) { -			dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); -			goto exit_rx_dma_free; -		} -		tspi->max_buf_size = tspi->dma_buf_size; -		init_completion(&tspi->tx_dma_complete); -		init_completion(&tspi->rx_dma_complete); -	} +	ret = tegra_spi_init_dma_param(tspi, true); +	if (ret < 0) +		goto exit_free_irq; +	ret = tegra_spi_init_dma_param(tspi, false); +	if (ret < 0) +		goto exit_rx_dma_free; +	tspi->max_buf_size = tspi->dma_buf_size; +	init_completion(&tspi->tx_dma_complete); +	init_completion(&tspi->rx_dma_complete);  	init_completion(&tspi->xfer_completion); @@ -1115,7 +1113,7 @@ static int tegra_spi_probe(struct platform_device *pdev)  	pm_runtime_put(&pdev->dev);  	master->dev.of_node = pdev->dev.of_node; -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret < 0) {  		dev_err(&pdev->dev, "can not register to master err %d\n", ret);  		goto exit_pm_disable; @@ -1142,7 +1140,6 @@ static int tegra_spi_remove(struct platform_device *pdev)  	struct tegra_spi_data	*tspi = spi_master_get_devdata(master);  	free_irq(tspi->irq, tspi); -	spi_unregister_master(master);  	if (tspi->tx_dma_chan)  		tegra_spi_deinit_dma_param(tspi, false); diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 1d814dc6e00..3548ce25c08 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -22,7 +22,6 @@  #include <linux/completion.h>  #include <linux/delay.h>  #include <linux/err.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/kernel.h> @@ -32,8 +31,8 @@  #include <linux/pm_runtime.h>  #include <linux/of.h>  #include <linux/of_device.h> +#include <linux/reset.h>  #include <linux/spi/spi.h> -#include <linux/clk/tegra.h>  #define SPI_COMMAND				0x000  #define SPI_GO					BIT(30) @@ -118,9 +117,9 @@ struct tegra_sflash_data {  	spinlock_t				lock;  	struct clk				*clk; +	struct reset_control			*rst;  	void __iomem				*base;  	unsigned				irq; -	u32					spi_max_frequency;  	u32					cur_speed;  	struct spi_device			*cur_spi; @@ -148,14 +147,14 @@ struct tegra_sflash_data {  static int tegra_sflash_runtime_suspend(struct device *dev);  static int tegra_sflash_runtime_resume(struct device *dev); -static inline unsigned long tegra_sflash_readl(struct tegra_sflash_data *tsd, +static inline u32 tegra_sflash_readl(struct tegra_sflash_data *tsd,  		unsigned long reg)  {  	return readl(tsd->base + reg);  }  static inline void tegra_sflash_writel(struct tegra_sflash_data *tsd, -		unsigned long val, unsigned long reg) +		u32 val, unsigned long reg)  {  	writel(val, tsd->base + reg);  } @@ -173,7 +172,7 @@ static unsigned tegra_sflash_calculate_curr_xfer_param(  	unsigned remain_len = t->len - tsd->cur_pos;  	unsigned max_word; -	tsd->bytes_per_word = (t->bits_per_word - 1) / 8 + 1; +	tsd->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8);  	max_word = remain_len / tsd->bytes_per_word;  	if (max_word > SPI_FIFO_DEPTH)  		max_word = SPI_FIFO_DEPTH; @@ -185,7 +184,7 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf(  	struct tegra_sflash_data *tsd, struct spi_transfer *t)  {  	unsigned nbytes; -	unsigned long status; +	u32 status;  	unsigned max_n_32bit = tsd->curr_xfer_words;  	u8 *tx_buf = (u8 *)t->tx_buf + tsd->cur_tx_pos; @@ -196,11 +195,11 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf(  	status = tegra_sflash_readl(tsd, SPI_STATUS);  	while (!(status & SPI_TXF_FULL)) {  		int i; -		unsigned int x = 0; +		u32 x = 0;  		for (i = 0; nbytes && (i < tsd->bytes_per_word);  							i++, nbytes--) -				x |= ((*tx_buf++) << i*8); +			x |= (u32)(*tx_buf++) << (i * 8);  		tegra_sflash_writel(tsd, x, SPI_TX_FIFO);  		if (!nbytes)  			break; @@ -214,16 +213,14 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf(  static int tegra_sflash_read_rx_fifo_to_client_rxbuf(  		struct tegra_sflash_data *tsd, struct spi_transfer *t)  { -	unsigned long status; +	u32 status;  	unsigned int read_words = 0;  	u8 *rx_buf = (u8 *)t->rx_buf + tsd->cur_rx_pos;  	status = tegra_sflash_readl(tsd, SPI_STATUS);  	while (!(status & SPI_RXF_EMPTY)) {  		int i; -		unsigned long x; - -		x = tegra_sflash_readl(tsd, SPI_RX_FIFO); +		u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO);  		for (i = 0; (i < tsd->bytes_per_word); i++)  			*rx_buf++ = (x >> (i*8)) & 0xFF;  		read_words++; @@ -236,7 +233,7 @@ static int tegra_sflash_read_rx_fifo_to_client_rxbuf(  static int tegra_sflash_start_cpu_based_transfer(  		struct tegra_sflash_data *tsd, struct spi_transfer *t)  { -	unsigned long val = 0; +	u32 val = 0;  	unsigned cur_words;  	if (tsd->cur_direction & DATA_DIR_TX) @@ -266,7 +263,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi,  {  	struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master);  	u32 speed; -	unsigned long command; +	u32 command;  	speed = t->speed_hz;  	if (speed != tsd->cur_speed) { @@ -313,16 +310,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi,  	tegra_sflash_writel(tsd, command, SPI_COMMAND);  	tsd->command_reg = command; -	return  tegra_sflash_start_cpu_based_transfer(tsd, t); -} - -static int tegra_sflash_setup(struct spi_device *spi) -{ -	struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master); - -	/* Set speed to the spi max fequency if spi device has not set */ -	spi->max_speed_hz = spi->max_speed_hz ? : tsd->spi_max_frequency; -	return 0; +	return tegra_sflash_start_cpu_based_transfer(tsd, t);  }  static int tegra_sflash_transfer_one_message(struct spi_master *master, @@ -339,7 +327,7 @@ static int tegra_sflash_transfer_one_message(struct spi_master *master,  	msg->actual_length = 0;  	single_xfer = list_is_singular(&msg->transfers);  	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		INIT_COMPLETION(tsd->xfer_completion); +		reinit_completion(&tsd->xfer_completion);  		ret = tegra_sflash_start_transfer_one(spi, xfer,  					is_first_msg, single_xfer);  		if (ret < 0) { @@ -389,9 +377,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd)  		dev_err(tsd->dev,  			"CpuXfer 0x%08x:0x%08x\n", tsd->command_reg,  				tsd->dma_control_reg); -		tegra_periph_reset_assert(tsd->clk); +		reset_control_assert(tsd->rst);  		udelay(2); -		tegra_periph_reset_deassert(tsd->clk); +		reset_control_deassert(tsd->rst);  		complete(&tsd->xfer_completion);  		goto exit;  	} @@ -431,16 +419,7 @@ static irqreturn_t tegra_sflash_isr(int irq, void *context_data)  	return handle_cpu_based_xfer(tsd);  } -static void tegra_sflash_parse_dt(struct tegra_sflash_data *tsd) -{ -	struct device_node *np = tsd->dev->of_node; - -	if (of_property_read_u32(np, "spi-max-frequency", -					&tsd->spi_max_frequency)) -		tsd->spi_max_frequency = 25000000; /* 25MHz */ -} - -static struct of_device_id tegra_sflash_of_match[] = { +static const struct of_device_id tegra_sflash_of_match[] = {  	{ .compatible = "nvidia,tegra20-sflash", },  	{}  }; @@ -468,11 +447,9 @@ static int tegra_sflash_probe(struct platform_device *pdev)  	/* the spi->mode bits understood by this driver: */  	master->mode_bits = SPI_CPOL | SPI_CPHA; -	master->setup = tegra_sflash_setup;  	master->transfer_one_message = tegra_sflash_transfer_one_message;  	master->auto_runtime_pm = true;  	master->num_chipselect = MAX_CHIP_SELECT; -	master->bus_num = -1;  	platform_set_drvdata(pdev, master);  	tsd = spi_master_get_devdata(master); @@ -480,7 +457,9 @@ static int tegra_sflash_probe(struct platform_device *pdev)  	tsd->dev = &pdev->dev;  	spin_lock_init(&tsd->lock); -	tegra_sflash_parse_dt(tsd); +	if (of_property_read_u32(tsd->dev->of_node, "spi-max-frequency", +				 &master->max_speed_hz)) +		master->max_speed_hz = 25000000; /* 25MHz */  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	tsd->base = devm_ioremap_resource(&pdev->dev, r); @@ -505,6 +484,13 @@ static int tegra_sflash_probe(struct platform_device *pdev)  		goto exit_free_irq;  	} +	tsd->rst = devm_reset_control_get(&pdev->dev, "spi"); +	if (IS_ERR(tsd->rst)) { +		dev_err(&pdev->dev, "can not get reset\n"); +		ret = PTR_ERR(tsd->rst); +		goto exit_free_irq; +	} +  	init_completion(&tsd->xfer_completion);  	pm_runtime_enable(&pdev->dev);  	if (!pm_runtime_enabled(&pdev->dev)) { @@ -520,16 +506,16 @@ static int tegra_sflash_probe(struct platform_device *pdev)  	}  	/* Reset controller */ -	tegra_periph_reset_assert(tsd->clk); +	reset_control_assert(tsd->rst);  	udelay(2); -	tegra_periph_reset_deassert(tsd->clk); +	reset_control_deassert(tsd->rst);  	tsd->def_command_reg  = SPI_M_S | SPI_CS_SW;  	tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);  	pm_runtime_put(&pdev->dev);  	master->dev.of_node = pdev->dev.of_node; -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret < 0) {  		dev_err(&pdev->dev, "can not register to master err %d\n", ret);  		goto exit_pm_disable; @@ -553,7 +539,6 @@ static int tegra_sflash_remove(struct platform_device *pdev)  	struct tegra_sflash_data	*tsd = spi_master_get_devdata(master);  	free_irq(tsd->irq, tsd); -	spi_unregister_master(master);  	pm_runtime_disable(&pdev->dev);  	if (!pm_runtime_status_suspended(&pdev->dev)) diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index c70353672a2..0b9e32e9f49 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -23,7 +23,6 @@  #include <linux/dma-mapping.h>  #include <linux/dmapool.h>  #include <linux/err.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/kernel.h> @@ -33,8 +32,8 @@  #include <linux/pm_runtime.h>  #include <linux/of.h>  #include <linux/of_device.h> +#include <linux/reset.h>  #include <linux/spi/spi.h> -#include <linux/clk/tegra.h>  #define SLINK_COMMAND			0x000  #define SLINK_BIT_LENGTH(x)		(((x) & 0x1f) << 0) @@ -167,11 +166,10 @@ struct tegra_slink_data {  	spinlock_t				lock;  	struct clk				*clk; +	struct reset_control			*rst;  	void __iomem				*base;  	phys_addr_t				phys;  	unsigned				irq; -	int					dma_req_sel; -	u32					spi_max_frequency;  	u32					cur_speed;  	struct spi_device			*cur_spi; @@ -196,7 +194,7 @@ struct tegra_slink_data {  	u32					rx_status;  	u32					status_reg;  	bool					is_packed; -	unsigned long				packed_size; +	u32					packed_size;  	u32					command_reg;  	u32					command2_reg; @@ -220,14 +218,14 @@ struct tegra_slink_data {  static int tegra_slink_runtime_suspend(struct device *dev);  static int tegra_slink_runtime_resume(struct device *dev); -static inline unsigned long tegra_slink_readl(struct tegra_slink_data *tspi, +static inline u32 tegra_slink_readl(struct tegra_slink_data *tspi,  		unsigned long reg)  {  	return readl(tspi->base + reg);  }  static inline void tegra_slink_writel(struct tegra_slink_data *tspi, -		unsigned long val, unsigned long reg) +		u32 val, unsigned long reg)  {  	writel(val, tspi->base + reg); @@ -238,38 +236,30 @@ static inline void tegra_slink_writel(struct tegra_slink_data *tspi,  static void tegra_slink_clear_status(struct tegra_slink_data *tspi)  { -	unsigned long val; -	unsigned long val_write = 0; +	u32 val_write; -	val = tegra_slink_readl(tspi, SLINK_STATUS); +	tegra_slink_readl(tspi, SLINK_STATUS);  	/* Write 1 to clear status register */  	val_write = SLINK_RDY | SLINK_FIFO_ERROR;  	tegra_slink_writel(tspi, val_write, SLINK_STATUS);  } -static unsigned long tegra_slink_get_packed_size(struct tegra_slink_data *tspi, +static u32 tegra_slink_get_packed_size(struct tegra_slink_data *tspi,  				  struct spi_transfer *t)  { -	unsigned long val; -  	switch (tspi->bytes_per_word) {  	case 0: -		val = SLINK_PACK_SIZE_4; -		break; +		return SLINK_PACK_SIZE_4;  	case 1: -		val = SLINK_PACK_SIZE_8; -		break; +		return SLINK_PACK_SIZE_8;  	case 2: -		val = SLINK_PACK_SIZE_16; -		break; +		return SLINK_PACK_SIZE_16;  	case 4: -		val = SLINK_PACK_SIZE_32; -		break; +		return SLINK_PACK_SIZE_32;  	default: -		val = 0; +		return 0;  	} -	return val;  }  static unsigned tegra_slink_calculate_curr_xfer_param( @@ -278,12 +268,12 @@ static unsigned tegra_slink_calculate_curr_xfer_param(  {  	unsigned remain_len = t->len - tspi->cur_pos;  	unsigned max_word; -	unsigned bits_per_word ; +	unsigned bits_per_word;  	unsigned max_len;  	unsigned total_fifo_words;  	bits_per_word = t->bits_per_word; -	tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1; +	tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);  	if (bits_per_word == 8 || bits_per_word == 16) {  		tspi->is_packed = 1; @@ -312,10 +302,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(  {  	unsigned nbytes;  	unsigned tx_empty_count; -	unsigned long fifo_status; +	u32 fifo_status;  	unsigned max_n_32bit;  	unsigned i, count; -	unsigned long x;  	unsigned int written_words;  	unsigned fifo_words_left;  	u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos; @@ -329,9 +318,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(  		nbytes = written_words * tspi->bytes_per_word;  		max_n_32bit = DIV_ROUND_UP(nbytes, 4);  		for (count = 0; count < max_n_32bit; count++) { -			x = 0; +			u32 x = 0;  			for (i = 0; (i < 4) && nbytes; i++, nbytes--) -				x |= (*tx_buf++) << (i*8); +				x |= (u32)(*tx_buf++) << (i * 8);  			tegra_slink_writel(tspi, x, SLINK_TX_FIFO);  		}  	} else { @@ -339,10 +328,10 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(  		written_words = max_n_32bit;  		nbytes = written_words * tspi->bytes_per_word;  		for (count = 0; count < max_n_32bit; count++) { -			x = 0; +			u32 x = 0;  			for (i = 0; nbytes && (i < tspi->bytes_per_word);  							i++, nbytes--) -				x |= ((*tx_buf++) << i*8); +				x |= (u32)(*tx_buf++) << (i * 8);  			tegra_slink_writel(tspi, x, SLINK_TX_FIFO);  		}  	} @@ -354,9 +343,8 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(  		struct tegra_slink_data *tspi, struct spi_transfer *t)  {  	unsigned rx_full_count; -	unsigned long fifo_status; +	u32 fifo_status;  	unsigned i, count; -	unsigned long x;  	unsigned int read_words = 0;  	unsigned len;  	u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_rx_pos; @@ -366,7 +354,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(  	if (tspi->is_packed) {  		len = tspi->curr_dma_words * tspi->bytes_per_word;  		for (count = 0; count < rx_full_count; count++) { -			x = tegra_slink_readl(tspi, SLINK_RX_FIFO); +			u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO);  			for (i = 0; len && (i < 4); i++, len--)  				*rx_buf++ = (x >> i*8) & 0xFF;  		} @@ -374,7 +362,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(  		read_words += tspi->curr_dma_words;  	} else {  		for (count = 0; count < rx_full_count; count++) { -			x = tegra_slink_readl(tspi, SLINK_RX_FIFO); +			u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO);  			for (i = 0; (i < tspi->bytes_per_word); i++)  				*rx_buf++ = (x >> (i*8)) & 0xFF;  		} @@ -387,27 +375,24 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(  static void tegra_slink_copy_client_txbuf_to_spi_txbuf(  		struct tegra_slink_data *tspi, struct spi_transfer *t)  { -	unsigned len; -  	/* Make the dma buffer to read by cpu */  	dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys,  				tspi->dma_buf_size, DMA_TO_DEVICE);  	if (tspi->is_packed) { -		len = tspi->curr_dma_words * tspi->bytes_per_word; +		unsigned len = tspi->curr_dma_words * tspi->bytes_per_word;  		memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len);  	} else {  		unsigned int i;  		unsigned int count;  		u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos;  		unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word; -		unsigned int x;  		for (count = 0; count < tspi->curr_dma_words; count++) { -			x = 0; +			u32 x = 0;  			for (i = 0; consume && (i < tspi->bytes_per_word);  							i++, consume--) -				x |= ((*tx_buf++) << i * 8); +				x |= (u32)(*tx_buf++) << (i * 8);  			tspi->tx_dma_buf[count] = x;  		}  	} @@ -434,14 +419,10 @@ static void tegra_slink_copy_spi_rxbuf_to_client_rxbuf(  		unsigned int i;  		unsigned int count;  		unsigned char *rx_buf = t->rx_buf + tspi->cur_rx_pos; -		unsigned int x; -		unsigned int rx_mask, bits_per_word; +		u32 rx_mask = ((u32)1 << t->bits_per_word) - 1; -		bits_per_word = t->bits_per_word; -		rx_mask = (1 << bits_per_word) - 1;  		for (count = 0; count < tspi->curr_dma_words; count++) { -			x = tspi->rx_dma_buf[count]; -			x &= rx_mask; +			u32 x = tspi->rx_dma_buf[count] & rx_mask;  			for (i = 0; (i < tspi->bytes_per_word); i++)  				*rx_buf++ = (x >> (i*8)) & 0xFF;  		} @@ -462,7 +443,7 @@ static void tegra_slink_dma_complete(void *args)  static int tegra_slink_start_tx_dma(struct tegra_slink_data *tspi, int len)  { -	INIT_COMPLETION(tspi->tx_dma_complete); +	reinit_completion(&tspi->tx_dma_complete);  	tspi->tx_dma_desc = dmaengine_prep_slave_single(tspi->tx_dma_chan,  				tspi->tx_dma_phys, len, DMA_MEM_TO_DEV,  				DMA_PREP_INTERRUPT |  DMA_CTRL_ACK); @@ -481,7 +462,7 @@ static int tegra_slink_start_tx_dma(struct tegra_slink_data *tspi, int len)  static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len)  { -	INIT_COMPLETION(tspi->rx_dma_complete); +	reinit_completion(&tspi->rx_dma_complete);  	tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma_chan,  				tspi->rx_dma_phys, len, DMA_DEV_TO_MEM,  				DMA_PREP_INTERRUPT |  DMA_CTRL_ACK); @@ -501,17 +482,16 @@ static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len)  static int tegra_slink_start_dma_based_transfer(  		struct tegra_slink_data *tspi, struct spi_transfer *t)  { -	unsigned long val; -	unsigned long test_val; +	u32 val;  	unsigned int len;  	int ret = 0; -	unsigned long status; +	u32 status;  	/* Make sure that Rx and Tx fifo are empty */  	status = tegra_slink_readl(tspi, SLINK_STATUS);  	if ((status & SLINK_FIFO_EMPTY) != SLINK_FIFO_EMPTY) { -		dev_err(tspi->dev, -			"Rx/Tx fifo are not empty status 0x%08lx\n", status); +		dev_err(tspi->dev, "Rx/Tx fifo are not empty status 0x%08x\n", +			(unsigned)status);  		return -EIO;  	} @@ -551,9 +531,9 @@ static int tegra_slink_start_dma_based_transfer(  		}  		/* Wait for tx fifo to be fill before starting slink */ -		test_val = tegra_slink_readl(tspi, SLINK_STATUS); -		while (!(test_val & SLINK_TX_FULL)) -			test_val = tegra_slink_readl(tspi, SLINK_STATUS); +		status = tegra_slink_readl(tspi, SLINK_STATUS); +		while (!(status & SLINK_TX_FULL)) +			status = tegra_slink_readl(tspi, SLINK_STATUS);  	}  	if (tspi->cur_direction & DATA_DIR_RX) { @@ -587,7 +567,7 @@ static int tegra_slink_start_dma_based_transfer(  static int tegra_slink_start_cpu_based_transfer(  		struct tegra_slink_data *tspi, struct spi_transfer *t)  { -	unsigned long val; +	u32 val;  	unsigned cur_words;  	val = tspi->packed_size; @@ -629,15 +609,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,  	dma_addr_t dma_phys;  	int ret;  	struct dma_slave_config dma_sconfig; -	dma_cap_mask_t mask; -	dma_cap_zero(mask); -	dma_cap_set(DMA_SLAVE, mask); -	dma_chan = dma_request_channel(mask, NULL, NULL); -	if (!dma_chan) { -		dev_err(tspi->dev, -			"Dma channel is not available, will try later\n"); -		return -EPROBE_DEFER; +	dma_chan = dma_request_slave_channel_reason(tspi->dev, +						dma_to_memory ? "rx" : "tx"); +	if (IS_ERR(dma_chan)) { +		ret = PTR_ERR(dma_chan); +		if (ret != -EPROBE_DEFER) +			dev_err(tspi->dev, +				"Dma channel is not available: %d\n", ret); +		return ret;  	}  	dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, @@ -648,7 +628,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,  		return -ENOMEM;  	} -	dma_sconfig.slave_id = tspi->dma_req_sel;  	if (dma_to_memory) {  		dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO;  		dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -707,16 +686,15 @@ static void tegra_slink_deinit_dma_param(struct tegra_slink_data *tspi,  }  static int tegra_slink_start_transfer_one(struct spi_device *spi, -		struct spi_transfer *t, bool is_first_of_msg, -		bool is_single_xfer) +		struct spi_transfer *t)  {  	struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);  	u32 speed;  	u8 bits_per_word;  	unsigned total_fifo_words;  	int ret; -	unsigned long command; -	unsigned long command2; +	u32 command; +	u32 command2;  	bits_per_word = t->bits_per_word;  	speed = t->speed_hz; @@ -732,32 +710,12 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,  	tspi->curr_xfer = t;  	total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t); -	if (is_first_of_msg) { -		tegra_slink_clear_status(tspi); - -		command = tspi->def_command_reg; -		command |= SLINK_BIT_LENGTH(bits_per_word - 1); -		command |= SLINK_CS_SW | SLINK_CS_VALUE; - -		command2 = tspi->def_command2_reg; -		command2 |= SLINK_SS_EN_CS(spi->chip_select); +	command = tspi->command_reg; +	command &= ~SLINK_BIT_LENGTH(~0); +	command |= SLINK_BIT_LENGTH(bits_per_word - 1); -		command &= ~SLINK_MODES; -		if (spi->mode & SPI_CPHA) -			command |= SLINK_CK_SDA; - -		if (spi->mode & SPI_CPOL) -			command |= SLINK_IDLE_SCLK_DRIVE_HIGH; -		else -			command |= SLINK_IDLE_SCLK_DRIVE_LOW; -	} else { -		command = tspi->command_reg; -		command &= ~SLINK_BIT_LENGTH(~0); -		command |= SLINK_BIT_LENGTH(bits_per_word - 1); - -		command2 = tspi->command2_reg; -		command2 &= ~(SLINK_RXEN | SLINK_TXEN); -	} +	command2 = tspi->command2_reg; +	command2 &= ~(SLINK_RXEN | SLINK_TXEN);  	tegra_slink_writel(tspi, command, SLINK_COMMAND);  	tspi->command_reg = command; @@ -783,27 +741,24 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,  static int tegra_slink_setup(struct spi_device *spi)  { -	struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); -	unsigned long val; -	unsigned long flags; -	int ret; -	unsigned int cs_pol_bit[MAX_CHIP_SELECT] = { +	static const u32 cs_pol_bit[MAX_CHIP_SELECT] = {  			SLINK_CS_POLARITY,  			SLINK_CS_POLARITY1,  			SLINK_CS_POLARITY2,  			SLINK_CS_POLARITY3,  	}; +	struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); +	u32 val; +	unsigned long flags; +	int ret; +  	dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n",  		spi->bits_per_word,  		spi->mode & SPI_CPOL ? "" : "~",  		spi->mode & SPI_CPHA ? "" : "~",  		spi->max_speed_hz); -	BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - -	/* Set speed to the spi max fequency if spi device has not set */ -	spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency;  	ret = pm_runtime_get_sync(tspi->dev);  	if (ret < 0) {  		dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); @@ -824,58 +779,72 @@ static int tegra_slink_setup(struct spi_device *spi)  	return 0;  } -static int tegra_slink_transfer_one_message(struct spi_master *master, -			struct spi_message *msg) +static int tegra_slink_prepare_message(struct spi_master *master, +				       struct spi_message *msg)  { -	bool is_first_msg = true; -	int single_xfer;  	struct tegra_slink_data *tspi = spi_master_get_devdata(master); -	struct spi_transfer *xfer;  	struct spi_device *spi = msg->spi; -	int ret; -	msg->status = 0; -	msg->actual_length = 0; +	tegra_slink_clear_status(tspi); -	single_xfer = list_is_singular(&msg->transfers); -	list_for_each_entry(xfer, &msg->transfers, transfer_list) { -		INIT_COMPLETION(tspi->xfer_completion); -		ret = tegra_slink_start_transfer_one(spi, xfer, -					is_first_msg, single_xfer); -		if (ret < 0) { -			dev_err(tspi->dev, -				"spi can not start transfer, err %d\n", ret); -			goto exit; -		} -		is_first_msg = false; -		ret = wait_for_completion_timeout(&tspi->xfer_completion, -						SLINK_DMA_TIMEOUT); -		if (WARN_ON(ret == 0)) { -			dev_err(tspi->dev, -				"spi trasfer timeout, err %d\n", ret); -			ret = -EIO; -			goto exit; -		} +	tspi->command_reg = tspi->def_command_reg; +	tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE; -		if (tspi->tx_status ||  tspi->rx_status) { -			dev_err(tspi->dev, "Error in Transfer\n"); -			ret = -EIO; -			goto exit; -		} -		msg->actual_length += xfer->len; -		if (xfer->cs_change && xfer->delay_usecs) { -			tegra_slink_writel(tspi, tspi->def_command_reg, -					SLINK_COMMAND); -			udelay(xfer->delay_usecs); -		} +	tspi->command2_reg = tspi->def_command2_reg; +	tspi->command2_reg |= SLINK_SS_EN_CS(spi->chip_select); + +	tspi->command_reg &= ~SLINK_MODES; +	if (spi->mode & SPI_CPHA) +		tspi->command_reg |= SLINK_CK_SDA; + +	if (spi->mode & SPI_CPOL) +		tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_HIGH; +	else +		tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_LOW; + +	return 0; +} + +static int tegra_slink_transfer_one(struct spi_master *master, +				    struct spi_device *spi, +				    struct spi_transfer *xfer) +{ +	struct tegra_slink_data *tspi = spi_master_get_devdata(master); +	int ret; + +	reinit_completion(&tspi->xfer_completion); +	ret = tegra_slink_start_transfer_one(spi, xfer); +	if (ret < 0) { +		dev_err(tspi->dev, +			"spi can not start transfer, err %d\n", ret); +		return ret;  	} -	ret = 0; -exit: + +	ret = wait_for_completion_timeout(&tspi->xfer_completion, +					  SLINK_DMA_TIMEOUT); +	if (WARN_ON(ret == 0)) { +		dev_err(tspi->dev, +			"spi trasfer timeout, err %d\n", ret); +		return -EIO; +	} + +	if (tspi->tx_status) +		return tspi->tx_status; +	if (tspi->rx_status) +		return tspi->rx_status; + +	return 0; +} + +static int tegra_slink_unprepare_message(struct spi_master *master, +					 struct spi_message *msg) +{ +	struct tegra_slink_data *tspi = spi_master_get_devdata(master); +  	tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND);  	tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); -	msg->status = ret; -	spi_finalize_current_message(master); -	return ret; + +	return 0;  }  static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) @@ -891,9 +860,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)  		dev_err(tspi->dev,  			"CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,  				tspi->command2_reg, tspi->dma_control_reg); -		tegra_periph_reset_assert(tspi->clk); +		reset_control_assert(tspi->rst);  		udelay(2); -		tegra_periph_reset_deassert(tspi->clk); +		reset_control_deassert(tspi->rst);  		complete(&tspi->xfer_completion);  		goto exit;  	} @@ -964,9 +933,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi)  		dev_err(tspi->dev,  			"DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,  				tspi->command2_reg, tspi->dma_control_reg); -		tegra_periph_reset_assert(tspi->clk); +		reset_control_assert(tspi->rst);  		udelay(2); -		tegra_periph_reset_deassert(tspi->clk); +		reset_control_assert(tspi->rst);  		complete(&tspi->xfer_completion);  		spin_unlock_irqrestore(&tspi->lock, flags);  		return IRQ_HANDLED; @@ -1024,20 +993,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data)  	return IRQ_WAKE_THREAD;  } -static void tegra_slink_parse_dt(struct tegra_slink_data *tspi) -{ -	struct device_node *np = tspi->dev->of_node; -	u32 of_dma[2]; - -	if (of_property_read_u32_array(np, "nvidia,dma-request-selector", -				of_dma, 2) >= 0) -		tspi->dma_req_sel = of_dma[1]; - -	if (of_property_read_u32(np, "spi-max-frequency", -					&tspi->spi_max_frequency)) -		tspi->spi_max_frequency = 25000000; /* 25MHz */ -} -  static const struct tegra_slink_chip_data tegra30_spi_cdata = {  	.cs_hold_time = true,  }; @@ -1046,7 +1001,7 @@ static const struct tegra_slink_chip_data tegra20_spi_cdata = {  	.cs_hold_time = false,  }; -static struct of_device_id tegra_slink_of_match[] = { +static const struct of_device_id tegra_slink_of_match[] = {  	{ .compatible = "nvidia,tegra30-slink", .data = &tegra30_spi_cdata, },  	{ .compatible = "nvidia,tegra20-slink", .data = &tegra20_spi_cdata, },  	{} @@ -1078,10 +1033,11 @@ static int tegra_slink_probe(struct platform_device *pdev)  	/* the spi->mode bits understood by this driver: */  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;  	master->setup = tegra_slink_setup; -	master->transfer_one_message = tegra_slink_transfer_one_message; +	master->prepare_message = tegra_slink_prepare_message; +	master->transfer_one = tegra_slink_transfer_one; +	master->unprepare_message = tegra_slink_unprepare_message;  	master->auto_runtime_pm = true;  	master->num_chipselect = MAX_CHIP_SELECT; -	master->bus_num = -1;  	platform_set_drvdata(pdev, master);  	tspi = spi_master_get_devdata(master); @@ -1090,7 +1046,9 @@ static int tegra_slink_probe(struct platform_device *pdev)  	tspi->chip_data = cdata;  	spin_lock_init(&tspi->lock); -	tegra_slink_parse_dt(tspi); +	if (of_property_read_u32(tspi->dev->of_node, "spi-max-frequency", +				 &master->max_speed_hz)) +		master->max_speed_hz = 25000000; /* 25MHz */  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!r) { @@ -1123,25 +1081,25 @@ static int tegra_slink_probe(struct platform_device *pdev)  		goto exit_free_irq;  	} +	tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); +	if (IS_ERR(tspi->rst)) { +		dev_err(&pdev->dev, "can not get reset\n"); +		ret = PTR_ERR(tspi->rst); +		goto exit_free_irq; +	} +  	tspi->max_buf_size = SLINK_FIFO_DEPTH << 2;  	tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; -	if (tspi->dma_req_sel) { -		ret = tegra_slink_init_dma_param(tspi, true); -		if (ret < 0) { -			dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); -			goto exit_free_irq; -		} - -		ret = tegra_slink_init_dma_param(tspi, false); -		if (ret < 0) { -			dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); -			goto exit_rx_dma_free; -		} -		tspi->max_buf_size = tspi->dma_buf_size; -		init_completion(&tspi->tx_dma_complete); -		init_completion(&tspi->rx_dma_complete); -	} +	ret = tegra_slink_init_dma_param(tspi, true); +	if (ret < 0) +		goto exit_free_irq; +	ret = tegra_slink_init_dma_param(tspi, false); +	if (ret < 0) +		goto exit_rx_dma_free; +	tspi->max_buf_size = tspi->dma_buf_size; +	init_completion(&tspi->tx_dma_complete); +	init_completion(&tspi->rx_dma_complete);  	init_completion(&tspi->xfer_completion); @@ -1164,7 +1122,7 @@ static int tegra_slink_probe(struct platform_device *pdev)  	pm_runtime_put(&pdev->dev);  	master->dev.of_node = pdev->dev.of_node; -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret < 0) {  		dev_err(&pdev->dev, "can not register to master err %d\n", ret);  		goto exit_pm_disable; @@ -1191,7 +1149,6 @@ static int tegra_slink_remove(struct platform_device *pdev)  	struct tegra_slink_data	*tspi = spi_master_get_devdata(master);  	free_irq(tspi->irq, tspi); -	spi_unregister_master(master);  	if (tspi->tx_dma_chan)  		tegra_slink_deinit_dma_param(tspi, false); diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index e12d962a289..6c211d1910b 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -41,14 +41,13 @@ struct ti_qspi_regs {  struct ti_qspi {  	struct completion       transfer_complete; -	/* IRQ synchronization */ -	spinlock_t              lock; -  	/* list synchronization */  	struct mutex            list_lock;  	struct spi_master	*master;  	void __iomem            *base; +	void __iomem            *ctrl_base; +	void __iomem            *mmap_base;  	struct clk		*fclk;  	struct device           *dev; @@ -57,7 +56,8 @@ struct ti_qspi {  	u32 spi_max_frequency;  	u32 cmd;  	u32 dc; -	u32 stat; + +	bool ctrl_mod;  };  #define QSPI_PID			(0x0) @@ -165,7 +165,7 @@ static int ti_qspi_setup(struct spi_device *spi)  			qspi->spi_max_frequency, clk_div);  	ret = pm_runtime_get_sync(qspi->dev); -	if (ret) { +	if (ret < 0) {  		dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");  		return ret;  	} @@ -208,53 +208,36 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)  	txbuf = t->tx_buf;  	cmd = qspi->cmd | QSPI_WR_SNGL;  	count = t->len; -	wlen = t->bits_per_word; +	wlen = t->bits_per_word >> 3;	/* in bytes */  	while (count) {  		switch (wlen) { -		case 8: +		case 1:  			dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n",  					cmd, qspi->dc, *txbuf);  			writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG); -			ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); -			ret = wait_for_completion_timeout(&qspi->transfer_complete, -					QSPI_COMPLETION_TIMEOUT); -			if (ret == 0) { -				dev_err(qspi->dev, "write timed out\n"); -				return -ETIMEDOUT; -			} -			txbuf += 1; -			count -= 1;  			break; -		case 16: +		case 2:  			dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n",  					cmd, qspi->dc, *txbuf);  			writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); -			ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); -			ret = wait_for_completion_timeout(&qspi->transfer_complete, -				QSPI_COMPLETION_TIMEOUT); -			if (ret == 0) { -				dev_err(qspi->dev, "write timed out\n"); -				return -ETIMEDOUT; -			} -			txbuf += 2; -			count -= 2;  			break; -		case 32: +		case 4:  			dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n",  					cmd, qspi->dc, *txbuf);  			writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); -			ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); -			ret = wait_for_completion_timeout(&qspi->transfer_complete, -				QSPI_COMPLETION_TIMEOUT); -			if (ret == 0) { -				dev_err(qspi->dev, "write timed out\n"); -				return -ETIMEDOUT; -			} -			txbuf += 4; -			count -= 4;  			break;  		} + +		ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); +		ret = wait_for_completion_timeout(&qspi->transfer_complete, +						  QSPI_COMPLETION_TIMEOUT); +		if (ret == 0) { +			dev_err(qspi->dev, "write timed out\n"); +			return -ETIMEDOUT; +		} +		txbuf += wlen; +		count -= wlen;  	}  	return 0; @@ -280,7 +263,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)  		break;  	}  	count = t->len; -	wlen = t->bits_per_word; +	wlen = t->bits_per_word >> 3;	/* in bytes */  	while (count) {  		dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); @@ -292,22 +275,18 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)  			return -ETIMEDOUT;  		}  		switch (wlen) { -		case 8: +		case 1:  			*rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG); -			rxbuf += 1; -			count -= 1;  			break; -		case 16: +		case 2:  			*((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG); -			rxbuf += 2; -			count -= 2;  			break; -		case 32: +		case 4:  			*((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG); -			rxbuf += 4; -			count -= 4;  			break;  		} +		rxbuf += wlen; +		count -= wlen;  	}  	return 0; @@ -397,13 +376,12 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id)  {  	struct ti_qspi *qspi = dev_id;  	u16 int_stat; +	u32 stat;  	irqreturn_t ret = IRQ_HANDLED; -	spin_lock(&qspi->lock); -  	int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); -	qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); +	stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);  	if (!int_stat) {  		dev_dbg(qspi->dev, "No IRQ triggered\n"); @@ -411,42 +389,19 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id)  		goto out;  	} -	ret = IRQ_WAKE_THREAD; - -	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);  	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE,  				QSPI_INTR_STATUS_ENABLED_CLEAR); - +	if (stat & WC) +		complete(&qspi->transfer_complete);  out: -	spin_unlock(&qspi->lock); -  	return ret;  } -static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id) -{ -	struct ti_qspi *qspi = dev_id; -	unsigned long flags; - -	spin_lock_irqsave(&qspi->lock, flags); - -	if (qspi->stat & WC) -		complete(&qspi->transfer_complete); - -	spin_unlock_irqrestore(&qspi->lock, flags); - -	ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); - -	return IRQ_HANDLED; -} -  static int ti_qspi_runtime_resume(struct device *dev)  {  	struct ti_qspi      *qspi; -	struct spi_master       *master; -	master = dev_get_drvdata(dev); -	qspi = spi_master_get_devdata(master); +	qspi = dev_get_drvdata(dev);  	ti_qspi_restore_ctx(qspi);  	return 0; @@ -463,7 +418,7 @@ static int ti_qspi_probe(struct platform_device *pdev)  {  	struct  ti_qspi *qspi;  	struct spi_master *master; -	struct resource         *r; +	struct resource         *r, *res_ctrl, *res_mmap;  	struct device_node *np = pdev->dev.of_node;  	u32 max_freq;  	int ret = 0, num_cs, irq; @@ -472,26 +427,52 @@ static int ti_qspi_probe(struct platform_device *pdev)  	if (!master)  		return -ENOMEM; -	master->mode_bits = SPI_CPOL | SPI_CPHA; +	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD; -	master->bus_num = -1;  	master->flags = SPI_MASTER_HALF_DUPLEX;  	master->setup = ti_qspi_setup;  	master->auto_runtime_pm = true;  	master->transfer_one_message = ti_qspi_start_transfer_one;  	master->dev.of_node = pdev->dev.of_node; -	master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1); +	master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | +				     SPI_BPW_MASK(8);  	if (!of_property_read_u32(np, "num-cs", &num_cs))  		master->num_chipselect = num_cs; -	platform_set_drvdata(pdev, master); -  	qspi = spi_master_get_devdata(master);  	qspi->master = master;  	qspi->dev = &pdev->dev; +	platform_set_drvdata(pdev, qspi); + +	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base"); +	if (r == NULL) { +		r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +		if (r == NULL) { +			dev_err(&pdev->dev, "missing platform data\n"); +			return -ENODEV; +		} +	} -	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	res_mmap = platform_get_resource_byname(pdev, +			IORESOURCE_MEM, "qspi_mmap"); +	if (res_mmap == NULL) { +		res_mmap = platform_get_resource(pdev, IORESOURCE_MEM, 1); +		if (res_mmap == NULL) { +			dev_err(&pdev->dev, +				"memory mapped resource not required\n"); +		} +	} + +	res_ctrl = platform_get_resource_byname(pdev, +			IORESOURCE_MEM, "qspi_ctrlmod"); +	if (res_ctrl == NULL) { +		res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 2); +		if (res_ctrl == NULL) { +			dev_dbg(&pdev->dev, +				"control module resources not required\n"); +		} +	}  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) { @@ -499,7 +480,6 @@ static int ti_qspi_probe(struct platform_device *pdev)  		return irq;  	} -	spin_lock_init(&qspi->lock);  	mutex_init(&qspi->list_lock);  	qspi->base = devm_ioremap_resource(&pdev->dev, r); @@ -508,8 +488,24 @@ static int ti_qspi_probe(struct platform_device *pdev)  		goto free_master;  	} -	ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr, -			ti_qspi_threaded_isr, 0, +	if (res_ctrl) { +		qspi->ctrl_mod = true; +		qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl); +		if (IS_ERR(qspi->ctrl_base)) { +			ret = PTR_ERR(qspi->ctrl_base); +			goto free_master; +		} +	} + +	if (res_mmap) { +		qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); +		if (IS_ERR(qspi->mmap_base)) { +			ret = PTR_ERR(qspi->mmap_base); +			goto free_master; +		} +	} + +	ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0,  			dev_name(&pdev->dev), qspi);  	if (ret < 0) {  		dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", @@ -532,7 +528,7 @@ static int ti_qspi_probe(struct platform_device *pdev)  	if (!of_property_read_u32(np, "spi-max-frequency", &max_freq))  		qspi->spi_max_frequency = max_freq; -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret)  		goto free_master; @@ -545,9 +541,19 @@ free_master:  static int ti_qspi_remove(struct platform_device *pdev)  { -	struct	ti_qspi *qspi = platform_get_drvdata(pdev); +	struct ti_qspi *qspi = platform_get_drvdata(pdev); +	int ret; + +	ret = pm_runtime_get_sync(qspi->dev); +	if (ret < 0) { +		dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); +		return ret; +	} + +	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); -	spi_unregister_master(qspi->master); +	pm_runtime_put(qspi->dev); +	pm_runtime_disable(&pdev->dev);  	return 0;  } @@ -558,9 +564,9 @@ static const struct dev_pm_ops ti_qspi_pm_ops = {  static struct platform_driver ti_qspi_driver = {  	.probe	= ti_qspi_probe, -	.remove	= ti_qspi_remove, +	.remove = ti_qspi_remove,  	.driver = { -		.name	= "ti,dra7xxx-qspi", +		.name	= "ti-qspi",  		.owner	= THIS_MODULE,  		.pm =   &ti_qspi_pm_ops,  		.of_match_table = ti_qspi_match, @@ -572,3 +578,4 @@ module_platform_driver(ti_qspi_driver);  MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");  MODULE_LICENSE("GPL v2");  MODULE_DESCRIPTION("TI QSPI controller driver"); +MODULE_ALIAS("platform:ti-qspi"); diff --git a/drivers/spi/spi-ti-ssp.c b/drivers/spi/spi-ti-ssp.c deleted file mode 100644 index 7d20e121e4c..00000000000 --- a/drivers/spi/spi-ti-ssp.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Sequencer Serial Port (SSP) based SPI master driver - * - * Copyright (C) 2010 Texas Instruments Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - */ - -#include <linux/kernel.h> -#include <linux/err.h> -#include <linux/completion.h> -#include <linux/delay.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/mfd/ti_ssp.h> - -#define MODE_BITS	(SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) - -struct ti_ssp_spi { -	struct spi_master		*master; -	struct device			*dev; -	spinlock_t			lock; -	struct list_head		msg_queue; -	struct completion		complete; -	bool				shutdown; -	struct workqueue_struct		*workqueue; -	struct work_struct		work; -	u8				mode, bpw; -	int				cs_active; -	u32				pc_en, pc_dis, pc_wr, pc_rd; -	void				(*select)(int cs); -}; - -static u32 ti_ssp_spi_rx(struct ti_ssp_spi *hw) -{ -	u32 ret; - -	ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret); -	return ret; -} - -static void ti_ssp_spi_tx(struct ti_ssp_spi *hw, u32 data) -{ -	ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL); -} - -static int ti_ssp_spi_txrx(struct ti_ssp_spi *hw, struct spi_message *msg, -		       struct spi_transfer *t) -{ -	int count; - -	if (hw->bpw <= 8) { -		u8		*rx = t->rx_buf; -		const u8	*tx = t->tx_buf; - -		for (count = 0; count < t->len; count += 1) { -			if (t->tx_buf) -				ti_ssp_spi_tx(hw, *tx++); -			if (t->rx_buf) -				*rx++ = ti_ssp_spi_rx(hw); -		} -	} else if (hw->bpw <= 16) { -		u16		*rx = t->rx_buf; -		const u16	*tx = t->tx_buf; - -		for (count = 0; count < t->len; count += 2) { -			if (t->tx_buf) -				ti_ssp_spi_tx(hw, *tx++); -			if (t->rx_buf) -				*rx++ = ti_ssp_spi_rx(hw); -		} -	} else { -		u32		*rx = t->rx_buf; -		const u32	*tx = t->tx_buf; - -		for (count = 0; count < t->len; count += 4) { -			if (t->tx_buf) -				ti_ssp_spi_tx(hw, *tx++); -			if (t->rx_buf) -				*rx++ = ti_ssp_spi_rx(hw); -		} -	} - -	msg->actual_length += count; /* bytes transferred */ - -	dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", -		t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, -		hw->bpw, count, (count < t->len) ? " (under)" : ""); - -	return (count < t->len) ? -EIO : 0; /* left over data */ -} - -static void ti_ssp_spi_chip_select(struct ti_ssp_spi *hw, int cs_active) -{ -	cs_active = !!cs_active; -	if (cs_active == hw->cs_active) -		return; -	ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); -	hw->cs_active = cs_active; -} - -#define __SHIFT_OUT(bits)	(SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ -				 cs_en | clk | SSP_COUNT((bits) * 2 - 1)) -#define __SHIFT_IN(bits)	(SSP_OPCODE_SHIFT | SSP_IN_MODE  | \ -				 cs_en | clk | SSP_COUNT((bits) * 2 - 1)) - -static int ti_ssp_spi_setup_transfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) -{ -	int error, idx = 0; -	u32 seqram[16]; -	u32 cs_en, cs_dis, clk; -	u32 topbits, botbits; - -	mode &= MODE_BITS; -	if (mode == hw->mode && bpw == hw->bpw) -		return 0; - -	cs_en  = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; -	cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW  : SSP_CS_HIGH; -	clk    = (mode & SPI_CPOL)    ? SSP_CLK_HIGH : SSP_CLK_LOW; - -	/* Construct instructions */ - -	/* Disable Chip Select */ -	hw->pc_dis = idx; -	seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; -	seqram[idx++] = SSP_OPCODE_STOP   | SSP_OUT_MODE | cs_dis | clk; - -	/* Enable Chip Select */ -	hw->pc_en = idx; -	seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; -	seqram[idx++] = SSP_OPCODE_STOP   | SSP_OUT_MODE | cs_en | clk; - -	/* Reads and writes need to be split for bpw > 16 */ -	topbits = (bpw > 16) ? 16 : bpw; -	botbits = bpw - topbits; - -	/* Write */ -	hw->pc_wr = idx; -	seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; -	if (botbits) -		seqram[idx++] = __SHIFT_OUT(botbits)  | SSP_DATA_REG; -	seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; - -	/* Read */ -	hw->pc_rd = idx; -	if (botbits) -		seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; -	seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; -	seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; - -	error = ti_ssp_load(hw->dev, 0, seqram, idx); -	if (error < 0) -		return error; - -	error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ? -					  0 : SSP_EARLY_DIN)); -	if (error < 0) -		return error; - -	hw->bpw = bpw; -	hw->mode = mode; - -	return error; -} - -static void ti_ssp_spi_work(struct work_struct *work) -{ -	struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); - -	spin_lock(&hw->lock); - -	 while (!list_empty(&hw->msg_queue)) { -		struct spi_message	*m; -		struct spi_device	*spi; -		struct spi_transfer	*t = NULL; -		int			status = 0; - -		m = container_of(hw->msg_queue.next, struct spi_message, -				 queue); - -		list_del_init(&m->queue); - -		spin_unlock(&hw->lock); - -		spi = m->spi; - -		if (hw->select) -			hw->select(spi->chip_select); - -		list_for_each_entry(t, &m->transfers, transfer_list) { -			int bpw = spi->bits_per_word; -			int xfer_status; - -			if (t->bits_per_word) -				bpw = t->bits_per_word; - -			if (ti_ssp_spi_setup_transfer(hw, bpw, spi->mode) < 0) -				break; - -			ti_ssp_spi_chip_select(hw, 1); - -			xfer_status = ti_ssp_spi_txrx(hw, m, t); -			if (xfer_status < 0) -				status = xfer_status; - -			if (t->delay_usecs) -				udelay(t->delay_usecs); - -			if (t->cs_change) -				ti_ssp_spi_chip_select(hw, 0); -		} - -		ti_ssp_spi_chip_select(hw, 0); -		m->status = status; -		m->complete(m->context); - -		spin_lock(&hw->lock); -	} - -	if (hw->shutdown) -		complete(&hw->complete); - -	spin_unlock(&hw->lock); -} - -static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) -{ -	struct ti_ssp_spi	*hw; -	struct spi_transfer	*t; -	int			error = 0; - -	m->actual_length = 0; -	m->status = -EINPROGRESS; - -	hw = spi_master_get_devdata(spi->master); - -	if (list_empty(&m->transfers) || !m->complete) -		return -EINVAL; - -	list_for_each_entry(t, &m->transfers, transfer_list) { -		if (t->len && !(t->rx_buf || t->tx_buf)) { -			dev_err(&spi->dev, "invalid xfer, no buffer\n"); -			return -EINVAL; -		} - -		if (t->len && t->rx_buf && t->tx_buf) { -			dev_err(&spi->dev, "invalid xfer, full duplex\n"); -			return -EINVAL; -		} -	} - -	spin_lock(&hw->lock); -	if (hw->shutdown) { -		error = -ESHUTDOWN; -		goto error_unlock; -	} -	list_add_tail(&m->queue, &hw->msg_queue); -	queue_work(hw->workqueue, &hw->work); -error_unlock: -	spin_unlock(&hw->lock); -	return error; -} - -static int ti_ssp_spi_probe(struct platform_device *pdev) -{ -	const struct ti_ssp_spi_data *pdata; -	struct ti_ssp_spi *hw; -	struct spi_master *master; -	struct device *dev = &pdev->dev; -	int error = 0; - -	pdata = dev_get_platdata(dev); -	if (!pdata) { -		dev_err(dev, "platform data not found\n"); -		return -EINVAL; -	} - -	master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); -	if (!master) { -		dev_err(dev, "cannot allocate SPI master\n"); -		return -ENOMEM; -	} - -	hw = spi_master_get_devdata(master); -	platform_set_drvdata(pdev, hw); - -	hw->master = master; -	hw->dev = dev; -	hw->select = pdata->select; - -	spin_lock_init(&hw->lock); -	init_completion(&hw->complete); -	INIT_LIST_HEAD(&hw->msg_queue); -	INIT_WORK(&hw->work, ti_ssp_spi_work); - -	hw->workqueue = create_singlethread_workqueue(dev_name(dev)); -	if (!hw->workqueue) { -		error = -ENOMEM; -		dev_err(dev, "work queue creation failed\n"); -		goto error_wq; -	} - -	error = ti_ssp_set_iosel(hw->dev, pdata->iosel); -	if (error < 0) { -		dev_err(dev, "io setup failed\n"); -		goto error_iosel; -	} - -	master->bus_num		= pdev->id; -	master->num_chipselect	= pdata->num_cs; -	master->mode_bits	= MODE_BITS; -	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); -	master->flags		= SPI_MASTER_HALF_DUPLEX; -	master->transfer	= ti_ssp_spi_transfer; - -	error = spi_register_master(master); -	if (error) { -		dev_err(dev, "master registration failed\n"); -		goto error_reg; -	} - -	return 0; - -error_reg: -error_iosel: -	destroy_workqueue(hw->workqueue); -error_wq: -	spi_master_put(master); -	return error; -} - -static int ti_ssp_spi_remove(struct platform_device *pdev) -{ -	struct ti_ssp_spi *hw = platform_get_drvdata(pdev); -	int error; - -	hw->shutdown = 1; -	while (!list_empty(&hw->msg_queue)) { -		error = wait_for_completion_interruptible(&hw->complete); -		if (error < 0) { -			hw->shutdown = 0; -			return error; -		} -	} -	destroy_workqueue(hw->workqueue); -	spi_unregister_master(hw->master); - -	return 0; -} - -static struct platform_driver ti_ssp_spi_driver = { -	.probe		= ti_ssp_spi_probe, -	.remove		= ti_ssp_spi_remove, -	.driver		= { -		.name	= "ti-ssp-spi", -		.owner	= THIS_MODULE, -	}, -}; -module_platform_driver(ti_ssp_spi_driver); - -MODULE_DESCRIPTION("SSP SPI Master"); -MODULE_AUTHOR("Cyril Chemparathy"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ti-ssp-spi"); diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c index 2d4010d8082..daf5aa1c24c 100644 --- a/drivers/spi/spi-tle62x0.c +++ b/drivers/spi/spi-tle62x0.c @@ -253,10 +253,8 @@ static int tle62x0_probe(struct spi_device *spi)  	}  	st = kzalloc(sizeof(struct tle62x0_state), GFP_KERNEL); -	if (st == NULL) { -		dev_err(&spi->dev, "no memory for device state\n"); +	if (st == NULL)  		return -ENOMEM; -	}  	st->us = spi;  	st->nr_gpio = pdata->gpio_count; diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index eaeeed51bbb..f05abf89c06 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -217,7 +217,7 @@ struct pch_pd_dev_save {  	struct pch_spi_board_data *board_dat;  }; -static DEFINE_PCI_DEVICE_TABLE(pch_spi_pcidev_id) = { +static const struct pci_device_id pch_spi_pcidev_id[] = {  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI),    1, },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, }, @@ -332,7 +332,7 @@ static void pch_spi_handler_sub(struct pch_spi_data *data, u32 reg_spsr_val,  				data->transfer_active = false;  				wake_up(&data->wait);  			} else { -				dev_err(&data->master->dev, +				dev_vdbg(&data->master->dev,  					"%s : Transfer is not completed",  					__func__);  			} @@ -464,26 +464,6 @@ static void pch_spi_reset(struct spi_master *master)  	pch_spi_writereg(master, PCH_SRST, 0x0);  } -static int pch_spi_setup(struct spi_device *pspi) -{ -	/* check bits per word */ -	if (pspi->bits_per_word == 0) { -		pspi->bits_per_word = 8; -		dev_dbg(&pspi->dev, "%s 8 bits per word\n", __func__); -	} - -	/* Check baud rate setting */ -	/* if baud rate of chip is greater than -	   max we can support,return error */ -	if ((pspi->max_speed_hz) > PCH_MAX_BAUDRATE) -		pspi->max_speed_hz = PCH_MAX_BAUDRATE; - -	dev_dbg(&pspi->dev, "%s MODE = %x\n", __func__, -		(pspi->mode) & (SPI_CPOL | SPI_CPHA)); - -	return 0; -} -  static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg)  { @@ -492,23 +472,6 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg)  	int retval;  	unsigned long flags; -	/* validate spi message and baud rate */ -	if (unlikely(list_empty(&pmsg->transfers) == 1)) { -		dev_err(&pspi->dev, "%s list empty\n", __func__); -		retval = -EINVAL; -		goto err_out; -	} - -	if (unlikely(pspi->max_speed_hz == 0)) { -		dev_err(&pspi->dev, "%s pch_spi_transfer maxspeed=%d\n", -			__func__, pspi->max_speed_hz); -		retval = -EINVAL; -		goto err_out; -	} - -	dev_dbg(&pspi->dev, "%s Transfer List not empty. " -		"Transfer Speed is set.\n", __func__); -  	spin_lock_irqsave(&data->lock, flags);  	/* validate Tx/Rx buffers and Transfer length */  	list_for_each_entry(transfer, &pmsg->transfers, transfer_list) { @@ -526,12 +489,9 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg)  			goto err_return_spinlock;  		} -		dev_dbg(&pspi->dev, "%s Tx/Rx buffer valid. Transfer length" -			" valid\n", __func__); - -		/* if baud rate has been specified validate the same */ -		if (transfer->speed_hz > PCH_MAX_BAUDRATE) -			transfer->speed_hz = PCH_MAX_BAUDRATE; +		dev_dbg(&pspi->dev, +			"%s Tx/Rx buffer valid. Transfer length valid\n", +			__func__);  	}  	spin_unlock_irqrestore(&data->lock, flags); @@ -920,7 +880,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)  	/* Set Tx DMA */  	param = &dma->param_tx;  	param->dma_dev = &dma_dev->dev; -	param->chan_id = data->master->bus_num * 2; /* Tx = 0, 2 */ +	param->chan_id = data->ch * 2; /* Tx = 0, 2 */;  	param->tx_reg = data->io_base_addr + PCH_SPDWR;  	param->width = width;  	chan = dma_request_channel(mask, pch_spi_filter, param); @@ -935,7 +895,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)  	/* Set Rx DMA */  	param = &dma->param_rx;  	param->dma_dev = &dma_dev->dev; -	param->chan_id = data->master->bus_num * 2 + 1; /* Rx = Tx + 1 */ +	param->chan_id = data->ch * 2 + 1; /* Rx = Tx + 1 */;  	param->rx_reg = data->io_base_addr + PCH_SPDRR;  	param->width = width;  	chan = dma_request_channel(mask, pch_spi_filter, param); @@ -1156,8 +1116,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)  	dma->nent = num;  	dma->desc_tx = desc_tx; -	dev_dbg(&data->master->dev, "\n%s:Pulling down SSN low - writing " -		"0x2 to SSNXCR\n", __func__); +	dev_dbg(&data->master->dev, "%s:Pulling down SSN low - writing 0x2 to SSNXCR\n", __func__);  	spin_lock_irqsave(&data->lock, flags);  	pch_spi_writereg(data->master, PCH_SSNXCR, SSN_LOW); @@ -1181,8 +1140,8 @@ static void pch_spi_process_messages(struct work_struct *pwork)  	spin_lock(&data->lock);  	/* check if suspend has been initiated;if yes flush queue */  	if (data->board_dat->suspend_sts || (data->status == STATUS_EXITING)) { -		dev_dbg(&data->master->dev, "%s suspend/remove initiated," -			"flushing queue\n", __func__); +		dev_dbg(&data->master->dev, +			"%s suspend/remove initiated, flushing queue\n", __func__);  		list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) {  			pmsg->status = -EIO; @@ -1410,23 +1369,23 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)  	/* baseaddress + address offset) */  	data->io_base_addr = pci_resource_start(board_dat->pdev, 1) +  					 PCH_ADDRESS_SIZE * plat_dev->id; -	data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0) + -					 PCH_ADDRESS_SIZE * plat_dev->id; +	data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0);  	if (!data->io_remap_addr) {  		dev_err(&plat_dev->dev, "%s pci_iomap failed\n", __func__);  		ret = -ENOMEM;  		goto err_pci_iomap;  	} +	data->io_remap_addr += PCH_ADDRESS_SIZE * plat_dev->id;  	dev_dbg(&plat_dev->dev, "[ch%d] remap_addr=%p\n",  		plat_dev->id, data->io_remap_addr);  	/* initialize members of SPI master */  	master->num_chipselect = PCH_MAX_CS; -	master->setup = pch_spi_setup;  	master->transfer = pch_spi_transfer;  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;  	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); +	master->max_speed_hz = PCH_MAX_BAUDRATE;  	data->board_dat = board_dat;  	data->plat_dev = plat_dev; @@ -1457,6 +1416,11 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)  	pch_spi_set_master_mode(master); +	if (use_dma) { +		dev_info(&plat_dev->dev, "Use DMA for data transfers\n"); +		pch_alloc_dma_buf(board_dat, data); +	} +  	ret = spi_register_master(master);  	if (ret != 0) {  		dev_err(&plat_dev->dev, @@ -1464,14 +1428,10 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)  		goto err_spi_register_master;  	} -	if (use_dma) { -		dev_info(&plat_dev->dev, "Use DMA for data transfers\n"); -		pch_alloc_dma_buf(board_dat, data); -	} -  	return 0;  err_spi_register_master: +	pch_free_dma_buf(board_dat, data);  	free_irq(board_dat->pdev->irq, data);  err_request_irq:  	pch_spi_free_resources(board_dat, data); @@ -1609,8 +1569,7 @@ static struct platform_driver pch_spi_pd_driver = {  	.resume = pch_spi_pd_resume  }; -static int pch_spi_probe(struct pci_dev *pdev, -				   const struct pci_device_id *id) +static int pch_spi_probe(struct pci_dev *pdev, const struct pci_device_id *id)  {  	struct pch_spi_board_data *board_dat;  	struct platform_device *pd_dev = NULL; @@ -1619,14 +1578,11 @@ static int pch_spi_probe(struct pci_dev *pdev,  	struct pch_pd_dev_save *pd_dev_save;  	pd_dev_save = kzalloc(sizeof(struct pch_pd_dev_save), GFP_KERNEL); -	if (!pd_dev_save) { -		dev_err(&pdev->dev, "%s Can't allocate pd_dev_sav\n", __func__); +	if (!pd_dev_save)  		return -ENOMEM; -	}  	board_dat = kzalloc(sizeof(struct pch_spi_board_data), GFP_KERNEL);  	if (!board_dat) { -		dev_err(&pdev->dev, "%s Can't allocate board_dat\n", __func__);  		retval = -ENOMEM;  		goto err_no_mem;  	} @@ -1680,6 +1636,8 @@ static int pch_spi_probe(struct pci_dev *pdev,  	return 0;  err_platform_device: +	while (--i >= 0) +		platform_device_unregister(pd_dev_save->pd_save[i]);  	pci_disable_device(pdev);  pci_enable_device:  	pci_release_regions(pdev); diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 7c6d15766c7..5f183baa91a 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -80,7 +80,6 @@ struct txx9spi {  	void __iomem *membase;  	int baseclk;  	struct clk *clk; -	u32 max_speed_hz, min_speed_hz;  	int last_chipselect;  	int last_chipselect_val;  }; @@ -117,9 +116,7 @@ static int txx9spi_setup(struct spi_device *spi)  {  	struct txx9spi *c = spi_master_get_devdata(spi->master); -	if (!spi->max_speed_hz -			|| spi->max_speed_hz > c->max_speed_hz -			|| spi->max_speed_hz < c->min_speed_hz) +	if (!spi->max_speed_hz)  		return -EINVAL;  	if (gpio_direction_output(spi->chip_select, @@ -177,7 +174,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)  			| 0x08,  			TXx9_SPCR0); -	list_for_each_entry (t, &m->transfers, transfer_list) { +	list_for_each_entry(t, &m->transfers, transfer_list) {  		const void *txbuf = t->tx_buf;  		void *rxbuf = t->rx_buf;  		u32 data; @@ -265,7 +262,8 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)  exit:  	m->status = status; -	m->complete(m->context); +	if (m->complete) +		m->complete(m->context);  	/* normally deactivate chipselect ... unless no error and  	 * cs_change has hinted that the next message will probably @@ -308,16 +306,9 @@ static int txx9spi_transfer(struct spi_device *spi, struct spi_message *m)  	m->actual_length = 0;  	/* check each transfer's parameters */ -	list_for_each_entry (t, &m->transfers, transfer_list) { -		u32 speed_hz = t->speed_hz ? : spi->max_speed_hz; -		u8 bits_per_word = t->bits_per_word; - +	list_for_each_entry(t, &m->transfers, transfer_list) {  		if (!t->tx_buf && !t->rx_buf && t->len)  			return -EINVAL; -		if (t->len & ((bits_per_word >> 3) - 1)) -			return -EINVAL; -		if (speed_hz < c->min_speed_hz || speed_hz > c->max_speed_hz) -			return -EINVAL;  	}  	spin_lock_irqsave(&c->lock, flags); @@ -348,7 +339,7 @@ static int txx9spi_probe(struct platform_device *dev)  	INIT_LIST_HEAD(&c->queue);  	init_waitqueue_head(&c->waitq); -	c->clk = clk_get(&dev->dev, "spi-baseclk"); +	c->clk = devm_clk_get(&dev->dev, "spi-baseclk");  	if (IS_ERR(c->clk)) {  		ret = PTR_ERR(c->clk);  		c->clk = NULL; @@ -356,22 +347,16 @@ static int txx9spi_probe(struct platform_device *dev)  	}  	ret = clk_enable(c->clk);  	if (ret) { -		clk_put(c->clk);  		c->clk = NULL;  		goto exit;  	}  	c->baseclk = clk_get_rate(c->clk); -	c->min_speed_hz = DIV_ROUND_UP(c->baseclk, SPI_MAX_DIVIDER + 1); -	c->max_speed_hz = c->baseclk / (SPI_MIN_DIVIDER + 1); +	master->min_speed_hz = DIV_ROUND_UP(c->baseclk, SPI_MAX_DIVIDER + 1); +	master->max_speed_hz = c->baseclk / (SPI_MIN_DIVIDER + 1);  	res = platform_get_resource(dev, IORESOURCE_MEM, 0); -	if (!res) -		goto exit_busy; -	if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), -				     "spi_txx9")) -		goto exit_busy; -	c->membase = devm_ioremap(&dev->dev, res->start, resource_size(res)); -	if (!c->membase) +	c->membase = devm_ioremap_resource(&dev->dev, res); +	if (IS_ERR(c->membase))  		goto exit_busy;  	/* enter config mode */ @@ -406,7 +391,7 @@ static int txx9spi_probe(struct platform_device *dev)  	master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */  	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&dev->dev, master);  	if (ret)  		goto exit;  	return 0; @@ -415,24 +400,19 @@ exit_busy:  exit:  	if (c->workqueue)  		destroy_workqueue(c->workqueue); -	if (c->clk) { +	if (c->clk)  		clk_disable(c->clk); -		clk_put(c->clk); -	}  	spi_master_put(master);  	return ret;  }  static int txx9spi_remove(struct platform_device *dev)  { -	struct spi_master *master = spi_master_get(platform_get_drvdata(dev)); +	struct spi_master *master = platform_get_drvdata(dev);  	struct txx9spi *c = spi_master_get_devdata(master); -	spi_unregister_master(master);  	destroy_workqueue(c->workqueue);  	clk_disable(c->clk); -	clk_put(c->clk); -	spi_master_put(master);  	return 0;  } @@ -440,6 +420,7 @@ static int txx9spi_remove(struct platform_device *dev)  MODULE_ALIAS("platform:spi_txx9");  static struct platform_driver txx9spi_driver = { +	.probe = txx9spi_probe,  	.remove = txx9spi_remove,  	.driver = {  		.name = "spi_txx9", @@ -449,7 +430,7 @@ static struct platform_driver txx9spi_driver = {  static int __init txx9spi_init(void)  { -	return platform_driver_probe(&txx9spi_driver, txx9spi_probe); +	return platform_driver_register(&txx9spi_driver);  }  subsys_initcall(txx9spi_init); diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c index 4258c712ad3..bb478dccf1d 100644 --- a/drivers/spi/spi-xcomm.c +++ b/drivers/spi/spi-xcomm.c @@ -8,7 +8,6 @@   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/module.h>  #include <linux/delay.h>  #include <linux/i2c.h> @@ -74,15 +73,13 @@ static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm,  static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,  	struct spi_device *spi, struct spi_transfer *t, unsigned int *settings)  { -	unsigned int speed; -  	if (t->len > 62)  		return -EINVAL; -	speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz; +	if (t->speed_hz != spi_xcomm->current_speed) { +		unsigned int divider; -	if (speed != spi_xcomm->current_speed) { -		unsigned int divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, speed); +		divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, t->speed_hz);  		if (divider >= 64)  			*settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_64;  		else if (divider >= 16) @@ -90,7 +87,7 @@ static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,  		else  			*settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_4; -		spi_xcomm->current_speed = speed; +		spi_xcomm->current_speed = t->speed_hz;  	}  	if (spi->mode & SPI_CPOL) @@ -148,8 +145,6 @@ static int spi_xcomm_transfer_one(struct spi_master *master,  	int status = 0;  	bool is_last; -	is_first = true; -  	spi_xcomm_chipselect(spi_xcomm, spi, true);  	list_for_each_entry(t, &msg->transfers, transfer_list) { @@ -231,22 +226,13 @@ static int spi_xcomm_probe(struct i2c_client *i2c,  	master->dev.of_node = i2c->dev.of_node;  	i2c_set_clientdata(i2c, master); -	ret = spi_register_master(master); +	ret = devm_spi_register_master(&i2c->dev, master);  	if (ret < 0)  		spi_master_put(master);  	return ret;  } -static int spi_xcomm_remove(struct i2c_client *i2c) -{ -	struct spi_master *master = i2c_get_clientdata(i2c); - -	spi_unregister_master(master); - -	return 0; -} -  static const struct i2c_device_id spi_xcomm_ids[] = {  	{ "spi-xcomm" },  	{ }, @@ -259,7 +245,6 @@ static struct i2c_driver spi_xcomm_driver = {  	},  	.id_table	= spi_xcomm_ids,  	.probe		= spi_xcomm_probe, -	.remove		= spi_xcomm_remove,  };  module_i2c_driver(spi_xcomm_driver); diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 0bf1b2c457a..a3b0b9944bf 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -14,7 +14,6 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/of.h>  #include <linux/platform_device.h> @@ -88,10 +87,10 @@ struct xilinx_spi {  	const u8 *tx_ptr;	/* pointer in the Rx buffer */  	int remaining_bytes;	/* the number of bytes left to transfer */  	u8 bits_per_word; -	unsigned int (*read_fn) (void __iomem *); -	void (*write_fn) (u32, void __iomem *); -	void (*tx_fn) (struct xilinx_spi *); -	void (*rx_fn) (struct xilinx_spi *); +	unsigned int (*read_fn)(void __iomem *); +	void (*write_fn)(u32, void __iomem *); +	void (*tx_fn)(struct xilinx_spi *); +	void (*rx_fn)(struct xilinx_spi *);  };  static void xspi_write32(u32 val, void __iomem *addr) @@ -209,26 +208,11 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)  }  /* spi_bitbang requires custom setup_transfer() to be defined if there is a - * custom txrx_bufs(). We have nothing to setup here as the SPI IP block - * supports 8 or 16 bits per word which cannot be changed in software. - * SPI clock can't be changed in software either. - * Check for correct bits per word. Chip select delay calculations could be - * added here as soon as bitbang_work() can be made aware of the delay value. + * custom txrx_bufs().   */  static int xilinx_spi_setup_transfer(struct spi_device *spi,  		struct spi_transfer *t)  { -	struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); -	u8 bits_per_word; - -	bits_per_word = (t && t->bits_per_word) -			 ? t->bits_per_word : spi->bits_per_word; -	if (bits_per_word != xspi->bits_per_word) { -		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", -			__func__, bits_per_word); -		return -EINVAL; -	} -  	return 0;  } @@ -258,7 +242,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  	xspi->tx_ptr = t->tx_buf;  	xspi->rx_ptr = t->rx_buf;  	xspi->remaining_bytes = t->len; -	INIT_COMPLETION(xspi->done); +	reinit_completion(&xspi->done);  	/* Enable the transmit empty interrupt, which we use to determine @@ -372,7 +356,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)  	master->mode_bits = SPI_CPOL | SPI_CPHA;  	xspi = spi_master_get_devdata(master); -	xspi->bitbang.master = spi_master_get(master); +	xspi->bitbang.master = master;  	xspi->bitbang.chipselect = xilinx_spi_chipselect;  	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;  	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; @@ -407,6 +391,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)  		xspi->write_fn = xspi_write32_be;  	} +	master->bits_per_word_mask = SPI_BPW_MASK(bits_per_word);  	xspi->bits_per_word = bits_per_word;  	if (xspi->bits_per_word == 8) {  		xspi->tx_fn = xspi_tx8; diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c new file mode 100644 index 00000000000..41e158187f9 --- /dev/null +++ b/drivers/spi/spi-xtensa-xtfpga.c @@ -0,0 +1,170 @@ +/* + * Xtensa xtfpga SPI controller driver + * + * Copyright (c) 2014 Cadence Design Systems Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/spi_bitbang.h> + +#define XTFPGA_SPI_NAME "xtfpga_spi" + +#define XTFPGA_SPI_START	0x0 +#define XTFPGA_SPI_BUSY		0x4 +#define XTFPGA_SPI_DATA		0x8 + +#define BUSY_WAIT_US		100 + +struct xtfpga_spi { +	struct spi_bitbang bitbang; +	void __iomem *regs; +	u32 data; +	unsigned data_sz; +}; + +static inline void xtfpga_spi_write32(const struct xtfpga_spi *spi, +				      unsigned addr, u32 val) +{ +	iowrite32(val, spi->regs + addr); +} + +static inline unsigned int xtfpga_spi_read32(const struct xtfpga_spi *spi, +					     unsigned addr) +{ +	return ioread32(spi->regs + addr); +} + +static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) +{ +	unsigned i; +	for (i = 0; xtfpga_spi_read32(xspi, XTFPGA_SPI_BUSY) && +	     i < BUSY_WAIT_US; ++i) +		udelay(1); +	WARN_ON_ONCE(i == BUSY_WAIT_US); +} + +static u32 xtfpga_spi_txrx_word(struct spi_device *spi, unsigned nsecs, +				u32 v, u8 bits) +{ +	struct xtfpga_spi *xspi = spi_master_get_devdata(spi->master); + +	xspi->data = (xspi->data << bits) | (v & GENMASK(bits - 1, 0)); +	xspi->data_sz += bits; +	if (xspi->data_sz >= 16) { +		xtfpga_spi_write32(xspi, XTFPGA_SPI_DATA, +				   xspi->data >> (xspi->data_sz - 16)); +		xspi->data_sz -= 16; +		xtfpga_spi_write32(xspi, XTFPGA_SPI_START, 1); +		xtfpga_spi_wait_busy(xspi); +		xtfpga_spi_write32(xspi, XTFPGA_SPI_START, 0); +	} + +	return 0; +} + +static void xtfpga_spi_chipselect(struct spi_device *spi, int is_on) +{ +	struct xtfpga_spi *xspi = spi_master_get_devdata(spi->master); + +	WARN_ON(xspi->data_sz != 0); +	xspi->data_sz = 0; +} + +static int xtfpga_spi_probe(struct platform_device *pdev) +{ +	struct xtfpga_spi *xspi; +	struct resource *mem; +	int ret; +	struct spi_master *master; + +	master = spi_alloc_master(&pdev->dev, sizeof(struct xtfpga_spi)); +	if (!master) +		return -ENOMEM; + +	master->flags = SPI_MASTER_NO_RX; +	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16); +	master->bus_num = pdev->dev.id; +	master->dev.of_node = pdev->dev.of_node; + +	xspi = spi_master_get_devdata(master); +	xspi->bitbang.master = master; +	xspi->bitbang.chipselect = xtfpga_spi_chipselect; +	xspi->bitbang.txrx_word[SPI_MODE_0] = xtfpga_spi_txrx_word; + +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!mem) { +		dev_err(&pdev->dev, "No memory resource\n"); +		ret = -ENODEV; +		goto err; +	} +	xspi->regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(xspi->regs)) { +		ret = PTR_ERR(xspi->regs); +		goto err; +	} + +	xtfpga_spi_write32(xspi, XTFPGA_SPI_START, 0); +	usleep_range(1000, 2000); +	if (xtfpga_spi_read32(xspi, XTFPGA_SPI_BUSY)) { +		dev_err(&pdev->dev, "Device stuck in busy state\n"); +		ret = -EBUSY; +		goto err; +	} + +	ret = spi_bitbang_start(&xspi->bitbang); +	if (ret < 0) { +		dev_err(&pdev->dev, "spi_bitbang_start failed\n"); +		goto err; +	} + +	platform_set_drvdata(pdev, master); +	return 0; +err: +	spi_master_put(master); +	return ret; +} + +static int xtfpga_spi_remove(struct platform_device *pdev) +{ +	struct spi_master *master = platform_get_drvdata(pdev); +	struct xtfpga_spi *xspi = spi_master_get_devdata(master); + +	spi_bitbang_stop(&xspi->bitbang); +	spi_master_put(master); + +	return 0; +} + +MODULE_ALIAS("platform:" XTFPGA_SPI_NAME); + +#ifdef CONFIG_OF +static const struct of_device_id xtfpga_spi_of_match[] = { +	{ .compatible = "cdns,xtfpga-spi", }, +	{} +}; +MODULE_DEVICE_TABLE(of, xtfpga_spi_of_match); +#endif + +static struct platform_driver xtfpga_spi_driver = { +	.probe = xtfpga_spi_probe, +	.remove = xtfpga_spi_remove, +	.driver = { +		.name = XTFPGA_SPI_NAME, +		.owner = THIS_MODULE, +		.of_match_table = of_match_ptr(xtfpga_spi_of_match), +	}, +}; +module_platform_driver(xtfpga_spi_driver); + +MODULE_AUTHOR("Max Filippov <jcmvbkbc@gmail.com>"); +MODULE_DESCRIPTION("xtensa xtfpga SPI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 9e039c60c06..d4f9670b51b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -24,6 +24,8 @@  #include <linux/device.h>  #include <linux/init.h>  #include <linux/cache.h> +#include <linux/dma-mapping.h> +#include <linux/dmaengine.h>  #include <linux/mutex.h>  #include <linux/of_device.h>  #include <linux/of_irq.h> @@ -39,6 +41,9 @@  #include <linux/ioport.h>  #include <linux/acpi.h> +#define CREATE_TRACE_POINTS +#include <trace/events/spi.h> +  static void spidev_release(struct device *dev)  {  	struct spi_device	*spi = to_spi_device(dev); @@ -55,14 +60,21 @@ static ssize_t  modalias_show(struct device *dev, struct device_attribute *a, char *buf)  {  	const struct spi_device	*spi = to_spi_device(dev); +	int len; + +	len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); +	if (len != -ENODEV) +		return len;  	return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias);  } +static DEVICE_ATTR_RO(modalias); -static struct device_attribute spi_dev_attrs[] = { -	__ATTR_RO(modalias), -	__ATTR_NULL, +static struct attribute *spi_dev_attrs[] = { +	&dev_attr_modalias.attr, +	NULL,  }; +ATTRIBUTE_GROUPS(spi_dev);  /* modalias support makes "modprobe $MODALIAS" new-style hotplug work,   * and the sysfs version makes coldplug work too. @@ -109,6 +121,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)  static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)  {  	const struct spi_device		*spi = to_spi_device(dev); +	int rc; + +	rc = acpi_device_uevent_modalias(dev, env); +	if (rc != -ENODEV) +		return rc;  	add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);  	return 0; @@ -229,7 +246,7 @@ static const struct dev_pm_ops spi_pm = {  struct bus_type spi_bus_type = {  	.name		= "spi", -	.dev_attrs	= spi_dev_attrs, +	.dev_groups	= spi_dev_groups,  	.match		= spi_match_device,  	.uevent		= spi_uevent,  	.pm		= &spi_pm, @@ -240,15 +257,25 @@ EXPORT_SYMBOL_GPL(spi_bus_type);  static int spi_drv_probe(struct device *dev)  {  	const struct spi_driver		*sdrv = to_spi_driver(dev->driver); +	int ret; + +	acpi_dev_pm_attach(dev, true); +	ret = sdrv->probe(to_spi_device(dev)); +	if (ret) +		acpi_dev_pm_detach(dev, true); -	return sdrv->probe(to_spi_device(dev)); +	return ret;  }  static int spi_drv_remove(struct device *dev)  {  	const struct spi_driver		*sdrv = to_spi_driver(dev->driver); +	int ret; -	return sdrv->remove(to_spi_device(dev)); +	ret = sdrv->remove(to_spi_device(dev)); +	acpi_dev_pm_detach(dev, true); + +	return ret;  }  static void spi_drv_shutdown(struct device *dev) @@ -323,7 +350,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)  	if (!spi_master_get(master))  		return NULL; -	spi = kzalloc(sizeof *spi, GFP_KERNEL); +	spi = kzalloc(sizeof(*spi), GFP_KERNEL);  	if (!spi) {  		dev_err(dev, "cannot alloc spi_device\n");  		spi_master_put(master); @@ -340,6 +367,30 @@ struct spi_device *spi_alloc_device(struct spi_master *master)  }  EXPORT_SYMBOL_GPL(spi_alloc_device); +static void spi_dev_set_name(struct spi_device *spi) +{ +	struct acpi_device *adev = ACPI_COMPANION(&spi->dev); + +	if (adev) { +		dev_set_name(&spi->dev, "spi-%s", acpi_dev_name(adev)); +		return; +	} + +	dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev), +		     spi->chip_select); +} + +static int spi_dev_check(struct device *dev, void *data) +{ +	struct spi_device *spi = to_spi_device(dev); +	struct spi_device *new_spi = data; + +	if (spi->master == new_spi->master && +	    spi->chip_select == new_spi->chip_select) +		return -EBUSY; +	return 0; +} +  /**   * spi_add_device - Add spi_device allocated with spi_alloc_device   * @spi: spi_device to register @@ -354,7 +405,6 @@ int spi_add_device(struct spi_device *spi)  	static DEFINE_MUTEX(spi_add_lock);  	struct spi_master *master = spi->master;  	struct device *dev = master->dev.parent; -	struct device *d;  	int status;  	/* Chipselects are numbered 0..max; validate. */ @@ -366,9 +416,7 @@ int spi_add_device(struct spi_device *spi)  	}  	/* Set the bus ID string */ -	dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev), -			spi->chip_select); - +	spi_dev_set_name(spi);  	/* We need to make sure there's no other device with this  	 * chipselect **BEFORE** we call setup(), else we'll trash @@ -376,12 +424,10 @@ int spi_add_device(struct spi_device *spi)  	 */  	mutex_lock(&spi_add_lock); -	d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev)); -	if (d != NULL) { +	status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); +	if (status) {  		dev_err(dev, "chipselect %d already in use\n",  				spi->chip_select); -		put_device(d); -		status = -EBUSY;  		goto done;  	} @@ -523,6 +569,291 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)  /*-------------------------------------------------------------------------*/ +static void spi_set_cs(struct spi_device *spi, bool enable) +{ +	if (spi->mode & SPI_CS_HIGH) +		enable = !enable; + +	if (spi->cs_gpio >= 0) +		gpio_set_value(spi->cs_gpio, !enable); +	else if (spi->master->set_cs) +		spi->master->set_cs(spi, !enable); +} + +#ifdef CONFIG_HAS_DMA +static int spi_map_buf(struct spi_master *master, struct device *dev, +		       struct sg_table *sgt, void *buf, size_t len, +		       enum dma_data_direction dir) +{ +	const bool vmalloced_buf = is_vmalloc_addr(buf); +	const int desc_len = vmalloced_buf ? PAGE_SIZE : master->max_dma_len; +	const int sgs = DIV_ROUND_UP(len, desc_len); +	struct page *vm_page; +	void *sg_buf; +	size_t min; +	int i, ret; + +	ret = sg_alloc_table(sgt, sgs, GFP_KERNEL); +	if (ret != 0) +		return ret; + +	for (i = 0; i < sgs; i++) { +		min = min_t(size_t, len, desc_len); + +		if (vmalloced_buf) { +			vm_page = vmalloc_to_page(buf); +			if (!vm_page) { +				sg_free_table(sgt); +				return -ENOMEM; +			} +			sg_buf = page_address(vm_page) + +				((size_t)buf & ~PAGE_MASK); +		} else { +			sg_buf = buf; +		} + +		sg_set_buf(&sgt->sgl[i], sg_buf, min); + +		buf += min; +		len -= min; +	} + +	ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); +	if (ret < 0) { +		sg_free_table(sgt); +		return ret; +	} + +	sgt->nents = ret; + +	return 0; +} + +static void spi_unmap_buf(struct spi_master *master, struct device *dev, +			  struct sg_table *sgt, enum dma_data_direction dir) +{ +	if (sgt->orig_nents) { +		dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir); +		sg_free_table(sgt); +	} +} + +static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) +{ +	struct device *tx_dev, *rx_dev; +	struct spi_transfer *xfer; +	int ret; + +	if (!master->can_dma) +		return 0; + +	tx_dev = &master->dma_tx->dev->device; +	rx_dev = &master->dma_rx->dev->device; + +	list_for_each_entry(xfer, &msg->transfers, transfer_list) { +		if (!master->can_dma(master, msg->spi, xfer)) +			continue; + +		if (xfer->tx_buf != NULL) { +			ret = spi_map_buf(master, tx_dev, &xfer->tx_sg, +					  (void *)xfer->tx_buf, xfer->len, +					  DMA_TO_DEVICE); +			if (ret != 0) +				return ret; +		} + +		if (xfer->rx_buf != NULL) { +			ret = spi_map_buf(master, rx_dev, &xfer->rx_sg, +					  xfer->rx_buf, xfer->len, +					  DMA_FROM_DEVICE); +			if (ret != 0) { +				spi_unmap_buf(master, tx_dev, &xfer->tx_sg, +					      DMA_TO_DEVICE); +				return ret; +			} +		} +	} + +	master->cur_msg_mapped = true; + +	return 0; +} + +static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) +{ +	struct spi_transfer *xfer; +	struct device *tx_dev, *rx_dev; + +	if (!master->cur_msg_mapped || !master->can_dma) +		return 0; + +	tx_dev = &master->dma_tx->dev->device; +	rx_dev = &master->dma_rx->dev->device; + +	list_for_each_entry(xfer, &msg->transfers, transfer_list) { +		if (!master->can_dma(master, msg->spi, xfer)) +			continue; + +		spi_unmap_buf(master, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE); +		spi_unmap_buf(master, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); +	} + +	return 0; +} +#else /* !CONFIG_HAS_DMA */ +static inline int __spi_map_msg(struct spi_master *master, +				struct spi_message *msg) +{ +	return 0; +} + +static inline int spi_unmap_msg(struct spi_master *master, +				struct spi_message *msg) +{ +	return 0; +} +#endif /* !CONFIG_HAS_DMA */ + +static int spi_map_msg(struct spi_master *master, struct spi_message *msg) +{ +	struct spi_transfer *xfer; +	void *tmp; +	unsigned int max_tx, max_rx; + +	if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { +		max_tx = 0; +		max_rx = 0; + +		list_for_each_entry(xfer, &msg->transfers, transfer_list) { +			if ((master->flags & SPI_MASTER_MUST_TX) && +			    !xfer->tx_buf) +				max_tx = max(xfer->len, max_tx); +			if ((master->flags & SPI_MASTER_MUST_RX) && +			    !xfer->rx_buf) +				max_rx = max(xfer->len, max_rx); +		} + +		if (max_tx) { +			tmp = krealloc(master->dummy_tx, max_tx, +				       GFP_KERNEL | GFP_DMA); +			if (!tmp) +				return -ENOMEM; +			master->dummy_tx = tmp; +			memset(tmp, 0, max_tx); +		} + +		if (max_rx) { +			tmp = krealloc(master->dummy_rx, max_rx, +				       GFP_KERNEL | GFP_DMA); +			if (!tmp) +				return -ENOMEM; +			master->dummy_rx = tmp; +		} + +		if (max_tx || max_rx) { +			list_for_each_entry(xfer, &msg->transfers, +					    transfer_list) { +				if (!xfer->tx_buf) +					xfer->tx_buf = master->dummy_tx; +				if (!xfer->rx_buf) +					xfer->rx_buf = master->dummy_rx; +			} +		} +	} + +	return __spi_map_msg(master, msg); +} + +/* + * spi_transfer_one_message - Default implementation of transfer_one_message() + * + * This is a standard implementation of transfer_one_message() for + * drivers which impelment a transfer_one() operation.  It provides + * standard handling of delays and chip select management. + */ +static int spi_transfer_one_message(struct spi_master *master, +				    struct spi_message *msg) +{ +	struct spi_transfer *xfer; +	bool keep_cs = false; +	int ret = 0; +	int ms = 1; + +	spi_set_cs(msg->spi, true); + +	list_for_each_entry(xfer, &msg->transfers, transfer_list) { +		trace_spi_transfer_start(msg, xfer); + +		reinit_completion(&master->xfer_completion); + +		ret = master->transfer_one(master, msg->spi, xfer); +		if (ret < 0) { +			dev_err(&msg->spi->dev, +				"SPI transfer failed: %d\n", ret); +			goto out; +		} + +		if (ret > 0) { +			ret = 0; +			ms = xfer->len * 8 * 1000 / xfer->speed_hz; +			ms += ms + 100; /* some tolerance */ + +			ms = wait_for_completion_timeout(&master->xfer_completion, +							 msecs_to_jiffies(ms)); +		} + +		if (ms == 0) { +			dev_err(&msg->spi->dev, "SPI transfer timed out\n"); +			msg->status = -ETIMEDOUT; +		} + +		trace_spi_transfer_stop(msg, xfer); + +		if (msg->status != -EINPROGRESS) +			goto out; + +		if (xfer->delay_usecs) +			udelay(xfer->delay_usecs); + +		if (xfer->cs_change) { +			if (list_is_last(&xfer->transfer_list, +					 &msg->transfers)) { +				keep_cs = true; +			} else { +				spi_set_cs(msg->spi, false); +				udelay(10); +				spi_set_cs(msg->spi, true); +			} +		} + +		msg->actual_length += xfer->len; +	} + +out: +	if (ret != 0 || !keep_cs) +		spi_set_cs(msg->spi, false); + +	if (msg->status == -EINPROGRESS) +		msg->status = ret; + +	spi_finalize_current_message(master); + +	return ret; +} + +/** + * spi_finalize_current_transfer - report completion of a transfer + * + * Called by SPI drivers using the core transfer_one_message() + * implementation to notify it that the current interrupt driven + * transfer has finished and the next one may be scheduled. + */ +void spi_finalize_current_transfer(struct spi_master *master) +{ +	complete(&master->xfer_completion); +} +EXPORT_SYMBOL_GPL(spi_finalize_current_transfer); +  /**   * spi_pump_messages - kthread work function which processes spi message queue   * @work: pointer to kthread work struct contained in the master struct @@ -549,6 +880,10 @@ static void spi_pump_messages(struct kthread_work *work)  		}  		master->busy = false;  		spin_unlock_irqrestore(&master->queue_lock, flags); +		kfree(master->dummy_rx); +		master->dummy_rx = NULL; +		kfree(master->dummy_tx); +		master->dummy_tx = NULL;  		if (master->unprepare_transfer_hardware &&  		    master->unprepare_transfer_hardware(master))  			dev_err(&master->dev, @@ -557,6 +892,7 @@ static void spi_pump_messages(struct kthread_work *work)  			pm_runtime_mark_last_busy(master->dev.parent);  			pm_runtime_put_autosuspend(master->dev.parent);  		} +		trace_spi_master_idle(master);  		return;  	} @@ -567,7 +903,7 @@ static void spi_pump_messages(struct kthread_work *work)  	}  	/* Extract head of queue */  	master->cur_msg = -	    list_entry(master->queue.next, struct spi_message, queue); +		list_first_entry(&master->queue, struct spi_message, queue);  	list_del_init(&master->cur_msg->queue);  	if (master->busy) @@ -585,6 +921,9 @@ static void spi_pump_messages(struct kthread_work *work)  		}  	} +	if (!was_busy) +		trace_spi_master_busy(master); +  	if (!was_busy && master->prepare_transfer_hardware) {  		ret = master->prepare_transfer_hardware(master);  		if (ret) { @@ -597,6 +936,27 @@ static void spi_pump_messages(struct kthread_work *work)  		}  	} +	trace_spi_message_start(master->cur_msg); + +	if (master->prepare_message) { +		ret = master->prepare_message(master, master->cur_msg); +		if (ret) { +			dev_err(&master->dev, +				"failed to prepare message: %d\n", ret); +			master->cur_msg->status = ret; +			spi_finalize_current_message(master); +			return; +		} +		master->cur_msg_prepared = true; +	} + +	ret = spi_map_msg(master, master->cur_msg); +	if (ret) { +		master->cur_msg->status = ret; +		spi_finalize_current_message(master); +		return; +	} +  	ret = master->transfer_one_message(master, master->cur_msg);  	if (ret) {  		dev_err(&master->dev, @@ -656,11 +1016,8 @@ struct spi_message *spi_get_next_queued_message(struct spi_master *master)  	/* get a pointer to the next message, if any */  	spin_lock_irqsave(&master->queue_lock, flags); -	if (list_empty(&master->queue)) -		next = NULL; -	else -		next = list_entry(master->queue.next, -				  struct spi_message, queue); +	next = list_first_entry_or_null(&master->queue, struct spi_message, +					queue);  	spin_unlock_irqrestore(&master->queue_lock, flags);  	return next; @@ -678,6 +1035,7 @@ void spi_finalize_current_message(struct spi_master *master)  {  	struct spi_message *mesg;  	unsigned long flags; +	int ret;  	spin_lock_irqsave(&master->queue_lock, flags);  	mesg = master->cur_msg; @@ -686,9 +1044,22 @@ void spi_finalize_current_message(struct spi_master *master)  	queue_kthread_work(&master->kworker, &master->pump_messages);  	spin_unlock_irqrestore(&master->queue_lock, flags); +	spi_unmap_msg(master, mesg); + +	if (master->cur_msg_prepared && master->unprepare_message) { +		ret = master->unprepare_message(master, mesg); +		if (ret) { +			dev_err(&master->dev, +				"failed to unprepare message: %d\n", ret); +		} +	} +	master->cur_msg_prepared = false; +  	mesg->state = NULL;  	if (mesg->complete)  		mesg->complete(mesg->context); + +	trace_spi_message_done(mesg);  }  EXPORT_SYMBOL_GPL(spi_finalize_current_message); @@ -728,7 +1099,7 @@ static int spi_stop_queue(struct spi_master *master)  	 */  	while ((!list_empty(&master->queue) || master->busy) && limit--) {  		spin_unlock_irqrestore(&master->queue_lock, flags); -		msleep(10); +		usleep_range(10000, 11000);  		spin_lock_irqsave(&master->queue_lock, flags);  	} @@ -801,8 +1172,9 @@ static int spi_master_initialize_queue(struct spi_master *master)  {  	int ret; -	master->queued = true;  	master->transfer = spi_queued_transfer; +	if (!master->transfer_one_message) +		master->transfer_one_message = spi_transfer_one_message;  	/* Initialize and start queue */  	ret = spi_init_queue(master); @@ -810,6 +1182,7 @@ static int spi_master_initialize_queue(struct spi_master *master)  		dev_err(&master->dev, "problem initializing queue\n");  		goto err_init_queue;  	} +	master->queued = true;  	ret = spi_start_queue(master);  	if (ret) {  		dev_err(&master->dev, "problem starting queue\n"); @@ -819,8 +1192,8 @@ static int spi_master_initialize_queue(struct spi_master *master)  	return 0;  err_start_queue: -err_init_queue:  	spi_destroy_queue(master); +err_init_queue:  	return ret;  } @@ -838,10 +1211,8 @@ static void of_register_spi_devices(struct spi_master *master)  {  	struct spi_device *spi;  	struct device_node *nc; -	const __be32 *prop; -	char modalias[SPI_NAME_SIZE + 4];  	int rc; -	int len; +	u32 value;  	if (!master->dev.of_node)  		return; @@ -866,14 +1237,14 @@ static void of_register_spi_devices(struct spi_master *master)  		}  		/* Device address */ -		prop = of_get_property(nc, "reg", &len); -		if (!prop || len < sizeof(*prop)) { -			dev_err(&master->dev, "%s has no 'reg' property\n", -				nc->full_name); +		rc = of_property_read_u32(nc, "reg", &value); +		if (rc) { +			dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", +				nc->full_name, rc);  			spi_dev_put(spi);  			continue;  		} -		spi->chip_select = be32_to_cpup(prop); +		spi->chip_select = value;  		/* Mode (clock phase/polarity/etc.) */  		if (of_find_property(nc, "spi-cpha", NULL)) @@ -884,57 +1255,55 @@ static void of_register_spi_devices(struct spi_master *master)  			spi->mode |= SPI_CS_HIGH;  		if (of_find_property(nc, "spi-3wire", NULL))  			spi->mode |= SPI_3WIRE; +		if (of_find_property(nc, "spi-lsb-first", NULL)) +			spi->mode |= SPI_LSB_FIRST;  		/* Device DUAL/QUAD mode */ -		prop = of_get_property(nc, "spi-tx-bus-width", &len); -		if (prop && len == sizeof(*prop)) { -			switch (be32_to_cpup(prop)) { -			case SPI_NBITS_SINGLE: +		if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { +			switch (value) { +			case 1:  				break; -			case SPI_NBITS_DUAL: +			case 2:  				spi->mode |= SPI_TX_DUAL;  				break; -			case SPI_NBITS_QUAD: +			case 4:  				spi->mode |= SPI_TX_QUAD;  				break;  			default: -				dev_err(&master->dev, -					"spi-tx-bus-width %d not supported\n", -					be32_to_cpup(prop)); -				spi_dev_put(spi); -				continue; +				dev_warn(&master->dev, +					 "spi-tx-bus-width %d not supported\n", +					 value); +				break;  			}  		} -		prop = of_get_property(nc, "spi-rx-bus-width", &len); -		if (prop && len == sizeof(*prop)) { -			switch (be32_to_cpup(prop)) { -			case SPI_NBITS_SINGLE: +		if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { +			switch (value) { +			case 1:  				break; -			case SPI_NBITS_DUAL: +			case 2:  				spi->mode |= SPI_RX_DUAL;  				break; -			case SPI_NBITS_QUAD: +			case 4:  				spi->mode |= SPI_RX_QUAD;  				break;  			default: -				dev_err(&master->dev, -					"spi-rx-bus-width %d not supported\n", -					be32_to_cpup(prop)); -				spi_dev_put(spi); -				continue; +				dev_warn(&master->dev, +					 "spi-rx-bus-width %d not supported\n", +					 value); +				break;  			}  		}  		/* Device speed */ -		prop = of_get_property(nc, "spi-max-frequency", &len); -		if (!prop || len < sizeof(*prop)) { -			dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n", -				nc->full_name); +		rc = of_property_read_u32(nc, "spi-max-frequency", &value); +		if (rc) { +			dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", +				nc->full_name, rc);  			spi_dev_put(spi);  			continue;  		} -		spi->max_speed_hz = be32_to_cpup(prop); +		spi->max_speed_hz = value;  		/* IRQ */  		spi->irq = irq_of_parse_and_map(nc, 0); @@ -944,9 +1313,7 @@ static void of_register_spi_devices(struct spi_master *master)  		spi->dev.of_node = nc;  		/* Register the new device */ -		snprintf(modalias, sizeof(modalias), "%s%s", SPI_MODULE_PREFIX, -			 spi->modalias); -		request_module(modalias); +		request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias);  		rc = spi_add_device(spi);  		if (rc) {  			dev_err(&master->dev, "spi_device register error %s\n", @@ -1012,7 +1379,7 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,  		return AE_NO_MEMORY;  	} -	ACPI_HANDLE_SET(&spi->dev, handle); +	ACPI_COMPANION_SET(&spi->dev, adev);  	spi->irq = -1;  	INIT_LIST_HEAD(&resource_list); @@ -1025,8 +1392,10 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,  		return AE_OK;  	} -	strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias)); +	adev->power.flags.ignore_parent = true; +	strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));  	if (spi_add_device(spi)) { +		adev->power.flags.ignore_parent = false;  		dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",  			dev_name(&adev->dev));  		spi_dev_put(spi); @@ -1097,7 +1466,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)  	if (!dev)  		return NULL; -	master = kzalloc(size + sizeof *master, GFP_KERNEL); +	master = kzalloc(size + sizeof(*master), GFP_KERNEL);  	if (!master)  		return NULL; @@ -1122,7 +1491,7 @@ static int of_spi_register_master(struct spi_master *master)  		return 0;  	nb = of_gpio_named_count(np, "cs-gpios"); -	master->num_chipselect = max(nb, (int)master->num_chipselect); +	master->num_chipselect = max_t(int, nb, master->num_chipselect);  	/* Return error only for an incorrectly formed cs-gpios property */  	if (nb == 0 || nb == -ENOENT) @@ -1209,6 +1578,9 @@ int spi_register_master(struct spi_master *master)  	spin_lock_init(&master->bus_lock_spinlock);  	mutex_init(&master->bus_lock_mutex);  	master->bus_lock_flag = 0; +	init_completion(&master->xfer_completion); +	if (!master->max_dma_len) +		master->max_dma_len = INT_MAX;  	/* register the device, then userspace will see it.  	 * registration fails if the bus ID is in use. @@ -1245,6 +1617,41 @@ done:  }  EXPORT_SYMBOL_GPL(spi_register_master); +static void devm_spi_unregister(struct device *dev, void *res) +{ +	spi_unregister_master(*(struct spi_master **)res); +} + +/** + * dev_spi_register_master - register managed SPI master controller + * @dev:    device managing SPI master + * @master: initialized master, originally from spi_alloc_master() + * Context: can sleep + * + * Register a SPI device as with spi_register_master() which will + * automatically be unregister + */ +int devm_spi_register_master(struct device *dev, struct spi_master *master) +{ +	struct spi_master **ptr; +	int ret; + +	ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL); +	if (!ptr) +		return -ENOMEM; + +	ret = spi_register_master(master); +	if (!ret) { +		*ptr = master; +		devres_add(dev, ptr); +	} else { +		devres_free(ptr); +	} + +	return ret; +} +EXPORT_SYMBOL_GPL(devm_spi_register_master); +  static int __unregister(struct device *dev, void *null)  {  	spi_unregister_device(to_spi_device(dev)); @@ -1370,7 +1777,7 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master);   */  int spi_setup(struct spi_device *spi)  { -	unsigned	bad_bits; +	unsigned	bad_bits, ugly_bits;  	int		status = 0;  	/* check mode to prevent that DUAL and QUAD set at the same time @@ -1390,6 +1797,15 @@ int spi_setup(struct spi_device *spi)  	 * that aren't supported with their current master  	 */  	bad_bits = spi->mode & ~spi->master->mode_bits; +	ugly_bits = bad_bits & +		    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD); +	if (ugly_bits) { +		dev_warn(&spi->dev, +			 "setup: ignoring unsupported mode bits %x\n", +			 ugly_bits); +		spi->mode &= ~ugly_bits; +		bad_bits &= ~ugly_bits; +	}  	if (bad_bits) {  		dev_err(&spi->dev, "setup: unsupported mode bits %x\n",  			bad_bits); @@ -1399,11 +1815,13 @@ int spi_setup(struct spi_device *spi)  	if (!spi->bits_per_word)  		spi->bits_per_word = 8; +	if (!spi->max_speed_hz) +		spi->max_speed_hz = spi->master->max_speed_hz; +  	if (spi->master->setup)  		status = spi->master->setup(spi); -	dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s" -				"%u bits/w, %u Hz max --> %d\n", +	dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n",  			(int) (spi->mode & (SPI_CPOL | SPI_CPHA)),  			(spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",  			(spi->mode & SPI_LSB_FIRST) ? "lsb, " : "", @@ -1416,15 +1834,14 @@ int spi_setup(struct spi_device *spi)  }  EXPORT_SYMBOL_GPL(spi_setup); -static int __spi_async(struct spi_device *spi, struct spi_message *message) +static int __spi_validate(struct spi_device *spi, struct spi_message *message)  {  	struct spi_master *master = spi->master;  	struct spi_transfer *xfer; +	int w_size;  	if (list_empty(&message->transfers))  		return -EINVAL; -	if (!message->complete) -		return -EINVAL;  	/* Half-duplex links include original MicroWire, and ones with  	 * only one data pin like SPI_3WIRE (switches direction) or where @@ -1455,12 +1872,13 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)  		message->frame_length += xfer->len;  		if (!xfer->bits_per_word)  			xfer->bits_per_word = spi->bits_per_word; -		if (!xfer->speed_hz) { + +		if (!xfer->speed_hz)  			xfer->speed_hz = spi->max_speed_hz; -			if (master->max_speed_hz && -			    xfer->speed_hz > master->max_speed_hz) -				xfer->speed_hz = master->max_speed_hz; -		} + +		if (master->max_speed_hz && +		    xfer->speed_hz > master->max_speed_hz) +			xfer->speed_hz = master->max_speed_hz;  		if (master->bits_per_word_mask) {  			/* Only 32 bits fit in the mask */ @@ -1471,21 +1889,32 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)  				return -EINVAL;  		} +		/* +		 * SPI transfer length should be multiple of SPI word size +		 * where SPI word size should be power-of-two multiple +		 */ +		if (xfer->bits_per_word <= 8) +			w_size = 1; +		else if (xfer->bits_per_word <= 16) +			w_size = 2; +		else +			w_size = 4; + +		/* No partial transfers accepted */ +		if (xfer->len % w_size) +			return -EINVAL; +  		if (xfer->speed_hz && master->min_speed_hz &&  		    xfer->speed_hz < master->min_speed_hz)  			return -EINVAL; -		if (xfer->speed_hz && master->max_speed_hz && -		    xfer->speed_hz > master->max_speed_hz) -			return -EINVAL;  		if (xfer->tx_buf && !xfer->tx_nbits)  			xfer->tx_nbits = SPI_NBITS_SINGLE;  		if (xfer->rx_buf && !xfer->rx_nbits)  			xfer->rx_nbits = SPI_NBITS_SINGLE;  		/* check transfer tx/rx_nbits: -		 * 1. keep the value is not out of single, dual and quad -		 * 2. keep tx/rx_nbits is contained by mode in spi_device -		 * 3. if SPI_3WIRE, tx/rx_nbits should be in single +		 * 1. check the value matches one of single, dual and quad +		 * 2. check tx/rx_nbits match the mode in spi_device  		 */  		if (xfer->tx_buf) {  			if (xfer->tx_nbits != SPI_NBITS_SINGLE && @@ -1498,9 +1927,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)  			if ((xfer->tx_nbits == SPI_NBITS_QUAD) &&  				!(spi->mode & SPI_TX_QUAD))  				return -EINVAL; -			if ((spi->mode & SPI_3WIRE) && -				(xfer->tx_nbits != SPI_NBITS_SINGLE)) -				return -EINVAL;  		}  		/* check transfer rx_nbits */  		if (xfer->rx_buf) { @@ -1514,14 +1940,22 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)  			if ((xfer->rx_nbits == SPI_NBITS_QUAD) &&  				!(spi->mode & SPI_RX_QUAD))  				return -EINVAL; -			if ((spi->mode & SPI_3WIRE) && -				(xfer->rx_nbits != SPI_NBITS_SINGLE)) -				return -EINVAL;  		}  	} -	message->spi = spi;  	message->status = -EINPROGRESS; + +	return 0; +} + +static int __spi_async(struct spi_device *spi, struct spi_message *message) +{ +	struct spi_master *master = spi->master; + +	message->spi = spi; + +	trace_spi_message_submit(message); +  	return master->transfer(spi, message);  } @@ -1560,6 +1994,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)  	int ret;  	unsigned long flags; +	ret = __spi_validate(spi, message); +	if (ret != 0) +		return ret; +  	spin_lock_irqsave(&master->bus_lock_spinlock, flags);  	if (master->bus_lock_flag) @@ -1608,6 +2046,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)  	int ret;  	unsigned long flags; +	ret = __spi_validate(spi, message); +	if (ret != 0) +		return ret; +  	spin_lock_irqsave(&master->bus_lock_spinlock, flags);  	ret = __spi_async(spi, message); @@ -1762,7 +2204,7 @@ int spi_bus_unlock(struct spi_master *master)  EXPORT_SYMBOL_GPL(spi_bus_unlock);  /* portable code must never pass more than 32 bytes */ -#define	SPI_BUFSIZ	max(32,SMP_CACHE_BYTES) +#define	SPI_BUFSIZ	max(32, SMP_CACHE_BYTES)  static u8	*buf; @@ -1811,7 +2253,7 @@ int spi_write_then_read(struct spi_device *spi,  	}  	spi_message_init(&message); -	memset(x, 0, sizeof x); +	memset(x, 0, sizeof(x));  	if (n_tx) {  		x[0].len = n_tx;  		spi_message_add_tail(&x[0], &message); diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index ca5bcfe874d..e3bc23bb588 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -37,7 +37,7 @@  #include <linux/spi/spi.h>  #include <linux/spi/spidev.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h>  /* @@ -73,7 +73,8 @@ static DECLARE_BITMAP(minors, N_SPI_MINORS);   */  #define SPI_MODE_MASK		(SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \  				| SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ -				| SPI_NO_CS | SPI_READY) +				| SPI_NO_CS | SPI_READY | SPI_TX_DUAL \ +				| SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)  struct spidev_data {  	dev_t			devt; @@ -206,9 +207,9 @@ spidev_write(struct file *filp, const char __user *buf,  	mutex_lock(&spidev->buf_lock);  	missing = copy_from_user(spidev->buffer, buf, count); -	if (missing == 0) { +	if (missing == 0)  		status = spidev_sync_write(spidev, count); -	} else +	else  		status = -EFAULT;  	mutex_unlock(&spidev->buf_lock); @@ -265,6 +266,8 @@ static int spidev_message(struct spidev_data *spidev,  		buf += k_tmp->len;  		k_tmp->cs_change = !!u_tmp->cs_change; +		k_tmp->tx_nbits = u_tmp->tx_nbits; +		k_tmp->rx_nbits = u_tmp->rx_nbits;  		k_tmp->bits_per_word = u_tmp->bits_per_word;  		k_tmp->delay_usecs = u_tmp->delay_usecs;  		k_tmp->speed_hz = u_tmp->speed_hz; @@ -359,6 +362,10 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  		retval = __put_user(spi->mode & SPI_MODE_MASK,  					(__u8 __user *)arg);  		break; +	case SPI_IOC_RD_MODE32: +		retval = __put_user(spi->mode & SPI_MODE_MASK, +					(__u32 __user *)arg); +		break;  	case SPI_IOC_RD_LSB_FIRST:  		retval = __put_user((spi->mode & SPI_LSB_FIRST) ?  1 : 0,  					(__u8 __user *)arg); @@ -372,9 +379,13 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  	/* write requests */  	case SPI_IOC_WR_MODE: -		retval = __get_user(tmp, (u8 __user *)arg); +	case SPI_IOC_WR_MODE32: +		if (cmd == SPI_IOC_WR_MODE) +			retval = __get_user(tmp, (u8 __user *)arg); +		else +			retval = __get_user(tmp, (u32 __user *)arg);  		if (retval == 0) { -			u8	save = spi->mode; +			u32	save = spi->mode;  			if (tmp & ~SPI_MODE_MASK) {  				retval = -EINVAL; @@ -382,18 +393,18 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  			}  			tmp |= spi->mode & ~SPI_MODE_MASK; -			spi->mode = (u8)tmp; +			spi->mode = (u16)tmp;  			retval = spi_setup(spi);  			if (retval < 0)  				spi->mode = save;  			else -				dev_dbg(&spi->dev, "spi mode %02x\n", tmp); +				dev_dbg(&spi->dev, "spi mode %x\n", tmp);  		}  		break;  	case SPI_IOC_WR_LSB_FIRST:  		retval = __get_user(tmp, (__u8 __user *)arg);  		if (retval == 0) { -			u8	save = spi->mode; +			u32	save = spi->mode;  			if (tmp)  				spi->mode |= SPI_LSB_FIRST; @@ -629,7 +640,6 @@ static int spidev_remove(struct spi_device *spi)  	/* make sure ops on existing fds can abort cleanly */  	spin_lock_irq(&spidev->spi_lock);  	spidev->spi = NULL; -	spi_set_drvdata(spi, NULL);  	spin_unlock_irq(&spidev->spi_lock);  	/* prevent new opens */  | 
