aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-axi-spi-engine.c17
-rw-r--r--drivers/spi/spi-bcm2835.c27
-rw-r--r--drivers/spi/spi-intel.c34
-rw-r--r--drivers/spi/spi-rockchip.c13
-rw-r--r--drivers/spi/spi.c63
5 files changed, 82 insertions, 72 deletions
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index 9ace259d2d29..6b0c72bf3395 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk.h>
+#include <linux/fpga/adi-axi-common.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -15,12 +16,6 @@
#include <linux/spi/spi.h>
#include <linux/timer.h>
-#define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff)
-#define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff)
-#define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff)
-
-#define SPI_ENGINE_REG_VERSION 0x00
-
#define SPI_ENGINE_REG_RESET 0x40
#define SPI_ENGINE_REG_INT_ENABLE 0x80
@@ -661,12 +656,12 @@ static int spi_engine_probe(struct platform_device *pdev)
if (IS_ERR(spi_engine->base))
return PTR_ERR(spi_engine->base);
- version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION);
- if (SPI_ENGINE_VERSION_MAJOR(version) != 1) {
+ version = readl(spi_engine->base + ADI_AXI_REG_VERSION);
+ if (ADI_AXI_PCORE_VER_MAJOR(version) != 1) {
dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n",
- SPI_ENGINE_VERSION_MAJOR(version),
- SPI_ENGINE_VERSION_MINOR(version),
- SPI_ENGINE_VERSION_PATCH(version));
+ ADI_AXI_PCORE_VER_MAJOR(version),
+ ADI_AXI_PCORE_VER_MINOR(version),
+ ADI_AXI_PCORE_VER_PATCH(version));
return -ENODEV;
}
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index e709887eb2a9..e1b9b1235787 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -1117,19 +1117,6 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
struct spi_device *spi = msg->spi;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *target = spi_get_ctldata(spi);
- int ret;
-
- if (ctlr->can_dma) {
- /*
- * DMA transfers are limited to 16 bit (0 to 65535 bytes) by
- * the SPI HW due to DLEN. Split up transfers (32-bit FIFO
- * aligned) if the limit is exceeded.
- */
- ret = spi_split_transfers_maxsize(ctlr, msg, 65532,
- GFP_KERNEL | GFP_DMA);
- if (ret)
- return ret;
- }
/*
* Set up clock polarity before spi_transfer_one_message() asserts
@@ -1219,6 +1206,19 @@ static int bcm2835_spi_setup_dma(struct spi_controller *ctlr,
return 0;
}
+static size_t bcm2835_spi_max_transfer_size(struct spi_device *spi)
+{
+ /*
+ * DMA transfers are limited to 16 bit (0 to 65535 bytes) by
+ * the SPI HW due to DLEN. Split up transfers (32-bit FIFO
+ * aligned) if the limit is exceeded.
+ */
+ if (spi->controller->can_dma)
+ return 65532;
+
+ return SIZE_MAX;
+}
+
static int bcm2835_spi_setup(struct spi_device *spi)
{
struct spi_controller *ctlr = spi->controller;
@@ -1348,6 +1348,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
ctlr->mode_bits = BCM2835_SPI_MODE_BITS;
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
ctlr->num_chipselect = 3;
+ ctlr->max_transfer_size = bcm2835_spi_max_transfer_size;
ctlr->setup = bcm2835_spi_setup;
ctlr->cleanup = bcm2835_spi_cleanup;
ctlr->transfer_one = bcm2835_spi_transfer_one;
diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
index 3654ae35d2db..3e5dcf2b3c8a 100644
--- a/drivers/spi/spi-intel.c
+++ b/drivers/spi/spi-intel.c
@@ -1254,6 +1254,13 @@ static void intel_spi_fill_partition(struct intel_spi *ispi,
if (end > part->size)
part->size = end;
}
+
+ /*
+ * Regions can refer to the second chip too so in this case we
+ * just make the BIOS partition to occupy the whole chip.
+ */
+ if (ispi->chip0_size && part->size > ispi->chip0_size)
+ part->size = MTDPART_SIZ_FULL;
}
static int intel_spi_read_desc(struct intel_spi *ispi)
@@ -1346,9 +1353,14 @@ static int intel_spi_read_desc(struct intel_spi *ispi)
static int intel_spi_populate_chip(struct intel_spi *ispi)
{
struct flash_platform_data *pdata;
+ struct mtd_partition *parts;
struct spi_board_info chip;
int ret;
+ ret = intel_spi_read_desc(ispi);
+ if (ret)
+ return ret;
+
pdata = devm_kzalloc(ispi->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
@@ -1368,15 +1380,27 @@ static int intel_spi_populate_chip(struct intel_spi *ispi)
if (!spi_new_device(ispi->host, &chip))
return -ENODEV;
- ret = intel_spi_read_desc(ispi);
- if (ret)
- return ret;
-
/* Add the second chip if present */
if (ispi->host->num_chipselect < 2)
return 0;
- chip.platform_data = NULL;
+ pdata = devm_kzalloc(ispi->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->name = devm_kasprintf(ispi->dev, GFP_KERNEL, "%s-chip1",
+ dev_name(ispi->dev));
+ pdata->nr_parts = 1;
+ parts = devm_kcalloc(ispi->dev, pdata->nr_parts, sizeof(*parts),
+ GFP_KERNEL);
+ if (!parts)
+ return -ENOMEM;
+
+ parts[0].size = MTDPART_SIZ_FULL;
+ parts[0].name = "BIOS1";
+ pdata->parts = parts;
+
+ chip.platform_data = pdata;
chip.chip_select = 1;
if (!spi_new_device(ispi->host, &chip))
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 4b9669da2cf3..e1ecd96c7858 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -160,8 +160,7 @@
*/
#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff
-/* 2 for native cs, 2 for cs-gpio */
-#define ROCKCHIP_SPI_MAX_CS_NUM 4
+#define ROCKCHIP_SPI_MAX_NATIVE_CS_NUM 2
#define ROCKCHIP_SPI_VER2_TYPE1 0x05EC0002
#define ROCKCHIP_SPI_VER2_TYPE2 0x00110002
@@ -192,8 +191,6 @@ struct rockchip_spi {
u8 n_bytes;
u8 rsd;
- bool cs_asserted[ROCKCHIP_SPI_MAX_CS_NUM];
-
bool target_abort;
bool cs_inactive; /* spi target tansmition stop when cs inactive */
bool cs_high_supported; /* native CS supports active-high polarity */
@@ -245,10 +242,6 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
bool cs_asserted = spi->mode & SPI_CS_HIGH ? enable : !enable;
- /* Return immediately for no-op */
- if (cs_asserted == rs->cs_asserted[spi_get_chipselect(spi, 0)])
- return;
-
if (cs_asserted) {
/* Keep things powered as long as CS is asserted */
pm_runtime_get_sync(rs->dev);
@@ -268,8 +261,6 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
/* Drop reference from when we first asserted CS */
pm_runtime_put(rs->dev);
}
-
- rs->cs_asserted[spi_get_chipselect(spi, 0)] = cs_asserted;
}
static void rockchip_spi_handle_err(struct spi_controller *ctlr,
@@ -847,7 +838,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
ctlr->target_abort = rockchip_spi_target_abort;
} else {
ctlr->flags = SPI_CONTROLLER_GPIO_SS;
- ctlr->max_native_cs = ROCKCHIP_SPI_MAX_CS_NUM;
+ ctlr->max_native_cs = ROCKCHIP_SPI_MAX_NATIVE_CS_NUM;
/*
* rk spi0 has two native cs, spi1..5 one cs only
* if num-cs is missing in the dts, default to 1
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6610aeced765..517558e01559 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1743,13 +1743,37 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
trace_spi_message_start(msg);
- ret = spi_split_transfers_maxsize(ctlr, msg,
- spi_max_transfer_size(msg->spi),
- GFP_KERNEL | GFP_DMA);
- if (ret) {
- msg->status = ret;
- spi_finalize_current_message(ctlr);
- return ret;
+ /*
+ * If an SPI controller does not support toggling the CS line on each
+ * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
+ * for the CS line, we can emulate the CS-per-word hardware function by
+ * splitting transfers into one-word transfers and ensuring that
+ * cs_change is set for each transfer.
+ */
+ if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
+ spi_is_csgpiod(msg->spi))) {
+ ret = spi_split_transfers_maxwords(ctlr, msg, 1, GFP_KERNEL);
+ if (ret) {
+ msg->status = ret;
+ spi_finalize_current_message(ctlr);
+ return ret;
+ }
+
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+ /* Don't change cs_change on the last entry in the list */
+ if (list_is_last(&xfer->transfer_list, &msg->transfers))
+ break;
+ xfer->cs_change = 1;
+ }
+ } else {
+ ret = spi_split_transfers_maxsize(ctlr, msg,
+ spi_max_transfer_size(msg->spi),
+ GFP_KERNEL | GFP_DMA);
+ if (ret) {
+ msg->status = ret;
+ spi_finalize_current_message(ctlr);
+ return ret;
+ }
}
if (ctlr->prepare_message) {
@@ -4062,31 +4086,6 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
message->spi = spi;
/*
- * If an SPI controller does not support toggling the CS line on each
- * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
- * for the CS line, we can emulate the CS-per-word hardware function by
- * splitting transfers into one-word transfers and ensuring that
- * cs_change is set for each transfer.
- */
- if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
- spi_is_csgpiod(spi))) {
- size_t maxsize = BITS_TO_BYTES(spi->bits_per_word);
- int ret;
-
- ret = spi_split_transfers_maxsize(ctlr, message, maxsize,
- GFP_KERNEL);
- if (ret)
- return ret;
-
- list_for_each_entry(xfer, &message->transfers, transfer_list) {
- /* Don't change cs_change on the last entry in the list */
- if (list_is_last(&xfer->transfer_list, &message->transfers))
- break;
- xfer->cs_change = 1;
- }
- }
-
- /*
* Half-duplex links include original MicroWire, and ones with
* only one data pin like SPI_3WIRE (switches direction) or where
* either MOSI or MISO is missing. They can also be caused by