Commit 85adbcd5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull spi updates from Mark Brown:
 "This release is mainly a collection of driver specific updates,
  including a few nice cleanups to make drivers use more core features.

   - automatically use the parent device to allocate DMA buffers if
     there wasn't an explicitly configured device.

   - fixes for leaks on allocation.

   - a small piece of the start of SPI slave support, a feature that's
     been on the cards for over a decade!"

* tag 'spi-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (55 commits)
  spi: spi-ti-qspi: Fix error handling
  spi: spi-ti-qspi: Fix error handling
  spi: lantiq-ssc: activate under COMPILE_TEST
  spi: armada-3700: Remove spi_master_put in a3700_spi_remove()
  spi: ti-qspi: revise ti_qspi_probe() failure flow
  spi: spi-ep93xx: simplify GPIO chip selects
  spi: rspi: Replaces "n" by "len" in qspi_transfer_*()
  spi: rspi: Fixes bogus received byte in qspi_transfer_in()
  spi: bcm-qspi: Remove unnecessary platform_set_drvdata()
  spi: bcm-qspi: Fix bcm_qspi_bspi_read() performance
  spi: lantiq-ssc: add support for Lantiq SSC SPI controller
  spi: s3c64xx: fix inconsistency between binding and driver
  spi: armada-3700: Remove .owner field for driver
  spi: bcm-qspi: Added mspi read fallback in bcm_qspi_flash_read()
  spi: fix device-node leaks
  spi: mediatek: Only do dma for 4-byte aligned buffers
  spi: When no dma_chan map buffers with spi_master's parent
  spi: pca2xx-pci: Allow MSI
  spi: pxa2xx: Prepare for edge-triggered interrupts
  spi: pxa2xx: Add support for Intel Gemini Lake
  ...
parents f790bd9c 57f22cd2
Lantiq Synchronous Serial Controller (SSC) SPI master driver
Required properties:
- compatible: "lantiq,ase-spi", "lantiq,falcon-spi", "lantiq,xrx100-spi"
- #address-cells: see spi-bus.txt
- #size-cells: see spi-bus.txt
- reg: address and length of the spi master registers
- interrupts: should contain the "spi_rx", "spi_tx" and "spi_err" interrupt.
Optional properties:
- clocks: spi clock phandle
- num-cs: see spi-bus.txt, set to 8 if unset
- base-cs: the number of the first chip select, set to 1 if unset.
Example:
spi: spi@E100800 {
compatible = "lantiq,xrx200-spi", "lantiq,xrx100-spi";
reg = <0xE100800 0x100>;
interrupt-parent = <&icu0>;
interrupts = <22 23 24>;
interrupt-names = "spi_rx", "spi_tx", "spi_err";
#address-cells = <1>;
#size-cells = <1>;
num-cs = <6>;
base-cs = <1>;
};
...@@ -31,6 +31,10 @@ Optional Properties: ...@@ -31,6 +31,10 @@ Optional Properties:
- rx-sample-delay-ns: nanoseconds to delay after the SCLK edge before sampling - rx-sample-delay-ns: nanoseconds to delay after the SCLK edge before sampling
Rx data (may need to be fine tuned for high capacitance lines). Rx data (may need to be fine tuned for high capacitance lines).
No delay (0) by default. No delay (0) by default.
- pinctrl-names: Names for the pin configuration(s); may be "default" or
"sleep", where the "sleep" configuration may describe the state
the pins should be in during system suspend. See also
pinctrl/pinctrl-bindings.txt.
Example: Example:
...@@ -46,4 +50,7 @@ Example: ...@@ -46,4 +50,7 @@ Example:
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
clock-names = "spiclk", "apb_pclk"; clock-names = "spiclk", "apb_pclk";
pinctrl-0 = <&spi1_pins>;
pinctrl-1 = <&spi1_sleep>;
pinctrl-names = "default", "sleep";
}; };
Cirrus EP93xx SPI controller driver HOWTO
=========================================
ep93xx_spi driver brings SPI master support for EP93xx SPI controller. Chip
selects are implemented with GPIO lines.
NOTE: If possible, don't use SFRMOUT (SFRM1) signal as a chip select. It will
not work correctly (it cannot be controlled by software). Use GPIO lines
instead.
Sample configuration
====================
Typically driver configuration is done in platform board files (the files under
arch/arm/mach-ep93xx/*.c). In this example we configure MMC over SPI through
this driver on TS-7260 board. You can adapt the code to suit your needs.
This example uses EGPIO9 as SD/MMC card chip select (this is wired in DIO1
header on the board).
You need to select CONFIG_MMC_SPI to use mmc_spi driver.
arch/arm/mach-ep93xx/ts72xx.c:
...
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/spi-ep93xx.h>
/* this is our GPIO line used for chip select */
#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO9
static int ts72xx_mmc_spi_setup(struct spi_device *spi)
{
int err;
err = gpio_request(MMC_CHIP_SELECT_GPIO, spi->modalias);
if (err)
return err;
gpio_direction_output(MMC_CHIP_SELECT_GPIO, 1);
return 0;
}
static void ts72xx_mmc_spi_cleanup(struct spi_device *spi)
{
gpio_set_value(MMC_CHIP_SELECT_GPIO, 1);
gpio_direction_input(MMC_CHIP_SELECT_GPIO);
gpio_free(MMC_CHIP_SELECT_GPIO);
}
static void ts72xx_mmc_spi_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
}
static struct ep93xx_spi_chip_ops ts72xx_mmc_spi_ops = {
.setup = ts72xx_mmc_spi_setup,
.cleanup = ts72xx_mmc_spi_cleanup,
.cs_control = ts72xx_mmc_spi_cs_control,
};
static struct spi_board_info ts72xx_spi_devices[] __initdata = {
{
.modalias = "mmc_spi",
.controller_data = &ts72xx_mmc_spi_ops,
/*
* We use 10 MHz even though the maximum is 7.4 MHz. The driver
* will limit it automatically to max. frequency.
*/
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
},
};
static struct ep93xx_spi_info ts72xx_spi_info = {
.num_chipselect = ARRAY_SIZE(ts72xx_spi_devices),
};
static void __init ts72xx_init_machine(void)
{
...
ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices,
ARRAY_SIZE(ts72xx_spi_devices));
}
The driver can use DMA for the transfers also. In this case ts72xx_spi_info
becomes:
static struct ep93xx_spi_info ts72xx_spi_info = {
.num_chipselect = ARRAY_SIZE(ts72xx_spi_devices),
.use_dma = true;
};
Note that CONFIG_EP93XX_DMA should be enabled as well.
Thanks to
=========
Martin Guy, H. Hartley Sweeten and others who helped me during development of
the driver. Simplemachines.it donated me a Sim.One board which I used testing
the driver on EP9307.
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-gpio.h> #include <linux/i2c-gpio.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -106,33 +105,10 @@ static struct cs4271_platform_data edb93xx_cs4271_data = { ...@@ -106,33 +105,10 @@ static struct cs4271_platform_data edb93xx_cs4271_data = {
.gpio_nreset = -EINVAL, /* filled in later */ .gpio_nreset = -EINVAL, /* filled in later */
}; };
static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
{
return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
GPIOF_OUT_INIT_HIGH, spi->modalias);
}
static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
{
gpio_free(EP93XX_GPIO_LINE_EGPIO6);
}
static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
}
static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
.setup = edb93xx_cs4271_hw_setup,
.cleanup = edb93xx_cs4271_hw_cleanup,
.cs_control = edb93xx_cs4271_hw_cs_control,
};
static struct spi_board_info edb93xx_spi_board_info[] __initdata = { static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
{ {
.modalias = "cs4271", .modalias = "cs4271",
.platform_data = &edb93xx_cs4271_data, .platform_data = &edb93xx_cs4271_data,
.controller_data = &edb93xx_cs4271_hw,
.max_speed_hz = 6000000, .max_speed_hz = 6000000,
.bus_num = 0, .bus_num = 0,
.chip_select = 0, .chip_select = 0,
...@@ -140,8 +116,13 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = { ...@@ -140,8 +116,13 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
}, },
}; };
static int edb93xx_spi_chipselects[] __initdata = {
EP93XX_GPIO_LINE_EGPIO6,
};
static struct ep93xx_spi_info edb93xx_spi_info __initdata = { static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
.num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info), .chipselect = edb93xx_spi_chipselects,
.num_chipselect = ARRAY_SIZE(edb93xx_spi_chipselects),
}; };
static void __init edb93xx_register_spi(void) static void __init edb93xx_register_spi(void)
......
...@@ -48,56 +48,6 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = { ...@@ -48,56 +48,6 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = {
*/ */
#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0
/*
* Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes
* low between multi-message command blocks. From v1.4, it uses a GPIO instead.
* v1.3 parts will still work, since the signal on SFRMOUT is automatic.
*/
#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1
/*
* MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal,
* you can leave these empty and pass NULL as .controller_data.
*/
static int simone_mmc_spi_setup(struct spi_device *spi)
{
unsigned int gpio = MMC_CHIP_SELECT_GPIO;
int err;
err = gpio_request(gpio, spi->modalias);
if (err)
return err;
err = gpio_direction_output(gpio, 1);
if (err) {
gpio_free(gpio);
return err;
}
return 0;
}
static void simone_mmc_spi_cleanup(struct spi_device *spi)
{
unsigned int gpio = MMC_CHIP_SELECT_GPIO;
gpio_set_value(gpio, 1);
gpio_direction_input(gpio);
gpio_free(gpio);
}
static void simone_mmc_spi_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
}
static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = {
.setup = simone_mmc_spi_setup,
.cleanup = simone_mmc_spi_cleanup,
.cs_control = simone_mmc_spi_cs_control,
};
/* /*
* MMC card detection GPIO setup. * MMC card detection GPIO setup.
*/ */
...@@ -152,7 +102,6 @@ static struct mmc_spi_platform_data simone_mmc_spi_data = { ...@@ -152,7 +102,6 @@ static struct mmc_spi_platform_data simone_mmc_spi_data = {
static struct spi_board_info simone_spi_devices[] __initdata = { static struct spi_board_info simone_spi_devices[] __initdata = {
{ {
.modalias = "mmc_spi", .modalias = "mmc_spi",
.controller_data = &simone_mmc_spi_ops,
.platform_data = &simone_mmc_spi_data, .platform_data = &simone_mmc_spi_data,
/* /*
* We use 10 MHz even though the maximum is 3.7 MHz. The driver * We use 10 MHz even though the maximum is 3.7 MHz. The driver
...@@ -165,8 +114,18 @@ static struct spi_board_info simone_spi_devices[] __initdata = { ...@@ -165,8 +114,18 @@ static struct spi_board_info simone_spi_devices[] __initdata = {
}, },
}; };
/*
* Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes
* low between multi-message command blocks. From v1.4, it uses a GPIO instead.
* v1.3 parts will still work, since the signal on SFRMOUT is automatic.
*/
static int simone_spi_chipselects[] __initdata = {
EP93XX_GPIO_LINE_EGPIO1,
};
static struct ep93xx_spi_info simone_spi_info __initdata = { static struct ep93xx_spi_info simone_spi_info __initdata = {
.num_chipselect = ARRAY_SIZE(simone_spi_devices), .chipselect = simone_spi_chipselects,
.num_chipselect = ARRAY_SIZE(simone_spi_chipselects),
.use_dma = 1, .use_dma = 1,
}; };
......
...@@ -175,33 +175,9 @@ static struct cs4271_platform_data vision_cs4271_data = { ...@@ -175,33 +175,9 @@ static struct cs4271_platform_data vision_cs4271_data = {
.gpio_nreset = EP93XX_GPIO_LINE_H(2), .gpio_nreset = EP93XX_GPIO_LINE_H(2),
}; };
static int vision_cs4271_hw_setup(struct spi_device *spi)
{
return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
GPIOF_OUT_INIT_HIGH, spi->modalias);
}
static void vision_cs4271_hw_cleanup(struct spi_device *spi)
{
gpio_free(EP93XX_GPIO_LINE_EGPIO6);
}
static void vision_cs4271_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
}
static struct ep93xx_spi_chip_ops vision_cs4271_hw = {
.setup = vision_cs4271_hw_setup,
.cleanup = vision_cs4271_hw_cleanup,
.cs_control = vision_cs4271_hw_cs_control,
};
/************************************************************************* /*************************************************************************
* SPI Flash * SPI Flash
*************************************************************************/ *************************************************************************/
#define VISION_SPI_FLASH_CS EP93XX_GPIO_LINE_EGPIO7
static struct mtd_partition vision_spi_flash_partitions[] = { static struct mtd_partition vision_spi_flash_partitions[] = {
{ {
.name = "SPI bootstrap", .name = "SPI bootstrap",
...@@ -224,68 +200,20 @@ static struct flash_platform_data vision_spi_flash_data = { ...@@ -224,68 +200,20 @@ static struct flash_platform_data vision_spi_flash_data = {
.nr_parts = ARRAY_SIZE(vision_spi_flash_partitions), .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions),
}; };
static int vision_spi_flash_hw_setup(struct spi_device *spi)
{
return gpio_request_one(VISION_SPI_FLASH_CS, GPIOF_INIT_HIGH,
spi->modalias);
}
static void vision_spi_flash_hw_cleanup(struct spi_device *spi)
{
gpio_free(VISION_SPI_FLASH_CS);
}
static void vision_spi_flash_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(VISION_SPI_FLASH_CS, value);
}
static struct ep93xx_spi_chip_ops vision_spi_flash_hw = {
.setup = vision_spi_flash_hw_setup,
.cleanup = vision_spi_flash_hw_cleanup,
.cs_control = vision_spi_flash_hw_cs_control,
};
/************************************************************************* /*************************************************************************
* SPI SD/MMC host * SPI SD/MMC host
*************************************************************************/ *************************************************************************/
#define VISION_SPI_MMC_CS EP93XX_GPIO_LINE_G(2)
#define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0)
#define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15
static struct mmc_spi_platform_data vision_spi_mmc_data = { static struct mmc_spi_platform_data vision_spi_mmc_data = {
.detect_delay = 100, .detect_delay = 100,
.powerup_msecs = 100, .powerup_msecs = 100,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
.cd_gpio = VISION_SPI_MMC_CD, .cd_gpio = EP93XX_GPIO_LINE_EGPIO15,
.cd_debounce = 1, .cd_debounce = 1,
.ro_gpio = VISION_SPI_MMC_WP, .ro_gpio = EP93XX_GPIO_LINE_F(0),
.caps2 = MMC_CAP2_RO_ACTIVE_HIGH, .caps2 = MMC_CAP2_RO_ACTIVE_HIGH,
}; };
static int vision_spi_mmc_hw_setup(struct spi_device *spi)
{
return gpio_request_one(VISION_SPI_MMC_CS, GPIOF_INIT_HIGH,
spi->modalias);
}
static void vision_spi_mmc_hw_cleanup(struct spi_device *spi)
{
gpio_free(VISION_SPI_MMC_CS);
}
static void vision_spi_mmc_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(VISION_SPI_MMC_CS, value);
}
static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = {
.setup = vision_spi_mmc_hw_setup,
.cleanup = vision_spi_mmc_hw_cleanup,
.cs_control = vision_spi_mmc_hw_cs_control,
};
/************************************************************************* /*************************************************************************
* SPI Bus * SPI Bus
*************************************************************************/ *************************************************************************/
...@@ -293,7 +221,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { ...@@ -293,7 +221,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
{ {
.modalias = "cs4271", .modalias = "cs4271",
.platform_data = &vision_cs4271_data, .platform_data = &vision_cs4271_data,
.controller_data = &vision_cs4271_hw,
.max_speed_hz = 6000000, .max_speed_hz = 6000000,
.bus_num = 0, .bus_num = 0,
.chip_select = 0, .chip_select = 0,
...@@ -301,7 +228,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { ...@@ -301,7 +228,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
}, { }, {
.modalias = "sst25l", .modalias = "sst25l",
.platform_data = &vision_spi_flash_data, .platform_data = &vision_spi_flash_data,
.controller_data = &vision_spi_flash_hw,
.max_speed_hz = 20000000, .max_speed_hz = 20000000,
.bus_num = 0, .bus_num = 0,
.chip_select = 1, .chip_select = 1,
...@@ -309,7 +235,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { ...@@ -309,7 +235,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
}, { }, {
.modalias = "mmc_spi", .modalias = "mmc_spi",
.platform_data = &vision_spi_mmc_data, .platform_data = &vision_spi_mmc_data,
.controller_data = &vision_spi_mmc_hw,
.max_speed_hz = 20000000, .max_speed_hz = 20000000,
.bus_num = 0, .bus_num = 0,
.chip_select = 2, .chip_select = 2,
...@@ -317,8 +242,15 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { ...@@ -317,8 +242,15 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
}, },
}; };
static int vision_spi_chipselects[] __initdata = {
EP93XX_GPIO_LINE_EGPIO6,
EP93XX_GPIO_LINE_EGPIO7,
EP93XX_GPIO_LINE_G(2),
};
static struct ep93xx_spi_info vision_spi_master __initdata = { static struct ep93xx_spi_info vision_spi_master __initdata = {
.num_chipselect = ARRAY_SIZE(vision_spi_board_info), .chipselect = vision_spi_chipselects,
.num_chipselect = ARRAY_SIZE(vision_spi_chipselects),
.use_dma = 1, .use_dma = 1,
}; };
......
...@@ -162,7 +162,8 @@ config SPI_BCM63XX_HSSPI ...@@ -162,7 +162,8 @@ config SPI_BCM63XX_HSSPI
config SPI_BCM_QSPI config SPI_BCM_QSPI
tristate "Broadcom BSPI and MSPI controller support" tristate "Broadcom BSPI and MSPI controller support"
depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || COMPILE_TEST depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || \
BMIPS_GENERIC || COMPILE_TEST
default ARCH_BCM_IPROC default ARCH_BCM_IPROC
help help
Enables support for the Broadcom SPI flash and MSPI controller. Enables support for the Broadcom SPI flash and MSPI controller.
...@@ -263,7 +264,7 @@ config SPI_EP93XX ...@@ -263,7 +264,7 @@ config SPI_EP93XX
mode. mode.
config SPI_FALCON config SPI_FALCON
tristate "Falcon SPI controller support" bool "Falcon SPI controller support"
depends on SOC_FALCON depends on SOC_FALCON
help help
The external bus unit (EBU) found on the FALC-ON SoC has SPI The external bus unit (EBU) found on the FALC-ON SoC has SPI
...@@ -416,6 +417,14 @@ config SPI_NUC900 ...@@ -416,6 +417,14 @@ config SPI_NUC900
help help
SPI driver for Nuvoton NUC900 series ARM SoCs SPI driver for Nuvoton NUC900 series ARM SoCs
config SPI_LANTIQ_SSC
tristate "Lantiq SSC SPI controller"
depends on LANTIQ || COMPILE_TEST
help
This driver supports the Lantiq SSC SPI controller in master
mode. This controller is found on Intel (former Lantiq) SoCs like
the Danube, Falcon, xRX200, xRX300.
config SPI_OC_TINY config SPI_OC_TINY
tristate "OpenCores tiny SPI" tristate "OpenCores tiny SPI"
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
......
...@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o ...@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
obj-$(CONFIG_SPI_GPIO) += spi-gpio.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_IMX) += spi-imx.o
obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
obj-$(CONFIG_SPI_JCORE) += spi-jcore.o obj-$(CONFIG_SPI_JCORE) += spi-jcore.o
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
......
...@@ -170,12 +170,12 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, ...@@ -170,12 +170,12 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
val &= ~(A3700_SPI_DATA_PIN0 | A3700_SPI_DATA_PIN1); val &= ~(A3700_SPI_DATA_PIN0 | A3700_SPI_DATA_PIN1);
switch (pin_mode) { switch (pin_mode) {
case 1: case SPI_NBITS_SINGLE:
break; break;
case 2: case SPI_NBITS_DUAL:
val |= A3700_SPI_DATA_PIN0; val |= A3700_SPI_DATA_PIN0;
break; break;
case 4: case SPI_NBITS_QUAD:
val |= A3700_SPI_DATA_PIN1; val |= A3700_SPI_DATA_PIN1;
break; break;
default: default:
...@@ -340,8 +340,7 @@ static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id) ...@@ -340,8 +340,7 @@ static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id)
spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, cause); spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, cause);
/* Wake up the transfer */ /* Wake up the transfer */
if (a3700_spi->wait_mask & cause) complete(&a3700_spi->done);
complete(&a3700_spi->done);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -421,7 +420,7 @@ static void a3700_spi_fifo_thres_set(struct a3700_spi *a3700_spi, ...@@ -421,7 +420,7 @@ static void a3700_spi_fifo_thres_set(struct a3700_spi *a3700_spi,
} }
static void a3700_spi_transfer_setup(struct spi_device *spi, static void a3700_spi_transfer_setup(struct spi_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
struct a3700_spi *a3700_spi; struct a3700_spi *a3700_spi;
unsigned int byte_len; unsigned int byte_len;
...@@ -562,6 +561,7 @@ static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi) ...@@ -562,6 +561,7 @@ static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi)
val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG); val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG);
if (a3700_spi->buf_len >= 4) { if (a3700_spi->buf_len >= 4) {
u32 data = le32_to_cpu(val); u32 data = le32_to_cpu(val);
memcpy(a3700_spi->rx_buf, &data, 4); memcpy(a3700_spi->rx_buf, &data, 4);
a3700_spi->buf_len -= 4; a3700_spi->buf_len -= 4;
...@@ -901,7 +901,6 @@ static int a3700_spi_remove(struct platform_device *pdev) ...@@ -901,7 +901,6 @@ static int a3700_spi_remove(struct platform_device *pdev)
struct a3700_spi *spi = spi_master_get_devdata(master); struct a3700_spi *spi = spi_master_get_devdata(master);
clk_unprepare(spi->clk); clk_unprepare(spi->clk);
spi_master_put(master);
return 0; return 0;
} }
...@@ -909,7 +908,6 @@ static int a3700_spi_remove(struct platform_device *pdev) ...@@ -909,7 +908,6 @@ static int a3700_spi_remove(struct platform_device *pdev)
static struct platform_driver a3700_spi_driver = { static struct platform_driver a3700_spi_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(a3700_spi_dt_ids), .of_match_table = of_match_ptr(a3700_spi_dt_ids),
}, },
.probe = a3700_spi_probe, .probe = a3700_spi_probe,
......
...@@ -78,14 +78,16 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active) ...@@ -78,14 +78,16 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
} }
if (spi->chip_select) { if (gpio_is_valid(spi->cs_gpio)) {
/* SPI is normally active-low */ /* SPI is normally active-low */
gpio_set_value(spi->cs_gpio, cs_high); gpio_set_value_cansleep(spi->cs_gpio, cs_high);
} else { } else {
u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
if (cs_high) if (cs_high)
sp->ioc_base |= AR71XX_SPI_IOC_CS0; sp->ioc_base |= cs_bit;
else else
sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; sp->ioc_base &= ~cs_bit;
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
} }
...@@ -118,11 +120,8 @@ static int ath79_spi_setup_cs(struct spi_device *spi) ...@@ -118,11 +120,8 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
struct ath79_spi *sp = ath79_spidev_to_sp(spi); struct ath79_spi *sp = ath79_spidev_to_sp(spi);
int status; int status;
if (spi->chip_select && !gpio_is_valid(spi->cs_gpio))
return -EINVAL;
status = 0; status = 0;
if (spi->chip_select) { if (gpio_is_valid(spi->cs_gpio)) {
unsigned long flags; unsigned long flags;
flags = GPIOF_DIR_OUT; flags = GPIOF_DIR_OUT;
...@@ -134,10 +133,12 @@ static int ath79_spi_setup_cs(struct spi_device *spi) ...@@ -134,10 +133,12 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
status = gpio_request_one(spi->cs_gpio, flags, status = gpio_request_one(spi->cs_gpio, flags,
dev_name(&spi->dev)); dev_name(&spi->dev));
} else { } else {
u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; sp->ioc_base &= ~cs_bit;
else else
sp->ioc_base |= AR71XX_SPI_IOC_CS0; sp->ioc_base |= cs_bit;
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
} }
...@@ -147,7 +148,7 @@ static int ath79_spi_setup_cs(struct spi_device *spi) ...@@ -147,7 +148,7 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
static void ath79_spi_cleanup_cs(struct spi_device *spi) static void ath79_spi_cleanup_cs(struct spi_device *spi)
{ {
if (spi->chip_select) { if (gpio_is_valid(spi->cs_gpio)) {
gpio_free(spi->cs_gpio); gpio_free(spi->cs_gpio);
} }
} }
......
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
#define BSPI_BPP_MODE_SELECT_MASK BIT(8) #define BSPI_BPP_MODE_SELECT_MASK BIT(8)
#define BSPI_BPP_ADDR_SELECT_MASK BIT(16) #define BSPI_BPP_ADDR_SELECT_MASK BIT(16)
#define BSPI_READ_LENGTH 256 #define BSPI_READ_LENGTH 512
/* MSPI register offsets */ /* MSPI register offsets */
#define MSPI_SPCR0_LSB 0x000 #define MSPI_SPCR0_LSB 0x000
...@@ -192,9 +192,11 @@ struct bcm_qspi_dev_id { ...@@ -192,9 +192,11 @@ struct bcm_qspi_dev_id {
void *dev; void *dev;
}; };
struct qspi_trans { struct qspi_trans {
struct spi_transfer *trans; struct spi_transfer *trans;
int byte; int byte;
bool mspi_last_trans;
}; };
struct bcm_qspi { struct bcm_qspi {
...@@ -616,6 +618,16 @@ static int bcm_qspi_setup(struct spi_device *spi) ...@@ -616,6 +618,16 @@ static int bcm_qspi_setup(struct spi_device *spi)
return 0; return 0;
} }
static bool bcm_qspi_mspi_transfer_is_last(struct bcm_qspi *qspi,
struct qspi_trans *qt)
{
if (qt->mspi_last_trans &&
spi_transfer_is_last(qspi->master, qt->trans))
return true;
else
return false;
}
static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, static int update_qspi_trans_byte_count(struct bcm_qspi *qspi,
struct qspi_trans *qt, int flags) struct qspi_trans *qt, int flags)
{ {
...@@ -629,7 +641,6 @@ static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, ...@@ -629,7 +641,6 @@ static int update_qspi_trans_byte_count(struct bcm_qspi *qspi,
if (qt->byte >= qt->trans->len) { if (qt->byte >= qt->trans->len) {
/* we're at the end of the spi_transfer */ /* we're at the end of the spi_transfer */
/* in TX mode, need to pause for a delay or CS change */ /* in TX mode, need to pause for a delay or CS change */
if (qt->trans->delay_usecs && if (qt->trans->delay_usecs &&
(flags & TRANS_STATUS_BREAK_DELAY)) (flags & TRANS_STATUS_BREAK_DELAY))
...@@ -641,7 +652,7 @@ static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, ...@@ -641,7 +652,7 @@ static int update_qspi_trans_byte_count(struct bcm_qspi *qspi,
goto done; goto done;
dev_dbg(&qspi->pdev->dev, "advance msg exit\n"); dev_dbg(&qspi->pdev->dev, "advance msg exit\n");
if (spi_transfer_is_last(qspi->master, qt->trans)) if (bcm_qspi_mspi_transfer_is_last(qspi, qt))
ret = TRANS_STATUS_BREAK_EOM; ret = TRANS_STATUS_BREAK_EOM;
else else
ret = TRANS_STATUS_BREAK_NO_BYTES; ret = TRANS_STATUS_BREAK_NO_BYTES;
...@@ -813,7 +824,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, ...@@ -813,7 +824,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
struct spi_flash_read_message *msg) struct spi_flash_read_message *msg)
{ {
struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
u32 addr = 0, len, len_words; u32 addr = 0, len, rdlen, len_words;
int ret = 0; int ret = 0;
unsigned long timeo = msecs_to_jiffies(100); unsigned long timeo = msecs_to_jiffies(100);
struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
...@@ -826,7 +837,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, ...@@ -826,7 +837,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
/* /*
* when using flex mode mode we need to send * when using flex mode we need to send
* the upper address byte to bspi * the upper address byte to bspi
*/ */
if (bcm_qspi_bspi_ver_three(qspi) == false) { if (bcm_qspi_bspi_ver_three(qspi) == false) {
...@@ -840,48 +851,127 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, ...@@ -840,48 +851,127 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
else else
addr = msg->from & 0x00ffffff; addr = msg->from & 0x00ffffff;
/* set BSPI RAF buffer max read length */
len = msg->len;
if (len > BSPI_READ_LENGTH)
len = BSPI_READ_LENGTH;
if (bcm_qspi_bspi_ver_three(qspi) == true) if (bcm_qspi_bspi_ver_three(qspi) == true)
addr = (addr + 0xc00000) & 0xffffff; addr = (addr + 0xc00000) & 0xffffff;
reinit_completion(&qspi->bspi_done); /*
bcm_qspi_enable_bspi(qspi); * read into the entire buffer by breaking the reads
len_words = (len + 3) >> 2; * into RAF buffer read lengths
qspi->bspi_rf_msg = msg; */
qspi->bspi_rf_msg_status = 0; len = msg->len;
qspi->bspi_rf_msg_idx = 0; qspi->bspi_rf_msg_idx = 0;
qspi->bspi_rf_msg_len = len;
dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); do {
bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); if (len > BSPI_READ_LENGTH)
bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); rdlen = BSPI_READ_LENGTH;
else
rdlen = len;
reinit_completion(&qspi->bspi_done);
bcm_qspi_enable_bspi(qspi);
len_words = (rdlen + 3) >> 2;
qspi->bspi_rf_msg = msg;
qspi->bspi_rf_msg_status = 0;
qspi->bspi_rf_msg_len = rdlen;
dev_dbg(&qspi->pdev->dev,
"bspi xfr addr 0x%x len 0x%x", addr, rdlen);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
if (qspi->soc_intc) {
/*
* clear soc MSPI and BSPI interrupts and enable
* BSPI interrupts.
*/
soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE);
soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true);
}
if (qspi->soc_intc) { /* Must flush previous writes before starting BSPI operation */
/* mb();
* clear soc MSPI and BSPI interrupts and enable bcm_qspi_bspi_lr_start(qspi);
* BSPI interrupts. if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {
*/ dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n");
soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE); ret = -ETIMEDOUT;
soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true); break;
}
/* set msg return length */
msg->retlen += rdlen;
addr += rdlen;
len -= rdlen;
} while (len);
return ret;
}
static int bcm_qspi_transfer_one(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *trans)
{
struct bcm_qspi *qspi = spi_master_get_devdata(master);
int slots;
unsigned long timeo = msecs_to_jiffies(100);
bcm_qspi_chip_select(qspi, spi->chip_select);
qspi->trans_pos.trans = trans;
qspi->trans_pos.byte = 0;
while (qspi->trans_pos.byte < trans->len) {
reinit_completion(&qspi->mspi_done);
slots = write_to_hw(qspi, spi);
if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) {
dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n");
return -ETIMEDOUT;
}
read_from_hw(qspi, slots);
} }
/* Must flush previous writes before starting BSPI operation */ return 0;
mb(); }
bcm_qspi_bspi_lr_start(qspi); static int bcm_qspi_mspi_flash_read(struct spi_device *spi,
if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { struct spi_flash_read_message *msg)
dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); {
ret = -ETIMEDOUT; struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
} else { struct spi_transfer t[2];
/* set the return length for the caller */ u8 cmd[6];
msg->retlen = len; int ret;
memset(cmd, 0, sizeof(cmd));
memset(t, 0, sizeof(t));
/* tx */
/* opcode is in cmd[0] */
cmd[0] = msg->read_opcode;
cmd[1] = msg->from >> (msg->addr_width * 8 - 8);
cmd[2] = msg->from >> (msg->addr_width * 8 - 16);
cmd[3] = msg->from >> (msg->addr_width * 8 - 24);
cmd[4] = msg->from >> (msg->addr_width * 8 - 32);
t[0].tx_buf = cmd;
t[0].len = msg->addr_width + msg->dummy_bytes + 1;
t[0].bits_per_word = spi->bits_per_word;
t[0].tx_nbits = msg->opcode_nbits;
/* lets mspi know that this is not last transfer */
qspi->trans_pos.mspi_last_trans = false;
ret = bcm_qspi_transfer_one(spi->master, spi, &t[0]);
/* rx */
qspi->trans_pos.mspi_last_trans = true;
if (!ret) {
/* rx */
t[1].rx_buf = msg->buf;
t[1].len = msg->len;
t[1].rx_nbits = msg->data_nbits;
t[1].bits_per_word = spi->bits_per_word;
ret = bcm_qspi_transfer_one(spi->master, spi, &t[1]);
} }
if (!ret)
msg->retlen = msg->len;
return ret; return ret;
} }
...@@ -918,8 +1008,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi, ...@@ -918,8 +1008,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi,
mspi_read = true; mspi_read = true;
if (mspi_read) if (mspi_read)
/* this will make the m25p80 read to fallback to mspi read */ return bcm_qspi_mspi_flash_read(spi, msg);
return -EAGAIN;
io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
addrlen = msg->addr_width; addrlen = msg->addr_width;
...@@ -931,33 +1020,6 @@ static int bcm_qspi_flash_read(struct spi_device *spi, ...@@ -931,33 +1020,6 @@ static int bcm_qspi_flash_read(struct spi_device *spi,
return ret; return ret;
} }
static int bcm_qspi_transfer_one(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *trans)
{
struct bcm_qspi *qspi = spi_master_get_devdata(master);
int slots;
unsigned long timeo = msecs_to_jiffies(100);
bcm_qspi_chip_select(qspi, spi->chip_select);
qspi->trans_pos.trans = trans;
qspi->trans_pos.byte = 0;
while (qspi->trans_pos.byte < trans->len) {
reinit_completion(&qspi->mspi_done);
slots = write_to_hw(qspi, spi);
if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) {
dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n");
return -ETIMEDOUT;
}
read_from_hw(qspi, slots);
}
return 0;
}
static void bcm_qspi_cleanup(struct spi_device *spi) static void bcm_qspi_cleanup(struct spi_device *spi)
{ {
struct bcm_qspi_parms *xp = spi_get_ctldata(spi); struct bcm_qspi_parms *xp = spi_get_ctldata(spi);
...@@ -1187,6 +1249,7 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1187,6 +1249,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->pdev = pdev; qspi->pdev = pdev;
qspi->trans_pos.trans = NULL; qspi->trans_pos.trans = NULL;
qspi->trans_pos.byte = 0; qspi->trans_pos.byte = 0;
qspi->trans_pos.mspi_last_trans = true;
qspi->master = master; qspi->master = master;
master->bus_num = -1; master->bus_num = -1;
...@@ -1345,7 +1408,6 @@ int bcm_qspi_remove(struct platform_device *pdev) ...@@ -1345,7 +1408,6 @@ int bcm_qspi_remove(struct platform_device *pdev)
{ {
struct bcm_qspi *qspi = platform_get_drvdata(pdev); struct bcm_qspi *qspi = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
bcm_qspi_hw_uninit(qspi); bcm_qspi_hw_uninit(qspi);
clk_disable_unprepare(qspi->clk); clk_disable_unprepare(qspi->clk);
kfree(qspi->dev_ids); kfree(qspi->dev_ids);
......
/*
* Copyright (C) 2014-2016 Rafał Miłecki <rafal@milecki.pl>
*
* 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.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -275,10 +283,6 @@ static int bcm53xxspi_flash_read(struct spi_device *spi, ...@@ -275,10 +283,6 @@ static int bcm53xxspi_flash_read(struct spi_device *spi,
* BCMA * BCMA
**************************************************/ **************************************************/
static struct spi_board_info bcm53xx_info = {
.modalias = "bcm53xxspiflash",
};
static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = { static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS), BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS),
{}, {},
...@@ -311,6 +315,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) ...@@ -311,6 +315,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core)
b53spi->bspi = true; b53spi->bspi = true;
bcm53xxspi_disable_bspi(b53spi); bcm53xxspi_disable_bspi(b53spi);
master->dev.of_node = dev->of_node;
master->transfer_one = bcm53xxspi_transfer_one; master->transfer_one = bcm53xxspi_transfer_one;
if (b53spi->mmio_base) if (b53spi->mmio_base)
master->spi_flash_read = bcm53xxspi_flash_read; master->spi_flash_read = bcm53xxspi_flash_read;
...@@ -324,9 +329,6 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) ...@@ -324,9 +329,6 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core)
return err; return err;
} }
/* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */
spi_new_device(master, &bcm53xx_info);
return 0; return 0;
} }
...@@ -361,4 +363,4 @@ module_exit(bcm53xxspi_module_exit); ...@@ -361,4 +363,4 @@ module_exit(bcm53xxspi_module_exit);
MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver"); MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver");
MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>"); MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL v2");
...@@ -107,9 +107,9 @@ static const struct file_operations dw_spi_regs_ops = { ...@@ -107,9 +107,9 @@ static const struct file_operations dw_spi_regs_ops = {
static int dw_spi_debugfs_init(struct dw_spi *dws) static int dw_spi_debugfs_init(struct dw_spi *dws)
{ {
char name[128]; char name[32];
snprintf(name, 128, "dw_spi-%s", dev_name(&dws->master->dev)); snprintf(name, 32, "dw_spi%d", dws->master->bus_num);
dws->debugfs = debugfs_create_dir(name, NULL); dws->debugfs = debugfs_create_dir(name, NULL);
if (!dws->debugfs) if (!dws->debugfs)
return -ENOMEM; return -ENOMEM;
...@@ -486,9 +486,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) ...@@ -486,9 +486,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
dws->type = SSI_MOTO_SPI; dws->type = SSI_MOTO_SPI;
dws->dma_inited = 0; dws->dma_inited = 0;
dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num);
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master); ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
master);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "can not get IRQ\n"); dev_err(dev, "can not get IRQ\n");
goto err_free_master; goto err_free_master;
......
...@@ -101,7 +101,6 @@ struct dw_spi_dma_ops { ...@@ -101,7 +101,6 @@ struct dw_spi_dma_ops {
struct dw_spi { struct dw_spi {
struct spi_master *master; struct spi_master *master;
enum dw_ssi_type type; enum dw_ssi_type type;
char name[16];
void __iomem *regs; void __iomem *regs;
unsigned long paddr; unsigned long paddr;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/platform_data/dma-ep93xx.h> #include <linux/platform_data/dma-ep93xx.h>
...@@ -107,16 +108,6 @@ struct ep93xx_spi { ...@@ -107,16 +108,6 @@ struct ep93xx_spi {
void *zeropage; void *zeropage;
}; };
/**
* struct ep93xx_spi_chip - SPI device hardware settings
* @spi: back pointer to the SPI device
* @ops: private chip operations
*/
struct ep93xx_spi_chip {
const struct spi_device *spi;
struct ep93xx_spi_chip_ops *ops;
};
/* converts bits per word to CR0.DSS value */ /* converts bits per word to CR0.DSS value */
#define bits_per_word_to_dss(bpw) ((bpw) - 1) #define bits_per_word_to_dss(bpw) ((bpw) - 1)
...@@ -229,104 +220,36 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, ...@@ -229,104 +220,36 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi,
return -EINVAL; return -EINVAL;
} }
static void ep93xx_spi_cs_control(struct spi_device *spi, bool control) static void ep93xx_spi_cs_control(struct spi_device *spi, bool enable)
{
struct ep93xx_spi_chip *chip = spi_get_ctldata(spi);
int value = (spi->mode & SPI_CS_HIGH) ? control : !control;
if (chip->ops && chip->ops->cs_control)
chip->ops->cs_control(spi, value);
}
/**
* ep93xx_spi_setup() - setup an SPI device
* @spi: SPI device to setup
*
* This function sets up SPI device mode, speed etc. Can be called multiple
* times for a single device. Returns %0 in case of success, negative error in
* case of failure. When this function returns success, the device is
* deselected.
*/
static int ep93xx_spi_setup(struct spi_device *spi)
{ {
struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); if (spi->mode & SPI_CS_HIGH)
struct ep93xx_spi_chip *chip; enable = !enable;
chip = spi_get_ctldata(spi); if (gpio_is_valid(spi->cs_gpio))
if (!chip) { gpio_set_value(spi->cs_gpio, !enable);
dev_dbg(&espi->pdev->dev, "initial setup for %s\n",
spi->modalias);
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
chip->spi = spi;
chip->ops = spi->controller_data;
if (chip->ops && chip->ops->setup) {
int ret = chip->ops->setup(spi);
if (ret) {
kfree(chip);
return ret;
}
}
spi_set_ctldata(spi, chip);
}
ep93xx_spi_cs_control(spi, false);
return 0;
} }
/**
* ep93xx_spi_cleanup() - cleans up master controller specific state
* @spi: SPI device to cleanup
*
* This function releases master controller specific state for given @spi
* device.
*/
static void ep93xx_spi_cleanup(struct spi_device *spi)
{
struct ep93xx_spi_chip *chip;
chip = spi_get_ctldata(spi);
if (chip) {
if (chip->ops && chip->ops->cleanup)
chip->ops->cleanup(spi);
spi_set_ctldata(spi, NULL);
kfree(chip);
}
}
/**
* ep93xx_spi_chip_setup() - configures hardware according to given @chip
* @espi: ep93xx SPI controller struct
* @chip: chip specific settings
* @speed_hz: transfer speed
* @bits_per_word: transfer bits_per_word
*/
static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi,
const struct ep93xx_spi_chip *chip, struct spi_device *spi,
u32 speed_hz, u8 bits_per_word) struct spi_transfer *xfer)
{ {
u8 dss = bits_per_word_to_dss(bits_per_word); u8 dss = bits_per_word_to_dss(xfer->bits_per_word);
u8 div_cpsr = 0; u8 div_cpsr = 0;
u8 div_scr = 0; u8 div_scr = 0;
u16 cr0; u16 cr0;
int err; int err;
err = ep93xx_spi_calc_divisors(espi, speed_hz, &div_cpsr, &div_scr); err = ep93xx_spi_calc_divisors(espi, xfer->speed_hz,
&div_cpsr, &div_scr);
if (err) if (err)
return err; return err;
cr0 = div_scr << SSPCR0_SCR_SHIFT; cr0 = div_scr << SSPCR0_SCR_SHIFT;
cr0 |= (chip->spi->mode & (SPI_CPHA|SPI_CPOL)) << SSPCR0_MODE_SHIFT; cr0 |= (spi->mode & (SPI_CPHA | SPI_CPOL)) << SSPCR0_MODE_SHIFT;
cr0 |= dss; cr0 |= dss;
dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
chip->spi->mode, div_cpsr, div_scr, dss); spi->mode, div_cpsr, div_scr, dss);
dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0);
ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr);
...@@ -603,12 +526,11 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, ...@@ -603,12 +526,11 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi,
struct spi_message *msg, struct spi_message *msg,
struct spi_transfer *t) struct spi_transfer *t)
{ {
struct ep93xx_spi_chip *chip = spi_get_ctldata(msg->spi);
int err; int err;
msg->state = t; msg->state = t;
err = ep93xx_spi_chip_setup(espi, chip, t->speed_hz, t->bits_per_word); err = ep93xx_spi_chip_setup(espi, msg->spi, t);
if (err) { if (err) {
dev_err(&espi->pdev->dev, dev_err(&espi->pdev->dev,
"failed to setup chip for transfer\n"); "failed to setup chip for transfer\n");
...@@ -863,8 +785,13 @@ static int ep93xx_spi_probe(struct platform_device *pdev) ...@@ -863,8 +785,13 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int irq; int irq;
int error; int error;
int i;
info = dev_get_platdata(&pdev->dev); info = dev_get_platdata(&pdev->dev);
if (!info) {
dev_err(&pdev->dev, "missing platform data\n");
return -EINVAL;
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
...@@ -882,14 +809,36 @@ static int ep93xx_spi_probe(struct platform_device *pdev) ...@@ -882,14 +809,36 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
master->setup = ep93xx_spi_setup;
master->transfer_one_message = ep93xx_spi_transfer_one_message; master->transfer_one_message = ep93xx_spi_transfer_one_message;
master->cleanup = ep93xx_spi_cleanup;
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->num_chipselect = info->num_chipselect;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
master->num_chipselect = info->num_chipselect;
master->cs_gpios = devm_kzalloc(&master->dev,
sizeof(int) * master->num_chipselect,
GFP_KERNEL);
if (!master->cs_gpios) {
error = -ENOMEM;
goto fail_release_master;
}
for (i = 0; i < master->num_chipselect; i++) {
master->cs_gpios[i] = info->chipselect[i];
if (!gpio_is_valid(master->cs_gpios[i]))
continue;
error = devm_gpio_request_one(&pdev->dev, master->cs_gpios[i],
GPIOF_OUT_INIT_HIGH,
"ep93xx-spi");
if (error) {
dev_err(&pdev->dev, "could not request cs gpio %d\n",
master->cs_gpios[i]);
goto fail_release_master;
}
}
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
espi = spi_master_get_devdata(master); espi = spi_master_get_devdata(master);
......
...@@ -366,7 +366,7 @@ static int fsl_lpspi_transfer_one_msg(struct spi_master *master, ...@@ -366,7 +366,7 @@ static int fsl_lpspi_transfer_one_msg(struct spi_master *master,
struct spi_transfer *xfer; struct spi_transfer *xfer;
bool is_first_xfer = true; bool is_first_xfer = true;
u32 temp; u32 temp;
int ret; int ret = 0;
msg->status = 0; msg->status = 0;
msg->actual_length = 0; msg->actual_length = 0;
...@@ -512,9 +512,9 @@ static int fsl_lpspi_remove(struct platform_device *pdev) ...@@ -512,9 +512,9 @@ static int fsl_lpspi_remove(struct platform_device *pdev)
static struct platform_driver fsl_lpspi_driver = { static struct platform_driver fsl_lpspi_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = fsl_lpspi_dt_ids, .of_match_table = fsl_lpspi_dt_ids,
}, },
.probe = fsl_lpspi_probe, .probe = fsl_lpspi_probe,
.remove = fsl_lpspi_remove, .remove = fsl_lpspi_remove,
}; };
......
...@@ -267,10 +267,9 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, ...@@ -267,10 +267,9 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,
if ((mpc8xxx_spi->spibrg / hz) > 64) { if ((mpc8xxx_spi->spibrg / hz) > 64) {
cs->hw_mode |= SPMODE_DIV16; cs->hw_mode |= SPMODE_DIV16;
pm = (mpc8xxx_spi->spibrg - 1) / (hz * 64) + 1; pm = (mpc8xxx_spi->spibrg - 1) / (hz * 64) + 1;
WARN_ONCE(pm > 16,
WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. " "%s: Requested speed is too low: %d Hz. Will use %d Hz instead.\n",
"Will use %d Hz instead.\n", dev_name(&spi->dev), dev_name(&spi->dev), hz, mpc8xxx_spi->spibrg / 1024);
hz, mpc8xxx_spi->spibrg / 1024);
if (pm > 16) if (pm > 16)
pm = 16; pm = 16;
} else { } else {
...@@ -727,12 +726,13 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ...@@ -727,12 +726,13 @@ static int of_fsl_spi_get_chipselects(struct device *dev)
return 0; return 0;
} }
pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL); pinfo->gpios = kmalloc_array(ngpios, sizeof(*pinfo->gpios),
GFP_KERNEL);
if (!pinfo->gpios) if (!pinfo->gpios)
return -ENOMEM; return -ENOMEM;
memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios)); memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios));
pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags), pinfo->alow_flags = kcalloc(ngpios, sizeof(*pinfo->alow_flags),
GFP_KERNEL); GFP_KERNEL);
if (!pinfo->alow_flags) { if (!pinfo->alow_flags) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -762,8 +762,9 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ...@@ -762,8 +762,9 @@ static int of_fsl_spi_get_chipselects(struct device *dev)
ret = gpio_direction_output(pinfo->gpios[i], ret = gpio_direction_output(pinfo->gpios[i],
pinfo->alow_flags[i]); pinfo->alow_flags[i]);
if (ret) { if (ret) {
dev_err(dev, "can't set output direction for gpio " dev_err(dev,
"#%d: %d\n", i, ret); "can't set output direction for gpio #%d: %d\n",
i, ret);
goto err_loop; goto err_loop;
} }
} }
......
...@@ -211,7 +211,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -211,7 +211,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *transfer) struct spi_transfer *transfer)
{ {
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
unsigned int bpw; unsigned int bpw, i;
if (!master->dma_rx) if (!master->dma_rx)
return false; return false;
...@@ -228,12 +228,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -228,12 +228,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
if (bpw != 1 && bpw != 2 && bpw != 4) if (bpw != 1 && bpw != 2 && bpw != 4)
return false; return false;
if (transfer->len < spi_imx->wml * bpw) for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) {
return false; if (!(transfer->len % (i * bpw)))
break;
}
if (transfer->len % (spi_imx->wml * bpw)) if (i == 0)
return false; return false;
spi_imx->wml = i;
return true; return true;
} }
...@@ -837,10 +841,6 @@ static int spi_imx_dma_configure(struct spi_master *master, ...@@ -837,10 +841,6 @@ static int spi_imx_dma_configure(struct spi_master *master,
struct dma_slave_config rx = {}, tx = {}; struct dma_slave_config rx = {}, tx = {};
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
if (bytes_per_word == spi_imx->bytes_per_word)
/* Same as last time */
return 0;
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: case 4:
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
......
This diff is collapsed.
...@@ -437,8 +437,9 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -437,8 +437,9 @@ static int mpc52xx_spi_probe(struct platform_device *op)
ms->gpio_cs_count = of_gpio_count(op->dev.of_node); ms->gpio_cs_count = of_gpio_count(op->dev.of_node);
if (ms->gpio_cs_count > 0) { if (ms->gpio_cs_count > 0) {
master->num_chipselect = ms->gpio_cs_count; master->num_chipselect = ms->gpio_cs_count;
ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int), ms->gpio_cs = kmalloc_array(ms->gpio_cs_count,
GFP_KERNEL); sizeof(*ms->gpio_cs),
GFP_KERNEL);
if (!ms->gpio_cs) { if (!ms->gpio_cs) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_alloc_gpio; goto err_alloc_gpio;
...@@ -448,8 +449,7 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -448,8 +449,7 @@ static int mpc52xx_spi_probe(struct platform_device *op)
gpio_cs = of_get_gpio(op->dev.of_node, i); gpio_cs = of_get_gpio(op->dev.of_node, i);
if (gpio_cs < 0) { if (gpio_cs < 0) {
dev_err(&op->dev, dev_err(&op->dev,
"could not parse the gpio field " "could not parse the gpio field in oftree\n");
"in oftree\n");
rc = -ENODEV; rc = -ENODEV;
goto err_gpio; goto err_gpio;
} }
...@@ -457,8 +457,8 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -457,8 +457,8 @@ static int mpc52xx_spi_probe(struct platform_device *op)
rc = gpio_request(gpio_cs, dev_name(&op->dev)); rc = gpio_request(gpio_cs, dev_name(&op->dev));
if (rc) { if (rc) {
dev_err(&op->dev, dev_err(&op->dev,
"can't request spi cs gpio #%d " "can't request spi cs gpio #%d on gpio line %d\n",
"on gpio line %d\n", i, gpio_cs); i, gpio_cs);
goto err_gpio; goto err_gpio;
} }
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
#define MTK_SPI_IDLE 0 #define MTK_SPI_IDLE 0
#define MTK_SPI_PAUSED 1 #define MTK_SPI_PAUSED 1
#define MTK_SPI_MAX_FIFO_SIZE 32 #define MTK_SPI_MAX_FIFO_SIZE 32U
#define MTK_SPI_PACKET_SIZE 1024 #define MTK_SPI_PACKET_SIZE 1024
struct mtk_spi_compatible { struct mtk_spi_compatible {
...@@ -333,7 +333,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, ...@@ -333,7 +333,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
struct mtk_spi *mdata = spi_master_get_devdata(master); struct mtk_spi *mdata = spi_master_get_devdata(master);
mdata->cur_transfer = xfer; mdata->cur_transfer = xfer;
mdata->xfer_len = xfer->len; mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, xfer->len);
mtk_spi_prepare_transfer(master, xfer); mtk_spi_prepare_transfer(master, xfer);
mtk_spi_setup_packet(master); mtk_spi_setup_packet(master);
...@@ -410,7 +410,10 @@ static bool mtk_spi_can_dma(struct spi_master *master, ...@@ -410,7 +410,10 @@ static bool mtk_spi_can_dma(struct spi_master *master,
struct spi_device *spi, struct spi_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
return xfer->len > MTK_SPI_MAX_FIFO_SIZE; /* Buffers for DMA transactions must be 4-byte aligned */
return (xfer->len > MTK_SPI_MAX_FIFO_SIZE &&
(unsigned long)xfer->tx_buf % 4 == 0 &&
(unsigned long)xfer->rx_buf % 4 == 0);
} }
static int mtk_spi_setup(struct spi_device *spi) static int mtk_spi_setup(struct spi_device *spi)
...@@ -451,7 +454,33 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) ...@@ -451,7 +454,33 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
&reg_val, remainder); &reg_val, remainder);
} }
} }
spi_finalize_current_transfer(master);
trans->len -= mdata->xfer_len;
if (!trans->len) {
spi_finalize_current_transfer(master);
return IRQ_HANDLED;
}
if (trans->tx_buf)
trans->tx_buf += mdata->xfer_len;
if (trans->rx_buf)
trans->rx_buf += mdata->xfer_len;
mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, trans->len);
mtk_spi_setup_packet(master);
cnt = trans->len / 4;
iowrite32_rep(mdata->base + SPI_TX_DATA_REG, trans->tx_buf, cnt);
remainder = trans->len % 4;
if (remainder > 0) {
reg_val = 0;
memcpy(&reg_val, trans->tx_buf + (cnt * 4), remainder);
writel(reg_val, mdata->base + SPI_TX_DATA_REG);
}
mtk_spi_enable_transfer(master);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -411,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) ...@@ -411,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
if (num_gpios > 0) { if (num_gpios > 0) {
int i; int i;
hw->gpios = kzalloc(sizeof(int) * num_gpios, GFP_KERNEL); hw->gpios = kcalloc(num_gpios, sizeof(*hw->gpios), GFP_KERNEL);
if (!hw->gpios) { if (!hw->gpios) {
ret = -ENOMEM; ret = -ENOMEM;
goto free_master; goto free_master;
...@@ -428,8 +428,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) ...@@ -428,8 +428,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
/* Real CS - set the initial state. */ /* Real CS - set the initial state. */
ret = gpio_request(gpio, np->name); ret = gpio_request(gpio, np->name);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "can't request gpio " dev_err(dev,
"#%d: %d\n", i, ret); "can't request gpio #%d: %d\n",
i, ret);
goto free_gpios; goto free_gpios;
} }
......
...@@ -41,6 +41,13 @@ struct pxa_spi_info { ...@@ -41,6 +41,13 @@ struct pxa_spi_info {
static struct dw_dma_slave byt_tx_param = { .dst_id = 0 }; static struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
static struct dw_dma_slave byt_rx_param = { .src_id = 1 }; static struct dw_dma_slave byt_rx_param = { .src_id = 1 };
static struct dw_dma_slave mrfld3_tx_param = { .dst_id = 15 };
static struct dw_dma_slave mrfld3_rx_param = { .src_id = 14 };
static struct dw_dma_slave mrfld5_tx_param = { .dst_id = 13 };
static struct dw_dma_slave mrfld5_rx_param = { .src_id = 12 };
static struct dw_dma_slave mrfld6_tx_param = { .dst_id = 11 };
static struct dw_dma_slave mrfld6_rx_param = { .src_id = 10 };
static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 }; static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 };
static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 }; static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 };
static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 }; static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 };
...@@ -93,22 +100,39 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) ...@@ -93,22 +100,39 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
{ {
struct pci_dev *dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0));
struct dw_dma_slave *tx, *rx;
switch (PCI_FUNC(dev->devfn)) { switch (PCI_FUNC(dev->devfn)) {
case 0: case 0:
c->port_id = 3; c->port_id = 3;
c->num_chipselect = 1; c->num_chipselect = 1;
c->tx_param = &mrfld3_tx_param;
c->rx_param = &mrfld3_rx_param;
break; break;
case 1: case 1:
c->port_id = 5; c->port_id = 5;
c->num_chipselect = 4; c->num_chipselect = 4;
c->tx_param = &mrfld5_tx_param;
c->rx_param = &mrfld5_rx_param;
break; break;
case 2: case 2:
c->port_id = 6; c->port_id = 6;
c->num_chipselect = 1; c->num_chipselect = 1;
c->tx_param = &mrfld6_tx_param;
c->rx_param = &mrfld6_rx_param;
break; break;
default: default:
return -ENODEV; return -ENODEV;
} }
tx = c->tx_param;
tx->dma_dev = &dma_dev->dev;
rx = c->rx_param;
rx->dma_dev = &dma_dev->dev;
c->dma_filter = lpss_dma_filter;
return 0; return 0;
} }
...@@ -203,10 +227,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ...@@ -203,10 +227,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
ssp = &spi_pdata.ssp; ssp = &spi_pdata.ssp;
ssp->phys_base = pci_resource_start(dev, 0); ssp->phys_base = pci_resource_start(dev, 0);
ssp->mmio_base = pcim_iomap_table(dev)[0]; ssp->mmio_base = pcim_iomap_table(dev)[0];
ssp->irq = dev->irq;
ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
ssp->type = c->type; ssp->type = c->type;
pci_set_master(dev);
ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
ssp->irq = pci_irq_vector(dev, 0);
snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id); snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0, ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0,
c->max_clk_rate); c->max_clk_rate);
......
...@@ -732,6 +732,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) ...@@ -732,6 +732,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void handle_bad_msg(struct driver_data *drv_data)
{
pxa2xx_spi_write(drv_data, SSCR0,
pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1);
if (!pxa25x_ssp_comp(drv_data))
pxa2xx_spi_write(drv_data, SSTO, 0);
write_SSSR_CS(drv_data, drv_data->clear_sr);
dev_err(&drv_data->pdev->dev,
"bad message state in interrupt handler\n");
}
static irqreturn_t ssp_int(int irq, void *dev_id) static irqreturn_t ssp_int(int irq, void *dev_id)
{ {
struct driver_data *drv_data = dev_id; struct driver_data *drv_data = dev_id;
...@@ -771,21 +785,11 @@ static irqreturn_t ssp_int(int irq, void *dev_id) ...@@ -771,21 +785,11 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
if (!(status & mask)) if (!(status & mask))
return IRQ_NONE; return IRQ_NONE;
if (!drv_data->master->cur_msg) { pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg & ~drv_data->int_cr1);
pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
pxa2xx_spi_write(drv_data, SSCR0,
pxa2xx_spi_read(drv_data, SSCR0)
& ~SSCR0_SSE);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1)
& ~drv_data->int_cr1);
if (!pxa25x_ssp_comp(drv_data))
pxa2xx_spi_write(drv_data, SSTO, 0);
write_SSSR_CS(drv_data, drv_data->clear_sr);
dev_err(&drv_data->pdev->dev,
"bad message state in interrupt handler\n");
if (!drv_data->master->cur_msg) {
handle_bad_msg(drv_data);
/* Never fail */ /* Never fail */
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -1458,6 +1462,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { ...@@ -1458,6 +1462,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
{ PCI_VDEVICE(INTEL, 0x1ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x1ac2), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x1ac4), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x1ac4), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x1ac6), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x1ac6), LPSS_BXT_SSP },
/* GLK */
{ PCI_VDEVICE(INTEL, 0x31c2), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x31c4), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x31c6), LPSS_BXT_SSP },
/* APL */ /* APL */
{ PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP },
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -843,6 +844,8 @@ static int rockchip_spi_suspend(struct device *dev) ...@@ -843,6 +844,8 @@ static int rockchip_spi_suspend(struct device *dev)
clk_disable_unprepare(rs->apb_pclk); clk_disable_unprepare(rs->apb_pclk);
} }
pinctrl_pm_select_sleep_state(dev);
return ret; return ret;
} }
...@@ -852,6 +855,8 @@ static int rockchip_spi_resume(struct device *dev) ...@@ -852,6 +855,8 @@ static int rockchip_spi_resume(struct device *dev)
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct rockchip_spi *rs = spi_master_get_devdata(master); struct rockchip_spi *rs = spi_master_get_devdata(master);
pinctrl_pm_select_default_state(dev);
if (!pm_runtime_suspended(dev)) { if (!pm_runtime_suspended(dev)) {
ret = clk_prepare_enable(rs->apb_pclk); ret = clk_prepare_enable(rs->apb_pclk);
if (ret < 0) if (ret < 0)
......
...@@ -808,7 +808,7 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) ...@@ -808,7 +808,7 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
rspi_write_data(rspi, *tx++); rspi_write_data(rspi, *tx++);
} else { } else {
ret = rspi_pio_transfer(rspi, tx, NULL, n); ret = rspi_pio_transfer(rspi, tx, NULL, len);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
...@@ -845,10 +845,9 @@ static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) ...@@ -845,10 +845,9 @@ static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
*rx++ = rspi_read_data(rspi); *rx++ = rspi_read_data(rspi);
} else { } else {
ret = rspi_pio_transfer(rspi, NULL, rx, n); ret = rspi_pio_transfer(rspi, NULL, rx, len);
if (ret < 0) if (ret < 0)
return ret; return ret;
*rx++ = ret;
} }
n -= len; n -= len;
} }
...@@ -1227,10 +1226,8 @@ static int rspi_probe(struct platform_device *pdev) ...@@ -1227,10 +1226,8 @@ static int rspi_probe(struct platform_device *pdev)
const struct spi_ops *ops; const struct spi_ops *ops;
master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data)); master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
if (master == NULL) { if (master == NULL)
dev_err(&pdev->dev, "spi_alloc_master error.\n");
return -ENOMEM; return -ENOMEM;
}
of_id = of_match_device(rspi_of_match, &pdev->dev); of_id = of_match_device(rspi_of_match, &pdev->dev);
if (of_id) { if (of_id) {
......
...@@ -341,43 +341,16 @@ static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable) ...@@ -341,43 +341,16 @@ static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable)
static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
{ {
struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
struct device *dev = &sdd->pdev->dev;
if (is_polling(sdd)) if (is_polling(sdd))
return 0; return 0;
/* Acquire DMA channels */
sdd->rx_dma.ch = dma_request_slave_channel(dev, "rx");
if (!sdd->rx_dma.ch) {
dev_err(dev, "Failed to get RX DMA channel\n");
return -EBUSY;
}
spi->dma_rx = sdd->rx_dma.ch; spi->dma_rx = sdd->rx_dma.ch;
sdd->tx_dma.ch = dma_request_slave_channel(dev, "tx");
if (!sdd->tx_dma.ch) {
dev_err(dev, "Failed to get TX DMA channel\n");
dma_release_channel(sdd->rx_dma.ch);
return -EBUSY;
}
spi->dma_tx = sdd->tx_dma.ch; spi->dma_tx = sdd->tx_dma.ch;
return 0; 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)) {
dma_release_channel(sdd->rx_dma.ch);
dma_release_channel(sdd->tx_dma.ch);
}
return 0;
}
static bool s3c64xx_spi_can_dma(struct spi_master *master, static bool s3c64xx_spi_can_dma(struct spi_master *master,
struct spi_device *spi, struct spi_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
...@@ -996,7 +969,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev) ...@@ -996,7 +969,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
sci->num_cs = temp; sci->num_cs = temp;
} }
sci->no_cs = of_property_read_bool(dev->of_node, "broken-cs"); sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback");
return sci; return sci;
} }
...@@ -1094,7 +1067,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) ...@@ -1094,7 +1067,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
master->prepare_message = s3c64xx_spi_prepare_message; master->prepare_message = s3c64xx_spi_prepare_message;
master->transfer_one = s3c64xx_spi_transfer_one; master->transfer_one = s3c64xx_spi_transfer_one;
master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
master->num_chipselect = sci->num_cs; master->num_chipselect = sci->num_cs;
master->dma_alignment = 8; master->dma_alignment = 8;
master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
...@@ -1161,6 +1133,24 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) ...@@ -1161,6 +1133,24 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
} }
} }
if (!is_polling(sdd)) {
/* Acquire DMA channels */
sdd->rx_dma.ch = dma_request_slave_channel_reason(&pdev->dev,
"rx");
if (IS_ERR(sdd->rx_dma.ch)) {
dev_err(&pdev->dev, "Failed to get RX DMA channel\n");
ret = PTR_ERR(sdd->rx_dma.ch);
goto err_disable_io_clk;
}
sdd->tx_dma.ch = dma_request_slave_channel_reason(&pdev->dev,
"tx");
if (IS_ERR(sdd->tx_dma.ch)) {
dev_err(&pdev->dev, "Failed to get TX DMA channel\n");
ret = PTR_ERR(sdd->tx_dma.ch);
goto err_release_rx_dma;
}
}
pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
...@@ -1206,6 +1196,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) ...@@ -1206,6 +1196,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev); pm_runtime_set_suspended(&pdev->dev);
if (!is_polling(sdd))
dma_release_channel(sdd->tx_dma.ch);
err_release_rx_dma:
if (!is_polling(sdd))
dma_release_channel(sdd->rx_dma.ch);
err_disable_io_clk:
clk_disable_unprepare(sdd->ioclk); clk_disable_unprepare(sdd->ioclk);
err_disable_src_clk: err_disable_src_clk:
clk_disable_unprepare(sdd->src_clk); clk_disable_unprepare(sdd->src_clk);
...@@ -1226,6 +1222,11 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) ...@@ -1226,6 +1222,11 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
writel(0, sdd->regs + S3C64XX_SPI_INT_EN); writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
if (!is_polling(sdd)) {
dma_release_channel(sdd->rx_dma.ch);
dma_release_channel(sdd->tx_dma.ch);
}
clk_disable_unprepare(sdd->ioclk); clk_disable_unprepare(sdd->ioclk);
clk_disable_unprepare(sdd->src_clk); clk_disable_unprepare(sdd->src_clk);
......
...@@ -1164,10 +1164,8 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) ...@@ -1164,10 +1164,8 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
int ret; int ret;
master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv)); master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));
if (master == NULL) { if (master == NULL)
dev_err(&pdev->dev, "failed to allocate spi master\n");
return -ENOMEM; return -ENOMEM;
}
p = spi_master_get_devdata(master); p = spi_master_get_devdata(master);
......
...@@ -652,7 +652,8 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -652,7 +652,8 @@ static int ti_qspi_probe(struct platform_device *pdev)
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) { if (r == NULL) {
dev_err(&pdev->dev, "missing platform data\n"); dev_err(&pdev->dev, "missing platform data\n");
return -ENODEV; ret = -ENODEV;
goto free_master;
} }
} }
...@@ -669,7 +670,8 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -669,7 +670,8 @@ static int ti_qspi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n"); dev_err(&pdev->dev, "no irq resource?\n");
return irq; ret = irq;
goto free_master;
} }
mutex_init(&qspi->list_lock); mutex_init(&qspi->list_lock);
...@@ -685,15 +687,17 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -685,15 +687,17 @@ static int ti_qspi_probe(struct platform_device *pdev)
qspi->ctrl_base = qspi->ctrl_base =
syscon_regmap_lookup_by_phandle(np, syscon_regmap_lookup_by_phandle(np,
"syscon-chipselects"); "syscon-chipselects");
if (IS_ERR(qspi->ctrl_base)) if (IS_ERR(qspi->ctrl_base)) {
return PTR_ERR(qspi->ctrl_base); ret = PTR_ERR(qspi->ctrl_base);
goto free_master;
}
ret = of_property_read_u32_index(np, ret = of_property_read_u32_index(np,
"syscon-chipselects", "syscon-chipselects",
1, &qspi->ctrl_reg); 1, &qspi->ctrl_reg);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"couldn't get ctrl_mod reg index\n"); "couldn't get ctrl_mod reg index\n");
return ret; goto free_master;
} }
} }
...@@ -714,9 +718,10 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -714,9 +718,10 @@ static int ti_qspi_probe(struct platform_device *pdev)
dma_cap_set(DMA_MEMCPY, mask); dma_cap_set(DMA_MEMCPY, mask);
qspi->rx_chan = dma_request_chan_by_mask(&mask); qspi->rx_chan = dma_request_chan_by_mask(&mask);
if (!qspi->rx_chan) { if (IS_ERR(qspi->rx_chan)) {
dev_err(qspi->dev, dev_err(qspi->dev,
"No Rx DMA available, trying mmap mode\n"); "No Rx DMA available, trying mmap mode\n");
qspi->rx_chan = NULL;
ret = 0; ret = 0;
goto no_dma; goto no_dma;
} }
...@@ -742,6 +747,7 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -742,6 +747,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
if (!ret) if (!ret)
return 0; return 0;
pm_runtime_disable(&pdev->dev);
free_master: free_master:
spi_master_put(master); spi_master_put(master);
return ret; return ret;
......
...@@ -591,7 +591,6 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw) ...@@ -591,7 +591,6 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw)
if (!data->pkt_rx_buff) { if (!data->pkt_rx_buff) {
/* flush queue and set status of all transfers to -ENOMEM */ /* flush queue and set status of all transfers to -ENOMEM */
dev_err(&data->master->dev, "%s :kzalloc failed\n", __func__);
list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) { list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) {
pmsg->status = -ENOMEM; pmsg->status = -ENOMEM;
...@@ -622,8 +621,9 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw) ...@@ -622,8 +621,9 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw)
if (n_writes > PCH_MAX_FIFO_DEPTH) if (n_writes > PCH_MAX_FIFO_DEPTH)
n_writes = PCH_MAX_FIFO_DEPTH; n_writes = PCH_MAX_FIFO_DEPTH;
dev_dbg(&data->master->dev, "\n%s:Pulling down SSN low - writing " dev_dbg(&data->master->dev,
"0x2 to SSNXCR\n", __func__); "\n%s:Pulling down SSN low - writing 0x2 to SSNXCR\n",
__func__);
pch_spi_writereg(data->master, PCH_SSNXCR, SSN_LOW); pch_spi_writereg(data->master, PCH_SSNXCR, SSN_LOW);
for (j = 0; j < n_writes; j++) for (j = 0; j < n_writes; j++)
...@@ -915,7 +915,6 @@ static void pch_spi_release_dma(struct pch_spi_data *data) ...@@ -915,7 +915,6 @@ static void pch_spi_release_dma(struct pch_spi_data *data)
dma_release_channel(dma->chan_rx); dma_release_channel(dma->chan_rx);
dma->chan_rx = NULL; dma->chan_rx = NULL;
} }
return;
} }
static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
...@@ -1008,7 +1007,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) ...@@ -1008,7 +1007,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
spin_unlock_irqrestore(&data->lock, flags); spin_unlock_irqrestore(&data->lock, flags);
/* RX */ /* RX */
dma->sg_rx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); dma->sg_rx_p = kcalloc(num, sizeof(*dma->sg_rx_p), GFP_ATOMIC);
sg_init_table(dma->sg_rx_p, num); /* Initialize SG table */ sg_init_table(dma->sg_rx_p, num); /* Initialize SG table */
/* offset, length setting */ /* offset, length setting */
sg = dma->sg_rx_p; sg = dma->sg_rx_p;
...@@ -1068,7 +1067,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) ...@@ -1068,7 +1067,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
head = 0; head = 0;
} }
dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); dma->sg_tx_p = kcalloc(num, sizeof(*dma->sg_tx_p), GFP_ATOMIC);
sg_init_table(dma->sg_tx_p, num); /* Initialize SG table */ sg_init_table(dma->sg_tx_p, num); /* Initialize SG table */
/* offset, length setting */ /* offset, length setting */
sg = dma->sg_tx_p; sg = dma->sg_tx_p;
...@@ -1181,14 +1180,16 @@ static void pch_spi_process_messages(struct work_struct *pwork) ...@@ -1181,14 +1180,16 @@ static void pch_spi_process_messages(struct work_struct *pwork)
data->cur_trans = data->cur_trans =
list_entry(data->current_msg->transfers.next, list_entry(data->current_msg->transfers.next,
struct spi_transfer, transfer_list); struct spi_transfer, transfer_list);
dev_dbg(&data->master->dev, "%s " dev_dbg(&data->master->dev,
":Getting 1st transfer message\n", __func__); "%s :Getting 1st transfer message\n",
__func__);
} else { } else {
data->cur_trans = data->cur_trans =
list_entry(data->cur_trans->transfer_list.next, list_entry(data->cur_trans->transfer_list.next,
struct spi_transfer, transfer_list); struct spi_transfer, transfer_list);
dev_dbg(&data->master->dev, "%s " dev_dbg(&data->master->dev,
":Getting next transfer message\n", __func__); "%s :Getting next transfer message\n",
__func__);
} }
spin_unlock(&data->lock); spin_unlock(&data->lock);
...@@ -1233,9 +1234,8 @@ static void pch_spi_process_messages(struct work_struct *pwork) ...@@ -1233,9 +1234,8 @@ static void pch_spi_process_messages(struct work_struct *pwork)
/* check for delay */ /* check for delay */
if (data->cur_trans->delay_usecs) { if (data->cur_trans->delay_usecs) {
dev_dbg(&data->master->dev, "%s:" dev_dbg(&data->master->dev, "%s:delay in usec=%d\n",
"delay in usec=%d\n", __func__, __func__, data->cur_trans->delay_usecs);
data->cur_trans->delay_usecs);
udelay(data->cur_trans->delay_usecs); udelay(data->cur_trans->delay_usecs);
} }
...@@ -1292,7 +1292,6 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat, ...@@ -1292,7 +1292,6 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat,
if (dma->rx_buf_dma) if (dma->rx_buf_dma)
dma_free_coherent(&board_dat->pdev->dev, PCH_BUF_SIZE, dma_free_coherent(&board_dat->pdev->dev, PCH_BUF_SIZE,
dma->rx_buf_virt, dma->rx_buf_dma); dma->rx_buf_virt, dma->rx_buf_dma);
return;
} }
static void pch_alloc_dma_buf(struct pch_spi_board_data *board_dat, static void pch_alloc_dma_buf(struct pch_spi_board_data *board_dat,
...@@ -1541,11 +1540,11 @@ static int pch_spi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1541,11 +1540,11 @@ static int pch_spi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
int i; int i;
struct pch_pd_dev_save *pd_dev_save; struct pch_pd_dev_save *pd_dev_save;
pd_dev_save = kzalloc(sizeof(struct pch_pd_dev_save), GFP_KERNEL); pd_dev_save = kzalloc(sizeof(*pd_dev_save), GFP_KERNEL);
if (!pd_dev_save) if (!pd_dev_save)
return -ENOMEM; return -ENOMEM;
board_dat = kzalloc(sizeof(struct pch_spi_board_data), GFP_KERNEL); board_dat = kzalloc(sizeof(*board_dat), GFP_KERNEL);
if (!board_dat) { if (!board_dat) {
retval = -ENOMEM; retval = -ENOMEM;
goto err_no_mem; goto err_no_mem;
......
...@@ -621,8 +621,10 @@ void spi_unregister_device(struct spi_device *spi) ...@@ -621,8 +621,10 @@ void spi_unregister_device(struct spi_device *spi)
if (!spi) if (!spi)
return; return;
if (spi->dev.of_node) if (spi->dev.of_node) {
of_node_clear_flag(spi->dev.of_node, OF_POPULATED); of_node_clear_flag(spi->dev.of_node, OF_POPULATED);
of_node_put(spi->dev.of_node);
}
if (ACPI_COMPANION(&spi->dev)) if (ACPI_COMPANION(&spi->dev))
acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev));
device_unregister(&spi->dev); device_unregister(&spi->dev);
...@@ -672,7 +674,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) ...@@ -672,7 +674,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
if (!n) if (!n)
return -EINVAL; return -EINVAL;
bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); bi = kcalloc(n, sizeof(*bi), GFP_KERNEL);
if (!bi) if (!bi)
return -ENOMEM; return -ENOMEM;
...@@ -805,12 +807,12 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) ...@@ -805,12 +807,12 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg)
if (master->dma_tx) if (master->dma_tx)
tx_dev = master->dma_tx->device->dev; tx_dev = master->dma_tx->device->dev;
else else
tx_dev = &master->dev; tx_dev = master->dev.parent;
if (master->dma_rx) if (master->dma_rx)
rx_dev = master->dma_rx->device->dev; rx_dev = master->dma_rx->device->dev;
else else
rx_dev = &master->dev; rx_dev = master->dev.parent;
list_for_each_entry(xfer, &msg->transfers, transfer_list) { list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (!master->can_dma(master, msg->spi, xfer)) if (!master->can_dma(master, msg->spi, xfer))
...@@ -852,12 +854,12 @@ static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg) ...@@ -852,12 +854,12 @@ static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
if (master->dma_tx) if (master->dma_tx)
tx_dev = master->dma_tx->device->dev; tx_dev = master->dma_tx->device->dev;
else else
tx_dev = &master->dev; tx_dev = master->dev.parent;
if (master->dma_rx) if (master->dma_rx)
rx_dev = master->dma_rx->device->dev; rx_dev = master->dma_rx->device->dev;
else else
rx_dev = &master->dev; rx_dev = master->dev.parent;
list_for_each_entry(xfer, &msg->transfers, transfer_list) { list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (!master->can_dma(master, msg->spi, xfer)) if (!master->can_dma(master, msg->spi, xfer))
...@@ -1502,37 +1504,18 @@ static int spi_master_initialize_queue(struct spi_master *master) ...@@ -1502,37 +1504,18 @@ static int spi_master_initialize_queue(struct spi_master *master)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#if defined(CONFIG_OF) #if defined(CONFIG_OF)
static struct spi_device * static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi,
of_register_spi_device(struct spi_master *master, struct device_node *nc) struct device_node *nc)
{ {
struct spi_device *spi;
int rc;
u32 value; u32 value;
int rc;
/* Alloc an spi_device */
spi = spi_alloc_device(master);
if (!spi) {
dev_err(&master->dev, "spi_device alloc error for %s\n",
nc->full_name);
rc = -ENOMEM;
goto err_out;
}
/* Select device driver */
rc = of_modalias_node(nc, spi->modalias,
sizeof(spi->modalias));
if (rc < 0) {
dev_err(&master->dev, "cannot find modalias for %s\n",
nc->full_name);
goto err_out;
}
/* Device address */ /* Device address */
rc = of_property_read_u32(nc, "reg", &value); rc = of_property_read_u32(nc, "reg", &value);
if (rc) { if (rc) {
dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n",
nc->full_name, rc); nc->full_name, rc);
goto err_out; return rc;
} }
spi->chip_select = value; spi->chip_select = value;
...@@ -1590,10 +1573,41 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) ...@@ -1590,10 +1573,41 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc)
if (rc) { if (rc) {
dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n",
nc->full_name, rc); nc->full_name, rc);
goto err_out; return rc;
} }
spi->max_speed_hz = value; spi->max_speed_hz = value;
return 0;
}
static struct spi_device *
of_register_spi_device(struct spi_master *master, struct device_node *nc)
{
struct spi_device *spi;
int rc;
/* Alloc an spi_device */
spi = spi_alloc_device(master);
if (!spi) {
dev_err(&master->dev, "spi_device alloc error for %s\n",
nc->full_name);
rc = -ENOMEM;
goto err_out;
}
/* Select device driver */
rc = of_modalias_node(nc, spi->modalias,
sizeof(spi->modalias));
if (rc < 0) {
dev_err(&master->dev, "cannot find modalias for %s\n",
nc->full_name);
goto err_out;
}
rc = of_spi_parse_dt(master, spi, nc);
if (rc)
goto err_out;
/* Store a pointer to the node in the device structure */ /* Store a pointer to the node in the device structure */
of_node_get(nc); of_node_get(nc);
spi->dev.of_node = nc; spi->dev.of_node = nc;
...@@ -1603,11 +1617,13 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) ...@@ -1603,11 +1617,13 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc)
if (rc) { if (rc) {
dev_err(&master->dev, "spi_device register error %s\n", dev_err(&master->dev, "spi_device register error %s\n",
nc->full_name); nc->full_name);
goto err_out; goto err_of_node_put;
} }
return spi; return spi;
err_of_node_put:
of_node_put(nc);
err_out: err_out:
spi_dev_put(spi); spi_dev_put(spi);
return ERR_PTR(rc); return ERR_PTR(rc);
......
...@@ -5,25 +5,14 @@ struct spi_device; ...@@ -5,25 +5,14 @@ struct spi_device;
/** /**
* struct ep93xx_spi_info - EP93xx specific SPI descriptor * struct ep93xx_spi_info - EP93xx specific SPI descriptor
* @num_chipselect: number of chip selects on this board, must be * @chipselect: array of gpio numbers to use as chip selects
* at least one * @num_chipselect: ARRAY_SIZE(chipselect)
* @use_dma: use DMA for the transfers * @use_dma: use DMA for the transfers
*/ */
struct ep93xx_spi_info { struct ep93xx_spi_info {
int *chipselect;
int num_chipselect; int num_chipselect;
bool use_dma; bool use_dma;
}; };
/**
* struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device
* @setup: setup the chip select mechanism
* @cleanup: cleanup the chip select mechanism
* @cs_control: control the device chip select
*/
struct ep93xx_spi_chip_ops {
int (*setup)(struct spi_device *spi);
void (*cleanup)(struct spi_device *spi);
void (*cs_control)(struct spi_device *spi, int value);
};
#endif /* __ASM_MACH_EP93XX_SPI_H */ #endif /* __ASM_MACH_EP93XX_SPI_H */
...@@ -90,9 +90,9 @@ ...@@ -90,9 +90,9 @@
#define SSSR_RFL_MASK (0xf << 12) /* Receive FIFO Level mask */ #define SSSR_RFL_MASK (0xf << 12) /* Receive FIFO Level mask */
#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ #define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */
#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ #define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ #define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
#define RX_THRESH_CE4100_DFLT 2 #define RX_THRESH_CE4100_DFLT 2
#define TX_THRESH_CE4100_DFLT 2 #define TX_THRESH_CE4100_DFLT 2
...@@ -106,9 +106,9 @@ ...@@ -106,9 +106,9 @@
#define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ #define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
/* QUARK_X1000 SSCR0 bit definition */ /* QUARK_X1000 SSCR0 bit definition */
#define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */ #define QUARK_X1000_SSCR0_DSS (0x1F << 0) /* Data Size Select (mask) */
#define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */ #define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */
#define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */ #define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */
#define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */ #define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */
#define RX_THRESH_QUARK_X1000_DFLT 1 #define RX_THRESH_QUARK_X1000_DFLT 1
...@@ -121,8 +121,8 @@ ...@@ -121,8 +121,8 @@
#define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..32] */ #define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..32] */
#define QUARK_X1000_SSCR1_RFT (0x1F << 11) /* Receive FIFO Threshold (mask) */ #define QUARK_X1000_SSCR1_RFT (0x1F << 11) /* Receive FIFO Threshold (mask) */
#define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */ #define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */
#define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */ #define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */
#define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */ #define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ /* extra bits in PXA255, PXA26x and PXA27x SSP ports */
#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment