summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpi_apd.c6
-rw-r--r--drivers/media/usb/msi2500/msi2500.c9
-rw-r--r--drivers/mtd/nand/spi/core.c76
-rw-r--r--drivers/mtd/spi-nor/core.c22
-rw-r--r--drivers/spi/Kconfig9
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi-airoha-snfi.c6
-rw-r--r--drivers/spi/spi-altera-platform.c31
-rw-r--r--drivers/spi/spi-amlogic-spifc-a1.c5
-rw-r--r--drivers/spi/spi-amlogic-spisg.c16
-rw-r--r--drivers/spi/spi-armada-3700.c44
-rw-r--r--drivers/spi/spi-aspeed-smc.c15
-rw-r--r--drivers/spi/spi-at91-usart.c63
-rw-r--r--drivers/spi/spi-atcspi200.c28
-rw-r--r--drivers/spi/spi-atmel.c167
-rw-r--r--drivers/spi/spi-bcm63xx-hsspi.c17
-rw-r--r--drivers/spi/spi-bcm63xx.c26
-rw-r--r--drivers/spi/spi-bitbang.c11
-rw-r--r--drivers/spi/spi-cadence-quadspi.c52
-rw-r--r--drivers/spi/spi-cadence-xspi.c56
-rw-r--r--drivers/spi/spi-cadence.c40
-rw-r--r--drivers/spi/spi-cavium-octeon.c17
-rw-r--r--drivers/spi/spi-cavium-thunderx.c32
-rw-r--r--drivers/spi/spi-clps711x.c31
-rw-r--r--drivers/spi/spi-coldfire-qspi.c28
-rw-r--r--drivers/spi/spi-cs42l43.c4
-rw-r--r--drivers/spi/spi-dln2.c26
-rw-r--r--drivers/spi/spi-dw-core.c2
-rw-r--r--drivers/spi/spi-dw-mmio.c7
-rw-r--r--drivers/spi/spi-dw-pci.c26
-rw-r--r--drivers/spi/spi-ep93xx.c23
-rw-r--r--drivers/spi/spi-falcon.c8
-rw-r--r--drivers/spi/spi-fsi.c8
-rw-r--r--drivers/spi/spi-fsl-dspi.c2
-rw-r--r--drivers/spi/spi-fsl-espi.c22
-rw-r--r--drivers/spi/spi-fsl-lpspi.c18
-rw-r--r--drivers/spi/spi-fsl-spi.c14
-rw-r--r--drivers/spi/spi-geni-qcom.c13
-rw-r--r--drivers/spi/spi-hisi-kunpeng.c12
-rw-r--r--drivers/spi/spi-hisi-sfc-v3xx.c20
-rw-r--r--drivers/spi/spi-img-spfi.c40
-rw-r--r--drivers/spi/spi-imx.c16
-rw-r--r--drivers/spi/spi-intel-pci.c66
-rw-r--r--drivers/spi/spi-intel.c6
-rw-r--r--drivers/spi/spi-jcore.c23
-rw-r--r--drivers/spi/spi-lantiq-ssc.c28
-rw-r--r--drivers/spi/spi-lp8841-rtc.c16
-rw-r--r--drivers/spi/spi-mem.c32
-rw-r--r--drivers/spi/spi-meson-spicc.c48
-rw-r--r--drivers/spi/spi-meson-spifc.c23
-rw-r--r--drivers/spi/spi-microchip-core-qspi.c3
-rw-r--r--drivers/spi/spi-mpc52xx.c28
-rw-r--r--drivers/spi/spi-mux.c19
-rw-r--r--drivers/spi/spi-mxic.c18
-rw-r--r--drivers/spi/spi-mxs.c14
-rw-r--r--drivers/spi/spi-npcm-fiu.c16
-rw-r--r--drivers/spi/spi-npcm-pspi.c19
-rw-r--r--drivers/spi/spi-nxp-xspi.c12
-rw-r--r--drivers/spi/spi-omap2-mcspi.c49
-rw-r--r--drivers/spi/spi-orion.c26
-rw-r--r--drivers/spi/spi-pci1xxxx.c42
-rw-r--r--drivers/spi/spi-pic32-sqi.c28
-rw-r--r--drivers/spi/spi-pic32.c11
-rw-r--r--drivers/spi/spi-pl022.c11
-rw-r--r--drivers/spi/spi-qcom-qspi.c80
-rw-r--r--drivers/spi/spi-qup.c15
-rw-r--r--drivers/spi/spi-rpc-if.c8
-rw-r--r--drivers/spi/spi-rspi.c44
-rw-r--r--drivers/spi/spi-rzv2h-rspi.c18
-rw-r--r--drivers/spi/spi-s3c64xx.c6
-rw-r--r--drivers/spi/spi-sc18is602.c6
-rw-r--r--drivers/spi/spi-sh-hspi.c11
-rw-r--r--drivers/spi/spi-sh-msiof.c32
-rw-r--r--drivers/spi/spi-sifive.c39
-rw-r--r--drivers/spi/spi-slave-mt27xx.c33
-rw-r--r--drivers/spi/spi-sn-f-ospi.c5
-rw-r--r--drivers/spi/spi-spacemit-k1.c789
-rw-r--r--drivers/spi/spi-sprd.c20
-rw-r--r--drivers/spi/spi-st-ssc4.c14
-rw-r--r--drivers/spi/spi-stm32-ospi.c13
-rw-r--r--drivers/spi/spi-stm32-qspi.c11
-rw-r--r--drivers/spi/spi-sun4i.c35
-rw-r--r--drivers/spi/spi-sun6i.c38
-rw-r--r--drivers/spi/spi-sunplus-sp7021.c3
-rw-r--r--drivers/spi/spi-synquacer.c24
-rw-r--r--drivers/spi/spi-tegra114.c34
-rw-r--r--drivers/spi/spi-tegra20-sflash.c24
-rw-r--r--drivers/spi/spi-tegra210-quad.c29
-rw-r--r--drivers/spi/spi-ti-qspi.c37
-rw-r--r--drivers/spi/spi-topcliff-pch.c10
-rw-r--r--drivers/spi/spi-uniphier.c46
-rw-r--r--drivers/spi/spi-wpcm-fiu.c2
-rw-r--r--drivers/spi/spi-xcomm.c4
-rw-r--r--drivers/spi/spi-xilinx.c19
-rw-r--r--drivers/spi/spi-xlp.c3
-rw-r--r--drivers/spi/spi-xtensa-xtfpga.c1
-rw-r--r--drivers/spi/spi-zynq-qspi.c40
-rw-r--r--drivers/spi/spi.c41
-rw-r--r--drivers/staging/greybus/spilib.c8
99 files changed, 1770 insertions, 1379 deletions
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 86678ee22a04..008bd0552cb7 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -182,6 +182,11 @@ static const struct apd_device_desc hip08_spi_desc = {
.fixed_clk_rate = 250000000,
};
+static const struct apd_device_desc leca_spi_desc = {
+ .setup = acpi_apd_setup,
+ .fixed_clk_rate = 400000000,
+};
+
static const struct apd_device_desc leca_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 250000000,
@@ -257,6 +262,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "HISI02A2", APD_ADDR(hip08_i2c_desc) },
{ "HISI02A3", APD_ADDR(hip08_lite_i2c_desc) },
{ "HISI0173", APD_ADDR(hip08_spi_desc) },
+ { "LECA0002", APD_ADDR(leca_spi_desc) },
{ "LECA0003", APD_ADDR(leca_i2c_desc) },
{ "NXP0001", APD_ADDR(nxp_i2c_desc) },
#endif
diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c
index 1ff98956b680..5c512d61dc1b 100644
--- a/drivers/media/usb/msi2500/msi2500.c
+++ b/drivers/media/usb/msi2500/msi2500.c
@@ -575,6 +575,7 @@ static void msi2500_disconnect(struct usb_interface *intf)
v4l2_device_disconnect(&dev->v4l2_dev);
video_unregister_device(&dev->vdev);
spi_unregister_controller(dev->ctlr);
+ spi_controller_put(dev->ctlr);
mutex_unlock(&dev->v4l2_lock);
mutex_unlock(&dev->vb_queue_lock);
@@ -1230,10 +1231,8 @@ static int msi2500_probe(struct usb_interface *intf,
ctlr->transfer_one_message = msi2500_transfer_one_message;
spi_controller_set_devdata(ctlr, dev);
ret = spi_register_controller(ctlr);
- if (ret) {
- spi_controller_put(ctlr);
- goto err_unregister_v4l2_dev;
- }
+ if (ret)
+ goto err_put_controller;
/* load v4l2 subdevice */
sd = v4l2_spi_new_subdev(&dev->v4l2_dev, ctlr, &board_info);
@@ -1276,6 +1275,8 @@ err_free_controls:
v4l2_ctrl_handler_free(&dev->hdl);
err_unregister_controller:
spi_unregister_controller(dev->ctlr);
+err_put_controller:
+ spi_controller_put(dev->ctlr);
err_unregister_v4l2_dev:
v4l2_device_unregister(&dev->v4l2_dev);
err_free_mem:
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 0b076790bd9d..786e3fb4874d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -501,10 +501,13 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
}
}
- if (req->mode == MTD_OPS_RAW)
- rdesc = spinand->dirmaps[req->pos.plane].rdesc;
+ rdesc = spinand->dirmaps[req->pos.plane].rdesc;
+
+ if (nand->ecc.engine->integration == NAND_ECC_ENGINE_INTEGRATION_PIPELINED &&
+ req->mode != MTD_OPS_RAW)
+ rdesc->info.op_tmpl->data.ecc = true;
else
- rdesc = spinand->dirmaps[req->pos.plane].rdesc_ecc;
+ rdesc->info.op_tmpl->data.ecc = false;
if (spinand->flags & SPINAND_HAS_READ_PLANE_SELECT_BIT)
column |= req->pos.plane << fls(nanddev_page_size(nand));
@@ -593,10 +596,13 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand,
req->ooblen);
}
- if (req->mode == MTD_OPS_RAW)
- wdesc = spinand->dirmaps[req->pos.plane].wdesc;
+ wdesc = spinand->dirmaps[req->pos.plane].wdesc;
+
+ if (nand->ecc.engine->integration == NAND_ECC_ENGINE_INTEGRATION_PIPELINED &&
+ req->mode != MTD_OPS_RAW)
+ wdesc->info.op_tmpl->data.ecc = true;
else
- wdesc = spinand->dirmaps[req->pos.plane].wdesc_ecc;
+ wdesc->info.op_tmpl->data.ecc = false;
if (spinand->flags & SPINAND_HAS_PROG_PLANE_SELECT_BIT)
column |= req->pos.plane << fls(nanddev_page_size(nand));
@@ -892,6 +898,12 @@ static int spinand_mtd_continuous_page_read(struct mtd_info *mtd, loff_t from,
* Each data read must be a multiple of 4-bytes and full pages should be read;
* otherwise, the data output might get out of sequence from one read command
* to another.
+ *
+ * Continuous reads never cross LUN boundaries. Some devices don't
+ * support crossing planes boundaries. Some devices don't even support
+ * crossing blocks boundaries. The common case being to read through UBI,
+ * we will very rarely read two consequent blocks or more, so let's only enable
+ * continuous reads when reading within the same erase block.
*/
nanddev_io_for_each_block(nand, NAND_PAGE_READ, from, ops, &iter) {
ret = spinand_select_target(spinand, iter.req.pos.target);
@@ -982,19 +994,6 @@ static bool spinand_use_cont_read(struct mtd_info *mtd, loff_t from,
nanddev_offs_to_pos(nand, from, &start_pos);
nanddev_offs_to_pos(nand, from + ops->len - 1, &end_pos);
- /*
- * Continuous reads never cross LUN boundaries. Some devices don't
- * support crossing planes boundaries. Some devices don't even support
- * crossing blocks boundaries. The common case being to read through UBI,
- * we will very rarely read two consequent blocks or more, so it is safer
- * and easier (can be improved) to only enable continuous reads when
- * reading within the same erase block.
- */
- if (start_pos.target != end_pos.target ||
- start_pos.plane != end_pos.plane ||
- start_pos.eraseblock != end_pos.eraseblock)
- return false;
-
return start_pos.page < end_pos.page;
}
@@ -1252,12 +1251,18 @@ static int spinand_create_dirmap(struct spinand_device *spinand,
struct nand_device *nand = spinand_to_nand(spinand);
struct spi_mem_dirmap_info info = { 0 };
struct spi_mem_dirmap_desc *desc;
+ bool enable_ecc = false;
+
+ if (nand->ecc.engine->integration == NAND_ECC_ENGINE_INTEGRATION_PIPELINED)
+ enable_ecc = true;
/* The plane number is passed in MSB just above the column address */
info.offset = plane << fls(nand->memorg.pagesize);
+ /* Write descriptor */
info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
- info.op_tmpl = *spinand->op_templates->update_cache;
+ info.primary_op_tmpl = *spinand->op_templates->update_cache;
+ info.primary_op_tmpl.data.ecc = enable_ecc;
desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
spinand->spimem, &info);
if (IS_ERR(desc))
@@ -1265,38 +1270,15 @@ static int spinand_create_dirmap(struct spinand_device *spinand,
spinand->dirmaps[plane].wdesc = desc;
- info.op_tmpl = *spinand->op_templates->read_cache;
+ /* Read descriptor */
+ info.primary_op_tmpl = *spinand->op_templates->read_cache;
+ info.primary_op_tmpl.data.ecc = enable_ecc;
desc = spinand_create_rdesc(spinand, &info);
if (IS_ERR(desc))
return PTR_ERR(desc);
spinand->dirmaps[plane].rdesc = desc;
- if (nand->ecc.engine->integration != NAND_ECC_ENGINE_INTEGRATION_PIPELINED) {
- spinand->dirmaps[plane].wdesc_ecc = spinand->dirmaps[plane].wdesc;
- spinand->dirmaps[plane].rdesc_ecc = spinand->dirmaps[plane].rdesc;
-
- return 0;
- }
-
- info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
- info.op_tmpl = *spinand->op_templates->update_cache;
- info.op_tmpl.data.ecc = true;
- desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
- spinand->spimem, &info);
- if (IS_ERR(desc))
- return PTR_ERR(desc);
-
- spinand->dirmaps[plane].wdesc_ecc = desc;
-
- info.op_tmpl = *spinand->op_templates->read_cache;
- info.op_tmpl.data.ecc = true;
- desc = spinand_create_rdesc(spinand, &info);
- if (IS_ERR(desc))
- return PTR_ERR(desc);
-
- spinand->dirmaps[plane].rdesc_ecc = desc;
-
return 0;
}
@@ -1421,7 +1403,7 @@ static void spinand_manufacturer_cleanup(struct spinand_device *spinand)
return spinand->manufacturer->ops->cleanup(spinand);
}
-static bool spinand_op_is_odtr(const struct spi_mem_op *op)
+bool spinand_op_is_odtr(const struct spi_mem_op *op)
{
return op->cmd.dtr && op->cmd.buswidth == 8;
}
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 5dd0b3cb5250..a7bc458edc5c 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3641,14 +3641,15 @@ EXPORT_SYMBOL_GPL(spi_nor_scan);
static int spi_nor_create_read_dirmap(struct spi_nor *nor)
{
struct spi_mem_dirmap_info info = {
- .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
- SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),
- SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
- SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+ .op_tmpl = &info.primary_op_tmpl,
+ .primary_op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(0, NULL, 0)),
.offset = 0,
.length = nor->params->size,
};
- struct spi_mem_op *op = &info.op_tmpl;
+ struct spi_mem_op *op = info.op_tmpl;
spi_nor_spimem_setup_op(nor, op, nor->read_proto);
@@ -3672,14 +3673,15 @@ static int spi_nor_create_read_dirmap(struct spi_nor *nor)
static int spi_nor_create_write_dirmap(struct spi_nor *nor)
{
struct spi_mem_dirmap_info info = {
- .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
- SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),
- SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
+ .op_tmpl = &info.primary_op_tmpl,
+ .primary_op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
.offset = 0,
.length = nor->params->size,
};
- struct spi_mem_op *op = &info.op_tmpl;
+ struct spi_mem_op *op = info.op_tmpl;
if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
op->addr.nbytes = 0;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b563f49e2197..8782514bb89b 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -1085,6 +1085,15 @@ config SPI_SG2044_NOR
also supporting 3Byte address devices and 4Byte address
devices.
+config SPI_SPACEMIT_K1
+ tristate "K1 SPI Controller"
+ depends on ARCH_SPACEMIT || COMPILE_TEST
+ depends on OF
+ imply MMP_PDMA if ARCH_SPACEMIT
+ default m if ARCH_SPACEMIT
+ help
+ Enable support for the SpacemiT K1 SPI controller.
+
config SPI_SPRD
tristate "Spreadtrum SPI controller"
depends on ARCH_SPRD || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 9d36190a9884..9fa12498ce8c 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -143,6 +143,7 @@ obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o
obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o
obj-$(CONFIG_SPI_SN_F_OSPI) += spi-sn-f-ospi.o
obj-$(CONFIG_SPI_SG2044_NOR) += spi-sg2044-nor.o
+obj-$(CONFIG_SPI_SPACEMIT_K1) += spi-spacemit-k1.o
obj-$(CONFIG_SPI_SPRD) += spi-sprd.o
obj-$(CONFIG_SPI_SPRD_ADI) += spi-sprd-adi.o
obj-$(CONFIG_SPI_STM32) += spi-stm32.o
diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
index 7b6c09f91fef..95bfde7c8e7f 100644
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -546,7 +546,7 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
if (desc->info.length > SPI_NAND_CACHE_SIZE)
return -E2BIG;
- if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl))
+ if (!airoha_snand_supports_op(desc->mem, desc->info.op_tmpl))
return -EOPNOTSUPP;
return 0;
@@ -572,7 +572,7 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
* DUALIO and QUADIO opcodes are not supported by the spi controller,
* replace them with supported opcodes.
*/
- opcode = desc->info.op_tmpl.cmd.opcode;
+ opcode = desc->info.op_tmpl->cmd.opcode;
switch (opcode) {
case SPI_NAND_OP_READ_FROM_CACHE_SINGLE:
case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST:
@@ -761,7 +761,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
/* minimum oob size is 64 */
bytes = round_up(offs + len, 64);
- opcode = desc->info.op_tmpl.cmd.opcode;
+ opcode = desc->info.op_tmpl->cmd.opcode;
switch (opcode) {
case SPI_NAND_OP_PROGRAM_LOAD_SINGLE:
case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE:
diff --git a/drivers/spi/spi-altera-platform.c b/drivers/spi/spi-altera-platform.c
index fc81de2610ef..3de7df73f216 100644
--- a/drivers/spi/spi-altera-platform.c
+++ b/drivers/spi/spi-altera-platform.c
@@ -39,12 +39,12 @@ static int altera_spi_probe(struct platform_device *pdev)
enum altera_spi_type type = ALTERA_SPI_TYPE_UNKNOWN;
struct altera_spi *hw;
struct spi_controller *host;
- int err = -ENODEV;
+ int err;
u16 i;
- host = spi_alloc_host(&pdev->dev, sizeof(struct altera_spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct altera_spi));
if (!host)
- return err;
+ return -ENOMEM;
/* setup the host state. */
host->bus_num = -1;
@@ -54,8 +54,7 @@ static int altera_spi_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"Invalid number of chipselect: %u\n",
pdata->num_chipselect);
- err = -EINVAL;
- goto exit;
+ return -EINVAL;
}
host->num_chipselect = pdata->num_chipselect;
@@ -80,7 +79,7 @@ static int altera_spi_probe(struct platform_device *pdev)
hw->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!hw->regmap) {
dev_err(&pdev->dev, "get regmap failed\n");
- goto exit;
+ return -ENODEV;
}
regoff = platform_get_resource(pdev, IORESOURCE_REG, 0);
@@ -90,17 +89,14 @@ static int altera_spi_probe(struct platform_device *pdev)
void __iomem *res;
res = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(res)) {
- err = PTR_ERR(res);
- goto exit;
- }
+ if (IS_ERR(res))
+ return PTR_ERR(res);
hw->regmap = devm_regmap_init_mmio(&pdev->dev, res,
&spi_altera_config);
if (IS_ERR(hw->regmap)) {
dev_err(&pdev->dev, "regmap mmio init failed\n");
- err = PTR_ERR(hw->regmap);
- goto exit;
+ return PTR_ERR(hw->regmap);
}
}
@@ -112,12 +108,12 @@ static int altera_spi_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
pdev->name, host);
if (err)
- goto exit;
+ return err;
}
err = devm_spi_register_controller(&pdev->dev, host);
if (err)
- goto exit;
+ return err;
if (pdata) {
for (i = 0; i < pdata->num_devices; i++) {
@@ -131,9 +127,6 @@ static int altera_spi_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "regoff %u, irq %d\n", hw->regoff, hw->irq);
return 0;
-exit:
- spi_controller_put(host);
- return err;
}
#ifdef CONFIG_OF
@@ -146,8 +139,8 @@ MODULE_DEVICE_TABLE(of, altera_spi_match);
#endif /* CONFIG_OF */
static const struct platform_device_id altera_spi_ids[] = {
- { DRV_NAME, ALTERA_SPI_TYPE_UNKNOWN },
- { "subdev_spi_altera", ALTERA_SPI_TYPE_SUBDEV },
+ { .name = DRV_NAME, .driver_data = ALTERA_SPI_TYPE_UNKNOWN },
+ { .name = "subdev_spi_altera", .driver_data = ALTERA_SPI_TYPE_SUBDEV },
{ }
};
MODULE_DEVICE_TABLE(platform, altera_spi_ids);
diff --git a/drivers/spi/spi-amlogic-spifc-a1.c b/drivers/spi/spi-amlogic-spifc-a1.c
index 7ee4c92e6e09..77a2c11bec5e 100644
--- a/drivers/spi/spi-amlogic-spifc-a1.c
+++ b/drivers/spi/spi-amlogic-spifc-a1.c
@@ -206,10 +206,9 @@ static int amlogic_spifc_a1_read(struct amlogic_spifc_a1 *spifc, void *buf,
u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL3_REG);
int ret;
- val &= ~(SPIFC_A1_USER_DIN_MODE | SPIFC_A1_USER_DIN_BYTES);
val |= SPIFC_A1_USER_DIN_ENABLE;
- val |= FIELD_PREP(SPIFC_A1_USER_DIN_MODE, mode);
- val |= FIELD_PREP(SPIFC_A1_USER_DIN_BYTES, size);
+ FIELD_MODIFY(SPIFC_A1_USER_DIN_MODE, &val, mode);
+ FIELD_MODIFY(SPIFC_A1_USER_DIN_BYTES, &val, size);
writel(val, spifc->base + SPIFC_A1_USER_CTRL3_REG);
ret = amlogic_spifc_a1_request(spifc, true);
diff --git a/drivers/spi/spi-amlogic-spisg.c b/drivers/spi/spi-amlogic-spisg.c
index f9de2d2c9213..afc8af04638d 100644
--- a/drivers/spi/spi-amlogic-spisg.c
+++ b/drivers/spi/spi-amlogic-spisg.c
@@ -258,8 +258,7 @@ static int aml_spisg_setup_transfer(struct spisg_device *spisg,
int ret;
memset(desc, 0, sizeof(*desc));
- if (exdesc)
- memset(exdesc, 0, sizeof(*exdesc));
+ memset(exdesc, 0, sizeof(*exdesc));
aml_spisg_set_speed(spisg, xfer->speed_hz);
xfer->effective_speed_hz = spisg->effective_speed_hz;
@@ -601,14 +600,11 @@ static int aml_spisg_prepare_message(struct spi_controller *ctlr,
spisg->bytes_per_word = spi->bits_per_word >> 3;
- spisg->cfg_spi &= ~CFG_SLAVE_SELECT;
- spisg->cfg_spi |= FIELD_PREP(CFG_SLAVE_SELECT, spi_get_chipselect(spi, 0));
-
- spisg->cfg_bus &= ~(CFG_CPOL | CFG_CPHA | CFG_B_L_ENDIAN | CFG_HALF_DUPLEX);
- spisg->cfg_bus |= FIELD_PREP(CFG_CPOL, !!(spi->mode & SPI_CPOL)) |
- FIELD_PREP(CFG_CPHA, !!(spi->mode & SPI_CPHA)) |
- FIELD_PREP(CFG_B_L_ENDIAN, !!(spi->mode & SPI_LSB_FIRST)) |
- FIELD_PREP(CFG_HALF_DUPLEX, !!(spi->mode & SPI_3WIRE));
+ FIELD_MODIFY(CFG_SLAVE_SELECT, &spisg->cfg_spi, spi_get_chipselect(spi, 0));
+ FIELD_MODIFY(CFG_CPOL, &spisg->cfg_bus, !!(spi->mode & SPI_CPOL));
+ FIELD_MODIFY(CFG_CPHA, &spisg->cfg_bus, !!(spi->mode & SPI_CPHA));
+ FIELD_MODIFY(CFG_B_L_ENDIAN, &spisg->cfg_bus, !!(spi->mode & SPI_LSB_FIRST));
+ FIELD_MODIFY(CFG_HALF_DUPLEX, &spisg->cfg_bus, !!(spi->mode & SPI_3WIRE));
return 0;
}
diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c
index 78248729d3e9..ca2faa265ca0 100644
--- a/drivers/spi/spi-armada-3700.c
+++ b/drivers/spi/spi-armada-3700.c
@@ -818,17 +818,13 @@ static int a3700_spi_probe(struct platform_device *pdev)
u32 num_cs = 0;
int irq, ret = 0;
- host = spi_alloc_host(dev, sizeof(*spi));
- if (!host) {
- dev_err(dev, "host allocation failed\n");
- ret = -ENOMEM;
- goto out;
- }
+ host = devm_spi_alloc_host(dev, sizeof(*spi));
+ if (!host)
+ return -ENOMEM;
if (of_property_read_u32(dev->of_node, "num-cs", &num_cs)) {
dev_err(dev, "could not find num-cs\n");
- ret = -ENXIO;
- goto error;
+ return -ENXIO;
}
host->bus_num = pdev->id;
@@ -849,25 +845,20 @@ static int a3700_spi_probe(struct platform_device *pdev)
spi->host = host;
spi->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(spi->base)) {
- ret = PTR_ERR(spi->base);
- goto error;
- }
+ if (IS_ERR(spi->base))
+ return PTR_ERR(spi->base);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = -ENXIO;
- goto error;
- }
+ if (irq < 0)
+ return -ENXIO;
+
spi->irq = irq;
init_completion(&spi->done);
spi->clk = devm_clk_get_prepared(dev, NULL);
- if (IS_ERR(spi->clk)) {
- dev_err(dev, "could not find clk: %ld\n", PTR_ERR(spi->clk));
- goto error;
- }
+ if (IS_ERR(spi->clk))
+ return dev_err_probe(dev, PTR_ERR(spi->clk), "could not find clk\n");
host->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ,
clk_get_rate(spi->clk));
@@ -878,23 +869,16 @@ static int a3700_spi_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0,
dev_name(dev), host);
- if (ret) {
- dev_err(dev, "could not request IRQ: %d\n", ret);
- goto error;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "could not request IRQ\n");
ret = devm_spi_register_controller(dev, host);
if (ret) {
dev_err(dev, "Failed to register host\n");
- goto error;
+ return ret;
}
return 0;
-
-error:
- spi_controller_put(host);
-out:
- return ret;
}
static struct platform_driver a3700_spi_driver = {
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index c21323e07d3c..e9fd9f3b552b 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -697,7 +697,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller);
struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)];
- struct spi_mem_op *op = &desc->info.op_tmpl;
+ struct spi_mem_op *op = desc->info.op_tmpl;
u32 ctl_val;
int ret = 0;
@@ -769,7 +769,7 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (chip->ahb_window_size < offset + len || chip->force_user_mode) {
int ret;
- ret = aspeed_spi_read_user(chip, &desc->info.op_tmpl, offset, len, buf);
+ ret = aspeed_spi_read_user(chip, desc->info.op_tmpl, offset, len, buf);
if (ret < 0)
return ret;
} else {
@@ -891,7 +891,7 @@ static int aspeed_spi_user_unprepare_msg(struct spi_controller *ctlr,
static void aspeed_spi_user_transfer_tx(struct aspeed_spi *aspi,
struct spi_device *spi,
const u8 *tx_buf, u8 *rx_buf,
- void *dst, u32 len)
+ void __iomem *dst, u32 len)
{
const struct aspeed_spi_data *data = aspi->data;
bool full_duplex_transfer = data->full_duplex && tx_buf == rx_buf;
@@ -936,7 +936,7 @@ static int aspeed_spi_user_transfer(struct spi_controller *ctlr,
aspeed_spi_set_io_mode(chip, CTRL_IO_QUAD_DATA);
aspeed_spi_user_transfer_tx(aspi, spi, tx_buf, rx_buf,
- (void *)ahb_base, xfer->len);
+ ahb_base, xfer->len);
}
if (rx_buf && rx_buf != tx_buf) {
@@ -1467,8 +1467,7 @@ end_calib:
* must contains the highest number of consecutive "pass"
* results and not span across multiple rows.
*/
-static u32 aspeed_spi_ast2600_optimized_timing(u32 rows, u32 cols,
- u8 buf[rows][cols])
+static u32 aspeed_spi_ast2600_optimized_timing(u32 rows, u32 cols, u8 *buf)
{
int r = 0, c = 0;
int max = 0;
@@ -1478,7 +1477,7 @@ static u32 aspeed_spi_ast2600_optimized_timing(u32 rows, u32 cols,
for (j = 0; j < cols;) {
int k = j;
- while (k < cols && buf[i][k])
+ while (k < cols && buf[(i * cols) + k])
k++;
if (k - j > max) {
@@ -1541,7 +1540,7 @@ static int aspeed_spi_ast2600_calibrate(struct aspeed_spi_chip *chip, u32 hdiv,
}
}
- calib_point = aspeed_spi_ast2600_optimized_timing(6, 17, calib_res);
+ calib_point = aspeed_spi_ast2600_optimized_timing(6, 17, &calib_res[0][0]);
/* No good setting for this frequency */
if (calib_point == 0)
return -1;
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c
index 79edc1cd13c0..77cad4118202 100644
--- a/drivers/spi/spi-at91-usart.c
+++ b/drivers/spi/spi-at91-usart.c
@@ -16,7 +16,6 @@
#include <linux/gpio/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
@@ -496,14 +495,13 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
if (IS_ERR(clk))
return PTR_ERR(clk);
- ret = -ENOMEM;
- controller = spi_alloc_host(&pdev->dev, sizeof(*aus));
+ controller = devm_spi_alloc_host(&pdev->dev, sizeof(*aus));
if (!controller)
- goto at91_usart_spi_probe_fail;
+ return -ENOMEM;
ret = at91_usart_gpio_setup(pdev);
if (ret)
- goto at91_usart_spi_probe_fail;
+ return ret;
controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH;
controller->dev.of_node = pdev->dev.parent->of_node;
@@ -525,10 +523,8 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
aus->dev = &pdev->dev;
aus->regs = devm_ioremap_resource(&pdev->dev, regs);
- if (IS_ERR(aus->regs)) {
- ret = PTR_ERR(aus->regs);
- goto at91_usart_spi_probe_fail;
- }
+ if (IS_ERR(aus->regs))
+ return PTR_ERR(aus->regs);
aus->irq = irq;
aus->clk = clk;
@@ -536,11 +532,11 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq, at91_usart_spi_interrupt, 0,
dev_name(&pdev->dev), controller);
if (ret)
- goto at91_usart_spi_probe_fail;
+ return ret;
ret = clk_prepare_enable(clk);
if (ret)
- goto at91_usart_spi_probe_fail;
+ return ret;
aus->spi_clk = clk_get_rate(clk);
at91_usart_spi_init(aus);
@@ -571,43 +567,22 @@ at91_usart_fail_register_controller:
at91_usart_spi_release_dma(controller);
at91_usart_fail_dma:
clk_disable_unprepare(clk);
-at91_usart_spi_probe_fail:
- spi_controller_put(controller);
- return ret;
-}
-
-__maybe_unused static int at91_usart_spi_runtime_suspend(struct device *dev)
-{
- struct spi_controller *ctlr = dev_get_drvdata(dev);
- struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
-
- clk_disable_unprepare(aus->clk);
- pinctrl_pm_select_sleep_state(dev);
-
- return 0;
-}
-
-__maybe_unused static int at91_usart_spi_runtime_resume(struct device *dev)
-{
- struct spi_controller *ctrl = dev_get_drvdata(dev);
- struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl);
-
- pinctrl_pm_select_default_state(dev);
- return clk_prepare_enable(aus->clk);
+ return ret;
}
__maybe_unused static int at91_usart_spi_suspend(struct device *dev)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
+ struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl);
int ret;
ret = spi_controller_suspend(ctrl);
if (ret)
return ret;
- if (!pm_runtime_suspended(dev))
- at91_usart_spi_runtime_suspend(dev);
+ clk_disable_unprepare(aus->clk);
+ pinctrl_pm_select_sleep_state(dev);
return 0;
}
@@ -618,11 +593,11 @@ __maybe_unused static int at91_usart_spi_resume(struct device *dev)
struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl);
int ret;
- if (!pm_runtime_suspended(dev)) {
- ret = at91_usart_spi_runtime_resume(dev);
- if (ret)
- return ret;
- }
+ pinctrl_pm_select_default_state(dev);
+
+ ret = clk_prepare_enable(aus->clk);
+ if (ret)
+ return ret;
at91_usart_spi_init(aus);
@@ -634,20 +609,14 @@ static void at91_usart_spi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
- spi_controller_get(ctlr);
-
spi_unregister_controller(ctlr);
at91_usart_spi_release_dma(ctlr);
clk_disable_unprepare(aus->clk);
-
- spi_controller_put(ctlr);
}
static const struct dev_pm_ops at91_usart_spi_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(at91_usart_spi_suspend, at91_usart_spi_resume)
- SET_RUNTIME_PM_OPS(at91_usart_spi_runtime_suspend,
- at91_usart_spi_runtime_resume, NULL)
};
static struct platform_driver at91_usart_spi_driver = {
diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c
index 3832d9db3cbf..6d4b6aeb3f5b 100644
--- a/drivers/spi/spi-atcspi200.c
+++ b/drivers/spi/spi-atcspi200.c
@@ -550,7 +550,7 @@ static int atcspi_probe(struct platform_device *pdev)
struct resource *mem_res;
int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi));
if (!host)
return -ENOMEM;
@@ -559,28 +559,24 @@ static int atcspi_probe(struct platform_device *pdev)
spi->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, host);
- mutex_init(&spi->mutex_lock);
+ ret = devm_mutex_init(&pdev->dev, &spi->mutex_lock);
+ if (ret)
+ return ret;
ret = atcspi_init_resources(pdev, spi, &mem_res);
if (ret)
- goto free_controller;
+ return ret;
ret = atcspi_enable_clk(spi);
if (ret)
- goto free_controller;
+ return ret;
atcspi_init_controller(pdev, spi, host, mem_res);
ret = atcspi_setup(spi);
if (ret)
- goto free_controller;
+ return ret;
- ret = devm_spi_register_controller(&pdev->dev, host);
- if (ret) {
- dev_err_probe(spi->dev, ret,
- "Failed to register SPI controller\n");
- goto free_controller;
- }
spi->use_dma = false;
if (ATCSPI_DMA_SUPPORT) {
ret = atcspi_configure_dma(spi);
@@ -591,12 +587,12 @@ static int atcspi_probe(struct platform_device *pdev)
spi->use_dma = true;
}
- return 0;
+ ret = devm_spi_register_controller(&pdev->dev, host);
+ if (ret)
+ return dev_err_probe(spi->dev, ret,
+ "Failed to register SPI controller\n");
-free_controller:
- mutex_destroy(&spi->mutex_lock);
- spi_controller_put(host);
- return ret;
+ return 0;
}
static int atcspi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 42db85d7ff8e..c8012c82c3a7 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -559,6 +559,38 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word)
return err;
}
+static void atmel_spi_release_dma(void *data)
+{
+ struct spi_controller *host = data;
+ struct atmel_spi *as = spi_controller_get_devdata(host);
+ struct device *dev = &as->pdev->dev;
+
+ if (host->dma_tx) {
+ dma_release_channel(host->dma_tx);
+ host->dma_tx = NULL;
+ }
+
+ if (host->dma_rx) {
+ dma_release_channel(host->dma_rx);
+ host->dma_rx = NULL;
+ }
+
+ if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) {
+ if (as->addr_tx_bbuf) {
+ dma_free_coherent(dev, SPI_MAX_DMA_XFER,
+ as->addr_tx_bbuf,
+ as->dma_addr_tx_bbuf);
+ as->addr_tx_bbuf = NULL;
+ }
+ if (as->addr_rx_bbuf) {
+ dma_free_coherent(dev, SPI_MAX_DMA_XFER,
+ as->addr_rx_bbuf,
+ as->dma_addr_rx_bbuf);
+ as->addr_rx_bbuf = NULL;
+ }
+ }
+}
+
static int atmel_spi_configure_dma(struct spi_controller *host,
struct atmel_spi *as)
{
@@ -569,7 +601,8 @@ static int atmel_spi_configure_dma(struct spi_controller *host,
if (IS_ERR(host->dma_tx)) {
err = PTR_ERR(host->dma_tx);
dev_dbg(dev, "No TX DMA channel, DMA is disabled\n");
- goto error_clear;
+ host->dma_tx = NULL;
+ return err;
}
host->dma_rx = dma_request_chan(dev, "rx");
@@ -580,26 +613,45 @@ static int atmel_spi_configure_dma(struct spi_controller *host,
* requested tx channel.
*/
dev_dbg(dev, "No RX DMA channel, DMA is disabled\n");
- goto error;
+ host->dma_rx = NULL;
+ goto err_release_dma;
}
err = atmel_spi_dma_slave_config(as, 8);
if (err)
- goto error;
+ goto err_release_dma;
+
+ if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) {
+ as->addr_tx_bbuf = dma_alloc_coherent(dev, SPI_MAX_DMA_XFER,
+ &as->dma_addr_tx_bbuf,
+ GFP_KERNEL | GFP_DMA);
+ if (!as->addr_tx_bbuf) {
+ err = -ENOMEM;
+ goto err_release_dma;
+ }
+
+ as->addr_rx_bbuf = dma_alloc_coherent(dev, SPI_MAX_DMA_XFER,
+ &as->dma_addr_rx_bbuf,
+ GFP_KERNEL | GFP_DMA);
+ if (!as->addr_rx_bbuf) {
+ err = -ENOMEM;
+ goto err_release_dma;
+ }
+ }
+
+ err = devm_add_action_or_reset(dev, atmel_spi_release_dma, host);
+ if (err)
+ return err;
dev_info(&as->pdev->dev,
- "Using %s (tx) and %s (rx) for DMA transfers\n",
- dma_chan_name(host->dma_tx),
- dma_chan_name(host->dma_rx));
+ "Using %s (tx) and %s (rx) for DMA transfers\n",
+ dma_chan_name(host->dma_tx), dma_chan_name(host->dma_rx));
return 0;
-error:
- if (!IS_ERR(host->dma_rx))
- dma_release_channel(host->dma_rx);
- if (!IS_ERR(host->dma_tx))
- dma_release_channel(host->dma_tx);
-error_clear:
- host->dma_tx = host->dma_rx = NULL;
+
+err_release_dma:
+ atmel_spi_release_dma(host);
+
return err;
}
@@ -611,18 +663,6 @@ static void atmel_spi_stop_dma(struct spi_controller *host)
dmaengine_terminate_all(host->dma_tx);
}
-static void atmel_spi_release_dma(struct spi_controller *host)
-{
- if (host->dma_rx) {
- dma_release_channel(host->dma_rx);
- host->dma_rx = NULL;
- }
- if (host->dma_tx) {
- dma_release_channel(host->dma_tx);
- host->dma_tx = NULL;
- }
-}
-
/* This function is called by the DMA driver from tasklet context */
static void dma_callback(void *data)
{
@@ -1528,7 +1568,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
return PTR_ERR(clk);
/* setup spi core then atmel-specific driver state */
- host = spi_alloc_host(&pdev->dev, sizeof(*as));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*as));
if (!host)
return -ENOMEM;
@@ -1555,18 +1595,15 @@ static int atmel_spi_probe(struct platform_device *pdev)
as->pdev = pdev;
as->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
- if (IS_ERR(as->regs)) {
- ret = PTR_ERR(as->regs);
- goto out_unmap_regs;
- }
+ if (IS_ERR(as->regs))
+ return PTR_ERR(as->regs);
+
as->phybase = regs->start;
as->irq = irq;
as->clk = clk;
as->gclk = devm_clk_get_optional(&pdev->dev, "spi_gclk");
- if (IS_ERR(as->gclk)) {
- ret = PTR_ERR(as->gclk);
- goto out_unmap_regs;
- }
+ if (IS_ERR(as->gclk))
+ return PTR_ERR(as->gclk);
init_completion(&as->xfer_completion);
@@ -1576,39 +1613,14 @@ static int atmel_spi_probe(struct platform_device *pdev)
as->use_pdc = false;
if (as->caps.has_dma_support) {
ret = atmel_spi_configure_dma(host, as);
- if (ret == 0) {
+ if (ret == 0)
as->use_dma = true;
- } else if (ret == -EPROBE_DEFER) {
- goto out_unmap_regs;
- }
+ else if (ret == -EPROBE_DEFER)
+ return ret;
} else if (as->caps.has_pdc_support) {
as->use_pdc = true;
}
- if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) {
- as->addr_rx_bbuf = dma_alloc_coherent(&pdev->dev,
- SPI_MAX_DMA_XFER,
- &as->dma_addr_rx_bbuf,
- GFP_KERNEL | GFP_DMA);
- if (!as->addr_rx_bbuf) {
- as->use_dma = false;
- } else {
- as->addr_tx_bbuf = dma_alloc_coherent(&pdev->dev,
- SPI_MAX_DMA_XFER,
- &as->dma_addr_tx_bbuf,
- GFP_KERNEL | GFP_DMA);
- if (!as->addr_tx_bbuf) {
- as->use_dma = false;
- dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER,
- as->addr_rx_bbuf,
- as->dma_addr_rx_bbuf);
- }
- }
- if (!as->use_dma)
- dev_info(host->dev.parent,
- " can not allocate dma coherent memory\n");
- }
-
if (as->caps.has_dma_support && !as->use_dma)
dev_info(&pdev->dev, "Atmel SPI Controller using PIO only\n");
@@ -1620,12 +1632,12 @@ static int atmel_spi_probe(struct platform_device *pdev)
0, dev_name(&pdev->dev), host);
}
if (ret)
- goto out_unmap_regs;
+ return ret;
/* Initialize the hardware */
ret = clk_prepare_enable(clk);
if (ret)
- goto out_free_irq;
+ return ret;
/*
* In cases where the peripheral clock is higher,the FLEX_SPI_CSRx.SCBR
@@ -1668,18 +1680,13 @@ static int atmel_spi_probe(struct platform_device *pdev)
out_free_dma:
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
-
- if (as->use_dma)
- atmel_spi_release_dma(host);
-
spi_writel(as, CR, SPI_BIT(SWRST));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
- clk_disable_unprepare(as->gclk);
+ if (as->gclk)
+ clk_disable_unprepare(as->gclk);
out_disable_clk:
clk_disable_unprepare(clk);
-out_free_irq:
-out_unmap_regs:
- spi_controller_put(host);
+
return ret;
}
@@ -1688,25 +1695,13 @@ static void atmel_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct atmel_spi *as = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
pm_runtime_get_sync(&pdev->dev);
spi_unregister_controller(host);
/* reset the hardware and block queue progress */
- if (as->use_dma) {
+ if (as->use_dma)
atmel_spi_stop_dma(host);
- atmel_spi_release_dma(host);
- if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) {
- dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER,
- as->addr_tx_bbuf,
- as->dma_addr_tx_bbuf);
- dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER,
- as->addr_rx_bbuf,
- as->dma_addr_rx_bbuf);
- }
- }
spin_lock_irq(&as->lock);
spi_writel(as, CR, SPI_BIT(SWRST));
@@ -1720,8 +1715,6 @@ static void atmel_spi_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(host);
}
static int atmel_spi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
index e935e8ab9cfd..58012e1b5ae7 100644
--- a/drivers/spi/spi-bcm63xx-hsspi.c
+++ b/drivers/spi/spi-bcm63xx-hsspi.c
@@ -783,7 +783,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
"failed get pll clk rate\n");
}
- host = spi_alloc_host(&pdev->dev, sizeof(*bs));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*bs));
if (!host)
return dev_err_probe(dev, -ENOMEM, "alloc host no mem\n");
@@ -796,10 +796,8 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0));
bs->wait_mode = HSSPI_WAIT_MODE_POLLING;
bs->prepend_buf = devm_kzalloc(dev, HSSPI_BUFFER_LEN, GFP_KERNEL);
- if (!bs->prepend_buf) {
- ret = -ENOMEM;
- goto out_put_host;
- }
+ if (!bs->prepend_buf)
+ return -ENOMEM;
mutex_init(&bs->bus_mutex);
mutex_init(&bs->msg_mutex);
@@ -845,7 +843,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
pdev->name, bs);
if (ret)
- goto out_put_host;
+ return ret;
}
pm_runtime_enable(&pdev->dev);
@@ -869,8 +867,7 @@ out_sysgroup_disable:
sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group);
out_pm_disable:
pm_runtime_disable(&pdev->dev);
-out_put_host:
- spi_controller_put(host);
+
return ret;
}
@@ -880,15 +877,11 @@ static void bcm63xx_hsspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
/* reset the hardware and block queue progress */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group);
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index 40cd7efc4b54..43d7b54e3ae8 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -477,8 +477,7 @@ static const struct platform_device_id bcm63xx_spi_dev_match[] = {
.name = "bcm6358-spi",
.driver_data = (unsigned long)bcm6358_spi_reg_offsets,
},
- {
- },
+ { }
};
MODULE_DEVICE_TABLE(platform, bcm63xx_spi_dev_match);
@@ -541,11 +540,9 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
if (IS_ERR(reset))
return PTR_ERR(reset);
- host = spi_alloc_host(dev, sizeof(*bs));
- if (!host) {
- dev_err(dev, "out of memory\n");
+ host = devm_spi_alloc_host(dev, sizeof(*bs));
+ if (!host)
return -ENOMEM;
- }
bs = spi_controller_get_devdata(host);
init_completion(&bs->done);
@@ -554,10 +551,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
bs->pdev = pdev;
bs->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
- if (IS_ERR(bs->regs)) {
- ret = PTR_ERR(bs->regs);
- goto out_err;
- }
+ if (IS_ERR(bs->regs))
+ return PTR_ERR(bs->regs);
bs->irq = irq;
bs->clk = clk;
@@ -568,7 +563,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
pdev->name, host);
if (ret) {
dev_err(dev, "unable to request irq\n");
- goto out_err;
+ return ret;
}
host->bus_num = bus_num;
@@ -587,7 +582,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
/* Initialize hardware */
ret = clk_prepare_enable(bs->clk);
if (ret)
- goto out_err;
+ return ret;
ret = reset_control_reset(reset);
if (ret) {
@@ -615,8 +610,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
out_clk_disable:
clk_disable_unprepare(clk);
-out_err:
- spi_controller_put(host);
+
return ret;
}
@@ -625,8 +619,6 @@ static void bcm63xx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
/* reset spi block */
@@ -634,8 +626,6 @@ static void bcm63xx_spi_remove(struct platform_device *pdev)
/* HW shutdown */
clk_disable_unprepare(bs->clk);
-
- spi_controller_put(host);
}
static int bcm63xx_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 9f03ac217319..fb288ed56d94 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -420,11 +420,6 @@ EXPORT_SYMBOL_GPL(spi_bitbang_init);
* This routine registers the spi_controller, which will process requests in a
* dedicated task, keeping IRQs unblocked most of the time. To stop
* processing those requests, call spi_bitbang_stop().
- *
- * On success, this routine will take a reference to the controller. The caller
- * is responsible for calling spi_bitbang_stop() to decrement the reference and
- * spi_controller_put() as counterpart of spi_alloc_host() to prevent a memory
- * leak.
*/
int spi_bitbang_start(struct spi_bitbang *bitbang)
{
@@ -438,11 +433,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
/* driver may get busy before register() returns, especially
* if someone registered boardinfo for devices
*/
- ret = spi_register_controller(spi_controller_get(ctlr));
- if (ret)
- spi_controller_put(ctlr);
-
- return ret;
+ return spi_register_controller(ctlr);
}
EXPORT_SYMBOL_GPL(spi_bitbang_start);
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 057381e56a7f..aaba1a3ad577 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1478,7 +1478,6 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
int ret;
struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
struct device *dev = &cqspi->pdev->dev;
- const struct cqspi_driver_platdata *ddata = of_device_get_match_data(dev);
if (refcount_read(&cqspi->inflight_ops) == 0)
return -ENODEV;
@@ -1494,18 +1493,15 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
return -EBUSY;
}
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
- ret = pm_runtime_resume_and_get(dev);
- if (ret) {
- dev_err(&mem->spi->dev, "resume failed with %d\n", ret);
- goto dec_inflight_refcount;
- }
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret) {
+ dev_err(&mem->spi->dev, "resume failed with %d\n", ret);
+ goto dec_inflight_refcount;
}
ret = cqspi_mem_process(mem, op);
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
- pm_runtime_put_autosuspend(dev);
+ pm_runtime_put_autosuspend(dev);
if (ret)
dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
@@ -1957,13 +1953,11 @@ static int cqspi_probe(struct platform_device *pdev)
cqspi->current_cs = -1;
cqspi->sclk = 0;
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
- pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_get_noresume(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
- }
+ pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
host->num_chipselect = cqspi->num_chipselect;
@@ -1993,12 +1987,11 @@ release_dma_chan:
if (cqspi->rx_chan)
dma_release_channel(cqspi->rx_chan);
disable_rpm:
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_put_noidle(dev);
- pm_runtime_dont_use_autosuspend(dev);
- }
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+
cqspi_controller_enable(cqspi, 0);
disable_clks:
clk_bulk_disable_unprepare(CLK_QSPI_NUM, cqspi->clks);
@@ -2008,13 +2001,10 @@ disable_clks:
static void cqspi_remove(struct platform_device *pdev)
{
- const struct cqspi_driver_platdata *ddata;
struct cqspi_st *cqspi = platform_get_drvdata(pdev);
- struct device *dev = &pdev->dev;
+ const struct cqspi_driver_platdata *ddata = cqspi->ddata;
int ret = 0;
- ddata = of_device_get_match_data(dev);
-
spi_unregister_controller(cqspi->host);
refcount_set(&cqspi->refcount, 0);
@@ -2033,12 +2023,10 @@ static void cqspi_remove(struct platform_device *pdev)
clk_bulk_disable_unprepare(CLK_QSPI_NUM, cqspi->clks);
}
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
- pm_runtime_put_noidle(&pdev->dev);
- pm_runtime_dont_use_autosuspend(&pdev->dev);
- }
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
}
static int cqspi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 895b4b3276a5..e1b337789fce 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -369,6 +369,8 @@ struct cdns_xspi_dev {
void *in_buffer;
const void *out_buffer;
+ /* Slave DMA data width in bytes (4 or 8). */
+ u8 dma_data_width;
u8 hw_num_banks;
@@ -453,8 +455,7 @@ static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi,
writel(clk_reg,
cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
clk_reg = FIELD_PREP(MRVL_XSPI_CLK_DIV, i);
- clk_reg &= ~MRVL_XSPI_CLK_DIV;
- clk_reg |= FIELD_PREP(MRVL_XSPI_CLK_DIV, i);
+ FIELD_MODIFY(MRVL_XSPI_CLK_DIV, &clk_reg, i);
clk_reg |= MRVL_XSPI_CLK_ENABLE;
clk_reg |= MRVL_XSPI_IRQ_ENABLE;
update_clk = true;
@@ -573,11 +574,56 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
ctrl_features = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_FEATURES_REG);
cdns_xspi->hw_num_banks = FIELD_GET(CDNS_XSPI_NUM_BANKS, ctrl_features);
+ cdns_xspi->dma_data_width = (ctrl_features & CDNS_XSPI_DMA_DATA_WIDTH) ? 8 : 4;
cdns_xspi->set_interrupts_handler(cdns_xspi, false);
return 0;
}
+static inline void cdns_xspi_sdma_read(struct cdns_xspi_dev *cdns_xspi, size_t len)
+{
+ void __iomem *src = cdns_xspi->sdmabase;
+ void *buf = cdns_xspi->in_buffer;
+ size_t offset = 0;
+
+ if (cdns_xspi->dma_data_width == 4) {
+ if (IS_ALIGNED((uintptr_t)src, 4) && IS_ALIGNED((uintptr_t)buf, 4)) {
+ ioread32_rep(src, buf, len >> 2);
+ offset = len & ~0x3;
+ len -= offset;
+ }
+ } else {
+ if (IS_ALIGNED((uintptr_t)src, 8) && IS_ALIGNED((uintptr_t)buf, 8)) {
+ readsq(src, buf, len >> 3);
+ offset = len & ~0x7;
+ len -= offset;
+ }
+ }
+ ioread8_rep(src, (u8 *)buf + offset, len);
+}
+
+static inline void cdns_xspi_sdma_write(struct cdns_xspi_dev *cdns_xspi, size_t len)
+{
+ void __iomem *dst = cdns_xspi->sdmabase;
+ const void *buf = cdns_xspi->out_buffer;
+ size_t offset = 0;
+
+ if (cdns_xspi->dma_data_width == 4) {
+ if (IS_ALIGNED((uintptr_t)dst, 4) && IS_ALIGNED((uintptr_t)buf, 4)) {
+ iowrite32_rep(dst, buf, len >> 2);
+ offset = len & ~0x3;
+ len -= offset;
+ }
+ } else {
+ if (IS_ALIGNED((uintptr_t)dst, 8) && IS_ALIGNED((uintptr_t)buf, 8)) {
+ writesq(dst, buf, len >> 3);
+ offset = len & ~0x7;
+ len -= offset;
+ }
+ }
+ iowrite8_rep(dst, (const u8 *)buf + offset, len);
+}
+
static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
{
u32 sdma_size, sdma_trd_info;
@@ -589,13 +635,11 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
switch (sdma_dir) {
case CDNS_XSPI_SDMA_DIR_READ:
- ioread8_rep(cdns_xspi->sdmabase,
- cdns_xspi->in_buffer, sdma_size);
+ cdns_xspi_sdma_read(cdns_xspi, sdma_size);
break;
case CDNS_XSPI_SDMA_DIR_WRITE:
- iowrite8_rep(cdns_xspi->sdmabase,
- cdns_xspi->out_buffer, sdma_size);
+ cdns_xspi_sdma_write(cdns_xspi, sdma_size);
break;
}
}
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 891e2ba36958..9b4e5b7013ae 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -635,7 +635,7 @@ static int cdns_target_abort(struct spi_controller *ctlr)
*/
static int cdns_spi_probe(struct platform_device *pdev)
{
- int ret = 0, irq;
+ int ret, irq;
struct spi_controller *ctlr;
struct cdns_spi *xspi;
u32 num_cs;
@@ -643,9 +643,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
target = of_property_read_bool(pdev->dev.of_node, "spi-slave");
if (target)
- ctlr = spi_alloc_target(&pdev->dev, sizeof(*xspi));
+ ctlr = devm_spi_alloc_target(&pdev->dev, sizeof(*xspi));
else
- ctlr = spi_alloc_host(&pdev->dev, sizeof(*xspi));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*xspi));
if (!ctlr)
return -ENOMEM;
@@ -654,23 +654,19 @@ static int cdns_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctlr);
xspi->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(xspi->regs)) {
- ret = PTR_ERR(xspi->regs);
- goto remove_ctlr;
- }
+ if (IS_ERR(xspi->regs))
+ return PTR_ERR(xspi->regs);
xspi->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
if (IS_ERR(xspi->pclk)) {
dev_err(&pdev->dev, "pclk clock not found.\n");
- ret = PTR_ERR(xspi->pclk);
- goto remove_ctlr;
+ return PTR_ERR(xspi->pclk);
}
xspi->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, "spi");
if (IS_ERR(xspi->rstc)) {
- ret = dev_err_probe(&pdev->dev, PTR_ERR(xspi->rstc),
- "Cannot get SPI reset.\n");
- goto remove_ctlr;
+ return dev_err_probe(&pdev->dev, PTR_ERR(xspi->rstc),
+ "Cannot get SPI reset.\n");
}
reset_control_assert(xspi->rstc);
@@ -679,8 +675,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
xspi->ref_clk = devm_clk_get_enabled(&pdev->dev, "ref_clk");
if (IS_ERR(xspi->ref_clk)) {
dev_err(&pdev->dev, "ref_clk clock not found.\n");
- ret = PTR_ERR(xspi->ref_clk);
- goto remove_ctlr;
+ return PTR_ERR(xspi->ref_clk);
}
if (!spi_controller_is_target(ctlr)) {
@@ -710,7 +705,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
- goto clk_dis_all;
+ goto err_disable_rpm;
}
ret = devm_request_irq(&pdev->dev, irq, cdns_spi_irq,
@@ -718,7 +713,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
if (ret != 0) {
ret = -ENXIO;
dev_err(&pdev->dev, "request_irq failed\n");
- goto clk_dis_all;
+ goto err_disable_rpm;
}
ctlr->use_gpio_descriptors = true;
@@ -748,23 +743,22 @@ static int cdns_spi_probe(struct platform_device *pdev)
ret = spi_register_controller(ctlr);
if (ret) {
dev_err(&pdev->dev, "spi_register_controller failed\n");
- goto clk_dis_all;
+ goto err_disable_rpm;
}
if (!spi_controller_is_target(ctlr))
pm_runtime_put_autosuspend(&pdev->dev);
- return ret;
+ return 0;
-clk_dis_all:
+err_disable_rpm:
if (!spi_controller_is_target(ctlr)) {
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
}
-remove_ctlr:
- spi_controller_put(ctlr);
+
return ret;
}
@@ -785,8 +779,6 @@ static void cdns_spi_remove(struct platform_device *pdev)
if (!spi_controller_is_target(ctlr))
ret = pm_runtime_get_sync(&pdev->dev);
- spi_controller_get(ctlr);
-
spi_unregister_controller(ctlr);
if (ret >= 0)
@@ -798,8 +790,6 @@ static void cdns_spi_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
}
-
- spi_controller_put(ctlr);
}
/**
diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c
index b95bfa6a3013..28c922c72068 100644
--- a/drivers/spi/spi-cavium-octeon.c
+++ b/drivers/spi/spi-cavium-octeon.c
@@ -23,17 +23,15 @@ static int octeon_spi_probe(struct platform_device *pdev)
struct octeon_spi *p;
int err = -ENOENT;
- host = spi_alloc_host(&pdev->dev, sizeof(struct octeon_spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct octeon_spi));
if (!host)
return -ENOMEM;
p = spi_controller_get_devdata(host);
platform_set_drvdata(pdev, host);
reg_base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(reg_base)) {
- err = PTR_ERR(reg_base);
- goto fail;
- }
+ if (IS_ERR(reg_base))
+ return PTR_ERR(reg_base);
p->register_base = reg_base;
p->sys_freq = octeon_get_io_clock_rate();
@@ -57,15 +55,12 @@ static int octeon_spi_probe(struct platform_device *pdev)
err = spi_register_controller(host);
if (err) {
dev_err(&pdev->dev, "register host failed: %d\n", err);
- goto fail;
+ return err;
}
dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
return 0;
-fail:
- spi_controller_put(host);
- return err;
}
static void octeon_spi_remove(struct platform_device *pdev)
@@ -73,14 +68,10 @@ static void octeon_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct octeon_spi *p = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
/* Clear the CSENA* and put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
-
- spi_controller_put(host);
}
static const struct of_device_id octeon_spi_match[] = {
diff --git a/drivers/spi/spi-cavium-thunderx.c b/drivers/spi/spi-cavium-thunderx.c
index f1a9aa696c87..529b4066c922 100644
--- a/drivers/spi/spi-cavium-thunderx.c
+++ b/drivers/spi/spi-cavium-thunderx.c
@@ -24,7 +24,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
struct octeon_spi *p;
int ret;
- host = spi_alloc_host(dev, sizeof(struct octeon_spi));
+ host = devm_spi_alloc_host(dev, sizeof(struct octeon_spi));
if (!host)
return -ENOMEM;
@@ -32,17 +32,15 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
ret = pcim_enable_device(pdev);
if (ret)
- goto error;
+ return ret;
ret = pcim_request_all_regions(pdev, DRV_NAME);
if (ret)
- goto error;
+ return ret;
p->register_base = pcim_iomap(pdev, 0, pci_resource_len(pdev, 0));
- if (!p->register_base) {
- ret = -EINVAL;
- goto error;
- }
+ if (!p->register_base)
+ return -EINVAL;
p->regs.config = 0x1000;
p->regs.status = 0x1008;
@@ -50,10 +48,8 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
p->regs.data = 0x1080;
p->clk = devm_clk_get_enabled(dev, NULL);
- if (IS_ERR(p->clk)) {
- ret = PTR_ERR(p->clk);
- goto error;
- }
+ if (IS_ERR(p->clk))
+ return PTR_ERR(p->clk);
p->sys_freq = clk_get_rate(p->clk);
if (!p->sys_freq)
@@ -70,15 +66,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, host);
- ret = spi_register_controller(host);
- if (ret)
- goto error;
-
- return 0;
-
-error:
- spi_controller_put(host);
- return ret;
+ return spi_register_controller(host);
}
static void thunderx_spi_remove(struct pci_dev *pdev)
@@ -90,14 +78,10 @@ static void thunderx_spi_remove(struct pci_dev *pdev)
if (!p)
return;
- spi_controller_get(host);
-
spi_unregister_controller(host);
/* Put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
-
- spi_controller_put(host);
}
static const struct pci_device_id thunderx_spi_pci_id_table[] = {
diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c
index d6458e59d41b..382c3c81c4b9 100644
--- a/drivers/spi/spi-clps711x.c
+++ b/drivers/spi/spi-clps711x.c
@@ -99,7 +99,7 @@ static int spi_clps711x_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- host = spi_alloc_host(&pdev->dev, sizeof(*hw));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*hw));
if (!host)
return -ENOMEM;
@@ -113,22 +113,16 @@ static int spi_clps711x_probe(struct platform_device *pdev)
hw = spi_controller_get_devdata(host);
hw->spi_clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(hw->spi_clk)) {
- ret = PTR_ERR(hw->spi_clk);
- goto err_out;
- }
+ if (IS_ERR(hw->spi_clk))
+ return PTR_ERR(hw->spi_clk);
hw->syscon = syscon_regmap_lookup_by_phandle(np, "syscon");
- if (IS_ERR(hw->syscon)) {
- ret = PTR_ERR(hw->syscon);
- goto err_out;
- }
+ if (IS_ERR(hw->syscon))
+ return PTR_ERR(hw->syscon);
hw->syncio = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(hw->syncio)) {
- ret = PTR_ERR(hw->syncio);
- goto err_out;
- }
+ if (IS_ERR(hw->syncio))
+ return PTR_ERR(hw->syncio);
/* Disable extended mode due hardware problems */
regmap_update_bits(hw->syscon, SYSCON_OFFSET, SYSCON3_ADCCON, 0);
@@ -139,16 +133,9 @@ static int spi_clps711x_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq, spi_clps711x_isr, 0,
dev_name(&pdev->dev), host);
if (ret)
- goto err_out;
+ return ret;
- ret = devm_spi_register_controller(&pdev->dev, host);
- if (!ret)
- return 0;
-
-err_out:
- spi_controller_put(host);
-
- return ret;
+ return devm_spi_register_controller(&pdev->dev, host);
}
static const struct of_device_id clps711x_spi_dt_ids[] = {
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
index b45f44de85dc..3b175c1da36b 100644
--- a/drivers/spi/spi-coldfire-qspi.c
+++ b/drivers/spi/spi-coldfire-qspi.c
@@ -353,39 +353,33 @@ static int mcfqspi_probe(struct platform_device *pdev)
return -EINVAL;
}
- host = spi_alloc_host(&pdev->dev, sizeof(*mcfqspi));
- if (host == NULL) {
- dev_dbg(&pdev->dev, "spi_alloc_host failed\n");
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*mcfqspi));
+ if (host == NULL)
return -ENOMEM;
- }
mcfqspi = spi_controller_get_devdata(host);
mcfqspi->iobase = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(mcfqspi->iobase)) {
- status = PTR_ERR(mcfqspi->iobase);
- goto fail0;
- }
+ if (IS_ERR(mcfqspi->iobase))
+ return PTR_ERR(mcfqspi->iobase);
mcfqspi->irq = platform_get_irq(pdev, 0);
if (mcfqspi->irq < 0) {
dev_dbg(&pdev->dev, "platform_get_irq failed\n");
- status = -ENXIO;
- goto fail0;
+ return -ENXIO;
}
status = devm_request_irq(&pdev->dev, mcfqspi->irq, mcfqspi_irq_handler,
0, pdev->name, mcfqspi);
if (status) {
dev_dbg(&pdev->dev, "request_irq failed\n");
- goto fail0;
+ return status;
}
mcfqspi->clk = devm_clk_get_enabled(&pdev->dev, "qspi_clk");
if (IS_ERR(mcfqspi->clk)) {
dev_dbg(&pdev->dev, "clk_get failed\n");
- status = PTR_ERR(mcfqspi->clk);
- goto fail0;
+ return PTR_ERR(mcfqspi->clk);
}
host->bus_num = pdata->bus_num;
@@ -395,7 +389,7 @@ static int mcfqspi_probe(struct platform_device *pdev)
status = mcfqspi_cs_setup(mcfqspi);
if (status) {
dev_dbg(&pdev->dev, "error initializing cs_control\n");
- goto fail0;
+ return status;
}
init_waitqueue_head(&mcfqspi->waitq);
@@ -423,8 +417,6 @@ static int mcfqspi_probe(struct platform_device *pdev)
fail1:
pm_runtime_disable(&pdev->dev);
mcfqspi_cs_teardown(mcfqspi);
-fail0:
- spi_controller_put(host);
dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
@@ -436,8 +428,6 @@ static void mcfqspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_disable(&pdev->dev);
@@ -445,8 +435,6 @@ static void mcfqspi_remove(struct platform_device *pdev)
mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
mcfqspi_cs_teardown(mcfqspi);
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-cs42l43.c b/drivers/spi/spi-cs42l43.c
index 68f208ef1e01..6961e36b89d1 100644
--- a/drivers/spi/spi-cs42l43.c
+++ b/drivers/spi/spi-cs42l43.c
@@ -438,8 +438,8 @@ static int cs42l43_spi_probe(struct platform_device *pdev)
}
static const struct platform_device_id cs42l43_spi_id_table[] = {
- { "cs42l43-spi", },
- {}
+ { .name = "cs42l43-spi" },
+ { }
};
MODULE_DEVICE_TABLE(platform, cs42l43_spi_id_table);
diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c
index 392f0d05f508..8333dda7d1e8 100644
--- a/drivers/spi/spi-dln2.c
+++ b/drivers/spi/spi-dln2.c
@@ -684,7 +684,7 @@ static int dln2_spi_probe(struct platform_device *pdev)
struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev);
int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*dln2));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*dln2));
if (!host)
return -ENOMEM;
@@ -693,10 +693,8 @@ static int dln2_spi_probe(struct platform_device *pdev)
dln2 = spi_controller_get_devdata(host);
dln2->buf = devm_kmalloc(&pdev->dev, DLN2_SPI_BUF_SIZE, GFP_KERNEL);
- if (!dln2->buf) {
- ret = -ENOMEM;
- goto exit_free_host;
- }
+ if (!dln2->buf)
+ return -ENOMEM;
dln2->host = host;
dln2->pdev = pdev;
@@ -709,13 +707,13 @@ static int dln2_spi_probe(struct platform_device *pdev)
ret = dln2_spi_enable(dln2, false);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to disable SPI module\n");
- goto exit_free_host;
+ return ret;
}
ret = dln2_spi_get_cs_num(dln2, &host->num_chipselect);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get number of CS pins\n");
- goto exit_free_host;
+ return ret;
}
ret = dln2_spi_get_speed_range(dln2,
@@ -723,20 +721,20 @@ static int dln2_spi_probe(struct platform_device *pdev)
&host->max_speed_hz);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to read bus min/max freqs\n");
- goto exit_free_host;
+ return ret;
}
ret = dln2_spi_get_supported_frame_sizes(dln2,
&host->bits_per_word_mask);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to read supported frame sizes\n");
- goto exit_free_host;
+ return ret;
}
ret = dln2_spi_cs_enable_all(dln2, true);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable CS pins\n");
- goto exit_free_host;
+ return ret;
}
host->bus_num = -1;
@@ -749,7 +747,7 @@ static int dln2_spi_probe(struct platform_device *pdev)
ret = dln2_spi_enable(dln2, true);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable SPI module\n");
- goto exit_free_host;
+ return ret;
}
pm_runtime_set_autosuspend_delay(&pdev->dev,
@@ -772,8 +770,6 @@ exit_register:
if (dln2_spi_enable(dln2, false) < 0)
dev_err(&pdev->dev, "Failed to disable SPI module\n");
-exit_free_host:
- spi_controller_put(host);
return ret;
}
@@ -783,16 +779,12 @@ static void dln2_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_disable(&pdev->dev);
if (dln2_spi_enable(dln2, false) < 0)
dev_err(&pdev->dev, "Failed to disable SPI module\n");
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
index 4672bc2a873a..eff08461c2f5 100644
--- a/drivers/spi/spi-dw-core.c
+++ b/drivers/spi/spi-dw-core.c
@@ -1034,6 +1034,8 @@ void dw_spi_remove_controller(struct dw_spi *dws)
dw_spi_shutdown_chip(dws);
free_irq(dws->irq, dws->ctlr);
+
+ spi_controller_put(dws->ctlr);
}
EXPORT_SYMBOL_NS_GPL(dw_spi_remove_controller, "SPI_DW_CORE");
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
index 1bfdf24c3227..4fc864d38cff 100644
--- a/drivers/spi/spi-dw-mmio.c
+++ b/drivers/spi/spi-dw-mmio.c
@@ -226,8 +226,8 @@ static int dw_spi_hssi_init(struct platform_device *pdev,
return 0;
}
-static int dw_spi_intel_init(struct platform_device *pdev,
- struct dw_spi_mmio *dwsmmio)
+static int dw_spi_hssi_no_dma_init(struct platform_device *pdev,
+ struct dw_spi_mmio *dwsmmio)
{
dwsmmio->dws.ip = DW_HSSI_ID;
@@ -438,7 +438,7 @@ static const struct of_device_id dw_spi_mmio_of_match[] = {
{ .compatible = "amazon,alpine-dw-apb-ssi", .data = dw_spi_alpine_init},
{ .compatible = "renesas,rzn1-spi", .data = dw_spi_pssi_init},
{ .compatible = "snps,dwc-ssi-1.01a", .data = dw_spi_hssi_init},
- { .compatible = "intel,keembay-ssi", .data = dw_spi_intel_init},
+ { .compatible = "intel,keembay-ssi", .data = dw_spi_hssi_no_dma_init},
{
.compatible = "intel,mountevans-imc-ssi",
.data = dw_spi_mountevans_imc_init,
@@ -453,6 +453,7 @@ MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id dw_spi_mmio_acpi_match[] = {
{"HISI0173", (kernel_ulong_t)dw_spi_pssi_init},
+ {"LECA0002", (kernel_ulong_t)dw_spi_hssi_no_dma_init},
{},
};
MODULE_DEVICE_TABLE(acpi, dw_spi_mmio_acpi_match);
diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c
index 72d9f5bc87f7..bfb874f96a26 100644
--- a/drivers/spi/spi-dw-pci.c
+++ b/drivers/spi/spi-dw-pci.c
@@ -120,16 +120,15 @@ static int dw_spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *en
if (desc->setup) {
ret = desc->setup(dws);
if (ret)
- goto err_free_irq_vectors;
+ return ret;
}
} else {
- ret = -ENODEV;
- goto err_free_irq_vectors;
+ return -ENODEV;
}
ret = dw_spi_add_controller(&pdev->dev, dws);
if (ret)
- goto err_free_irq_vectors;
+ return ret;
/* PCI hook and SPI hook use the same drv data */
pci_set_drvdata(pdev, dws);
@@ -143,10 +142,6 @@ static int dw_spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *en
pm_runtime_allow(&pdev->dev);
return 0;
-
-err_free_irq_vectors:
- pci_free_irq_vectors(pdev);
- return ret;
}
static void dw_spi_pci_remove(struct pci_dev *pdev)
@@ -157,7 +152,6 @@ static void dw_spi_pci_remove(struct pci_dev *pdev)
pm_runtime_get_noresume(&pdev->dev);
dw_spi_remove_controller(dws);
- pci_free_irq_vectors(pdev);
}
#ifdef CONFIG_PM_SLEEP
@@ -185,15 +179,15 @@ static const struct pci_device_id dw_spi_pci_ids[] = {
* exclusively used by SCU to communicate with MSIC.
*/
/* Intel MID platform SPI controller 1 */
- { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&dw_spi_pci_mid_desc_1},
+ { PCI_VDEVICE(INTEL, 0x0800), .driver_data = (kernel_ulong_t)&dw_spi_pci_mid_desc_1 },
/* Intel MID platform SPI controller 2 */
- { PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&dw_spi_pci_mid_desc_2},
+ { PCI_VDEVICE(INTEL, 0x0812), .driver_data = (kernel_ulong_t)&dw_spi_pci_mid_desc_2 },
/* Intel Elkhart Lake PSE SPI controllers */
- { PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&dw_spi_pci_ehl_desc},
- { PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&dw_spi_pci_ehl_desc},
- { PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&dw_spi_pci_ehl_desc},
- { PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&dw_spi_pci_ehl_desc},
- {},
+ { PCI_VDEVICE(INTEL, 0x4b84), .driver_data = (kernel_ulong_t)&dw_spi_pci_ehl_desc },
+ { PCI_VDEVICE(INTEL, 0x4b85), .driver_data = (kernel_ulong_t)&dw_spi_pci_ehl_desc },
+ { PCI_VDEVICE(INTEL, 0x4b86), .driver_data = (kernel_ulong_t)&dw_spi_pci_ehl_desc },
+ { PCI_VDEVICE(INTEL, 0x4b87), .driver_data = (kernel_ulong_t)&dw_spi_pci_ehl_desc },
+ { },
};
MODULE_DEVICE_TABLE(pci, dw_spi_pci_ids);
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
index f716c9607be4..bf389d7590d3 100644
--- a/drivers/spi/spi-ep93xx.c
+++ b/drivers/spi/spi-ep93xx.c
@@ -600,6 +600,7 @@ fail_release_rx:
espi->dma_rx = NULL;
fail_free_page:
free_page((unsigned long)espi->zeropage);
+ espi->zeropage = NULL;
return ret;
}
@@ -631,7 +632,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- host = spi_alloc_host(&pdev->dev, sizeof(*espi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*espi));
if (!host)
return -ENOMEM;
@@ -656,8 +657,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
espi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(espi->clk)) {
dev_err(&pdev->dev, "unable to get spi clock\n");
- error = PTR_ERR(espi->clk);
- goto fail_release_host;
+ return PTR_ERR(espi->clk);
}
/*
@@ -668,22 +668,21 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
host->min_speed_hz = clk_get_rate(espi->clk) / (254 * 256);
espi->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(espi->mmio)) {
- error = PTR_ERR(espi->mmio);
- goto fail_release_host;
- }
+ if (IS_ERR(espi->mmio))
+ return PTR_ERR(espi->mmio);
+
espi->sspdr_phys = res->start + SSPDR;
error = devm_request_irq(&pdev->dev, irq, ep93xx_spi_interrupt,
0, "ep93xx-spi", host);
if (error) {
dev_err(&pdev->dev, "failed to request irq\n");
- goto fail_release_host;
+ return error;
}
error = ep93xx_spi_setup_dma(&pdev->dev, espi);
if (error == -EPROBE_DEFER)
- goto fail_release_host;
+ return error;
if (error)
dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n");
@@ -704,8 +703,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
fail_free_dma:
ep93xx_spi_release_dma(espi);
-fail_release_host:
- spi_controller_put(host);
return error;
}
@@ -715,13 +712,9 @@ static void ep93xx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
ep93xx_spi_release_dma(espi);
-
- spi_controller_put(host);
}
static const struct of_device_id ep93xx_spi_of_ids[] = {
diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c
index cb15faabd88f..e00e808eafee 100644
--- a/drivers/spi/spi-falcon.c
+++ b/drivers/spi/spi-falcon.c
@@ -392,9 +392,8 @@ static int falcon_sflash_probe(struct platform_device *pdev)
{
struct falcon_sflash *priv;
struct spi_controller *host;
- int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*priv));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*priv));
if (!host)
return -ENOMEM;
@@ -406,10 +405,7 @@ static int falcon_sflash_probe(struct platform_device *pdev)
host->setup = falcon_sflash_setup;
host->transfer_one_message = falcon_sflash_xfer_one;
- ret = devm_spi_register_controller(&pdev->dev, host);
- if (ret)
- spi_controller_put(host);
- return ret;
+ return devm_spi_register_controller(&pdev->dev, host);
}
static const struct of_device_id falcon_sflash_match[] = {
diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c
index f6a75f0184c4..451cb4cfdb9c 100644
--- a/drivers/spi/spi-fsi.c
+++ b/drivers/spi/spi-fsi.c
@@ -554,7 +554,7 @@ static int fsi_spi_probe(struct fsi_device *fsi)
if (of_property_read_u32(np, "reg", &base))
continue;
- ctlr = spi_alloc_host(dev, sizeof(*ctx));
+ ctlr = devm_spi_alloc_host(dev, sizeof(*ctx));
if (!ctlr)
break;
@@ -571,9 +571,9 @@ static int fsi_spi_probe(struct fsi_device *fsi)
rc = devm_spi_register_controller(dev, ctlr);
if (rc)
- spi_controller_put(ctlr);
- else
- num_controllers_registered++;
+ continue;
+
+ num_controllers_registered++;
}
if (!num_controllers_registered)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9f2a7b8163b1..019d05cdefe6 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1715,6 +1715,8 @@ static void dspi_remove(struct platform_device *pdev)
dspi_release_dma(dspi);
if (dspi->irq)
free_irq(dspi->irq, dspi);
+
+ spi_controller_put(dspi->ctlr);
}
static void dspi_shutdown(struct platform_device *pdev)
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 45b9974ae911..1341bdd7db75 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -667,7 +667,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
struct fsl_espi *espi;
int ret;
- host = spi_alloc_host(dev, sizeof(struct fsl_espi));
+ host = devm_spi_alloc_host(dev, sizeof(struct fsl_espi));
if (!host)
return -ENOMEM;
@@ -690,8 +690,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
espi->spibrg = fsl_get_sys_freq();
if (espi->spibrg == -1) {
dev_err(dev, "Can't get sys frequency!\n");
- ret = -EINVAL;
- goto err_probe;
+ return -EINVAL;
}
/* determined by clock divider fields DIV16/PM in register SPMODEx */
host->min_speed_hz = DIV_ROUND_UP(espi->spibrg, 4 * 16 * 16);
@@ -700,15 +699,13 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
init_completion(&espi->done);
espi->reg_base = devm_ioremap_resource(dev, mem);
- if (IS_ERR(espi->reg_base)) {
- ret = PTR_ERR(espi->reg_base);
- goto err_probe;
- }
+ if (IS_ERR(espi->reg_base))
+ return PTR_ERR(espi->reg_base);
/* Register for SPI Interrupt */
ret = devm_request_irq(dev, irq, fsl_espi_irq, 0, "fsl_espi", espi);
if (ret)
- goto err_probe;
+ return ret;
fsl_espi_init_regs(dev, true);
@@ -732,8 +729,7 @@ err_pm:
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
-err_probe:
- spi_controller_put(host);
+
return ret;
}
@@ -760,7 +756,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
unsigned int irq, num_cs;
int ret;
- if (of_property_read_bool(np, "mode")) {
+ if (of_property_present(np, "mode")) {
dev_err(dev, "mode property is not supported on ESPI!\n");
return -EINVAL;
}
@@ -784,13 +780,9 @@ static void of_fsl_espi_remove(struct platform_device *dev)
{
struct spi_controller *host = platform_get_drvdata(dev);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_disable(&dev->dev);
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index e201309f8aae..e14753144e19 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -647,7 +647,7 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
tx->sgl, tx->nents, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx) {
- dmaengine_terminate_all(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
return -EINVAL;
}
@@ -668,8 +668,8 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
transfer_timeout);
if (!time_left) {
dev_err(fsl_lpspi->dev, "I/O Error in DMA TX\n");
- dmaengine_terminate_all(controller->dma_tx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
fsl_lpspi_reset(fsl_lpspi);
return -ETIMEDOUT;
}
@@ -678,8 +678,8 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
transfer_timeout);
if (!time_left) {
dev_err(fsl_lpspi->dev, "I/O Error in DMA RX\n");
- dmaengine_terminate_all(controller->dma_tx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
fsl_lpspi_reset(fsl_lpspi);
return -ETIMEDOUT;
}
@@ -688,8 +688,8 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
fsl_lpspi->target_aborted) {
dev_dbg(fsl_lpspi->dev,
"I/O Error in DMA TX interrupted\n");
- dmaengine_terminate_all(controller->dma_tx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
fsl_lpspi_reset(fsl_lpspi);
return -EINTR;
}
@@ -698,8 +698,8 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
fsl_lpspi->target_aborted) {
dev_dbg(fsl_lpspi->dev,
"I/O Error in DMA RX interrupted\n");
- dmaengine_terminate_all(controller->dma_tx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
fsl_lpspi_reset(fsl_lpspi);
return -EINTR;
}
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index 1252c41c206f..e45816ef7b65 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -535,7 +535,7 @@ static struct spi_controller *fsl_spi_probe(struct device *dev,
u32 regval;
int ret = 0;
- host = spi_alloc_host(dev, sizeof(struct mpc8xxx_spi));
+ host = devm_spi_alloc_host(dev, sizeof(struct mpc8xxx_spi));
if (host == NULL) {
ret = -ENOMEM;
goto err;
@@ -559,7 +559,7 @@ static struct spi_controller *fsl_spi_probe(struct device *dev,
ret = fsl_spi_cpm_init(mpc8xxx_spi);
if (ret)
- goto err_cpm_init;
+ goto err;
mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem);
if (IS_ERR(mpc8xxx_spi->reg_base)) {
@@ -625,8 +625,6 @@ static struct spi_controller *fsl_spi_probe(struct device *dev,
err_probe:
fsl_spi_cpm_free(mpc8xxx_spi);
-err_cpm_init:
- spi_controller_put(host);
err:
return ERR_PTR(ret);
}
@@ -705,13 +703,9 @@ static void of_fsl_spi_remove(struct platform_device *ofdev)
struct spi_controller *host = platform_get_drvdata(ofdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
fsl_spi_cpm_free(mpc8xxx_spi);
-
- spi_controller_put(host);
}
static struct platform_driver of_fsl_spi_driver = {
@@ -757,13 +751,9 @@ static void plat_mpc8xxx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
fsl_spi_cpm_free(mpc8xxx_spi);
-
- spi_controller_put(host);
}
MODULE_ALIAS("platform:mpc8xxx_spi");
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 23c6d3a37341..26e723cfea61 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
+#define CREATE_TRACE_POINTS
+#include <trace/events/qcom_geni_spi.h>
+
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
@@ -332,6 +335,9 @@ static int geni_spi_set_clock_and_bw(struct spi_geni_master *mas,
writel(clk_sel, se->base + SE_GENI_CLK_SEL);
writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG);
+ trace_geni_spi_clk_cfg(mas->dev, clk_hz, mas->cur_sclk_hz, idx, div,
+ mas->cur_bits_per_word);
+
/* Set BW quota for CPU as driver supports FIFO mode only. */
se->icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(mas->cur_speed_hz);
ret = geni_icc_set_bw(se);
@@ -366,6 +372,9 @@ static int setup_fifo_params(struct spi_device *spi_slv,
if ((mode_changed & SPI_CS_HIGH) || (cs_changed && (spi_slv->mode & SPI_CS_HIGH)))
writel((spi_slv->mode & SPI_CS_HIGH) ? BIT(chipselect) : 0, se->base + SE_SPI_DEMUX_OUTPUT_INV);
+ trace_geni_spi_setup_params(mas->dev, chipselect, spi_slv->mode,
+ mode_changed, cs_changed);
+
return 0;
}
@@ -872,6 +881,8 @@ static int setup_se_xfer(struct spi_transfer *xfer,
spin_lock_irq(&mas->lock);
geni_se_setup_m_cmd(se, m_cmd, m_params);
+ trace_geni_spi_transfer(mas->dev, len, m_cmd);
+
if (mas->cur_xfer_mode == GENI_SE_DMA) {
if (m_cmd & SPI_RX_ONLY)
geni_se_rx_init_dma(se, sg_dma_address(xfer->rx_sg.sgl),
@@ -926,6 +937,8 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
if (!m_irq && !dma_tx_status && !dma_rx_status)
return IRQ_NONE;
+ trace_geni_spi_irq(mas->dev, m_irq, dma_tx_status, dma_rx_status);
+
if (m_irq & (M_CMD_OVERRUN_EN | M_ILLEGAL_CMD_EN | M_CMD_FAILURE_EN |
M_RX_FIFO_RD_ERR_EN | M_RX_FIFO_WR_ERR_EN |
M_TX_FIFO_RD_ERR_EN | M_TX_FIFO_WR_ERR_EN))
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c
index 046bd894040b..30fcdb5028dc 100644
--- a/drivers/spi/spi-hisi-kunpeng.c
+++ b/drivers/spi/spi-hisi-kunpeng.c
@@ -463,6 +463,7 @@ static int hisi_spi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct spi_controller *host;
struct hisi_spi *hs;
+ u32 num_cs;
int ret, irq;
irq = platform_get_irq(pdev, 0);
@@ -495,10 +496,11 @@ static int hisi_spi_probe(struct platform_device *pdev)
if (host->max_speed_hz == 0)
return dev_err_probe(dev, -EINVAL, "spi-max-frequency can't be 0\n");
- ret = device_property_read_u16(dev, "num-cs",
- &host->num_chipselect);
+ ret = device_property_read_u32(dev, "num-cs", &num_cs);
if (ret)
host->num_chipselect = DEFAULT_NUM_CS;
+ else
+ host->num_chipselect = num_cs;
host->use_gpio_descriptors = true;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
@@ -520,10 +522,8 @@ static int hisi_spi_probe(struct platform_device *pdev)
}
ret = spi_register_controller(host);
- if (ret) {
- dev_err(dev, "failed to register spi host, ret=%d\n", ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register spi host\n");
if (hisi_spi_debugfs_init(hs))
dev_info(dev, "failed to create debugfs dir\n");
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index b2af2eed197f..eeeb86381862 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -436,7 +436,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
u32 version, glb_config;
int ret;
- ctlr = spi_alloc_host(&pdev->dev, sizeof(*host));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*host));
if (!ctlr)
return -ENOMEM;
@@ -451,16 +451,12 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
host->regbase = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(host->regbase)) {
- ret = PTR_ERR(host->regbase);
- goto err_put_host;
- }
+ if (IS_ERR(host->regbase))
+ return PTR_ERR(host->regbase);
host->irq = platform_get_irq_optional(pdev, 0);
- if (host->irq == -EPROBE_DEFER) {
- ret = -EPROBE_DEFER;
- goto err_put_host;
- }
+ if (host->irq == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
hisi_sfc_v3xx_disable_int(host);
@@ -501,16 +497,12 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
ret = devm_spi_register_controller(dev, ctlr);
if (ret)
- goto err_put_host;
+ return ret;
dev_info(&pdev->dev, "hw version 0x%x, %s mode.\n",
version, host->irq ? "irq" : "polling");
return 0;
-
-err_put_host:
- spi_controller_put(ctlr);
- return ret;
}
static const struct acpi_device_id hisi_sfc_v3xx_acpi_ids[] = {
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index 57625a3ce2f2..aec724e3f824 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -530,7 +530,7 @@ static int img_spfi_probe(struct platform_device *pdev)
int ret;
u32 max_speed_hz;
- host = spi_alloc_host(&pdev->dev, sizeof(*spfi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spfi));
if (!host)
return -ENOMEM;
platform_set_drvdata(pdev, host);
@@ -541,36 +541,32 @@ static int img_spfi_probe(struct platform_device *pdev)
spin_lock_init(&spfi->lock);
spfi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(spfi->regs)) {
- ret = PTR_ERR(spfi->regs);
- goto put_spi;
- }
+ if (IS_ERR(spfi->regs))
+ return PTR_ERR(spfi->regs);
+
spfi->phys = res->start;
spfi->irq = platform_get_irq(pdev, 0);
- if (spfi->irq < 0) {
- ret = spfi->irq;
- goto put_spi;
- }
+ if (spfi->irq < 0)
+ return spfi->irq;
+
ret = devm_request_irq(spfi->dev, spfi->irq, img_spfi_irq,
IRQ_TYPE_LEVEL_HIGH, dev_name(spfi->dev), spfi);
if (ret)
- goto put_spi;
+ return ret;
spfi->sys_clk = devm_clk_get(spfi->dev, "sys");
- if (IS_ERR(spfi->sys_clk)) {
- ret = PTR_ERR(spfi->sys_clk);
- goto put_spi;
- }
+ if (IS_ERR(spfi->sys_clk))
+ return PTR_ERR(spfi->sys_clk);
+
spfi->spfi_clk = devm_clk_get(spfi->dev, "spfi");
- if (IS_ERR(spfi->spfi_clk)) {
- ret = PTR_ERR(spfi->spfi_clk);
- goto put_spi;
- }
+ if (IS_ERR(spfi->spfi_clk))
+ return PTR_ERR(spfi->spfi_clk);
ret = clk_prepare_enable(spfi->sys_clk);
if (ret)
- goto put_spi;
+ return ret;
+
ret = clk_prepare_enable(spfi->spfi_clk);
if (ret)
goto disable_pclk;
@@ -658,8 +654,6 @@ disable_pm:
clk_disable_unprepare(spfi->spfi_clk);
disable_pclk:
clk_disable_unprepare(spfi->sys_clk);
-put_spi:
- spi_controller_put(host);
return ret;
}
@@ -669,8 +663,6 @@ static void img_spfi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
if (spfi->tx_ch)
@@ -683,8 +675,6 @@ static void img_spfi_remove(struct platform_device *pdev)
clk_disable_unprepare(spfi->spfi_clk);
clk_disable_unprepare(spfi->sys_clk);
}
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 480d1e8b281f..ae9912905c67 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -1774,8 +1774,8 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx,
transfer_timeout);
if (!time_left) {
dev_err(spi_imx->dev, "I/O Error in DMA TX\n");
- dmaengine_terminate_all(controller->dma_tx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
return -ETIMEDOUT;
}
@@ -1784,7 +1784,7 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx,
if (!time_left) {
dev_err(&controller->dev, "I/O Error in DMA RX\n");
spi_imx->devtype_data->reset(spi_imx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_rx);
return -ETIMEDOUT;
}
} else {
@@ -1793,15 +1793,15 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx,
if (wait_for_completion_interruptible(&spi_imx->dma_tx_completion) ||
READ_ONCE(spi_imx->target_aborted)) {
dev_dbg(spi_imx->dev, "I/O Error in DMA TX interrupted\n");
- dmaengine_terminate_all(controller->dma_tx);
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_rx);
return -EINTR;
}
if (wait_for_completion_interruptible(&spi_imx->dma_rx_completion) ||
READ_ONCE(spi_imx->target_aborted)) {
dev_dbg(spi_imx->dev, "I/O Error in DMA RX interrupted\n");
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_rx);
return -EINTR;
}
@@ -1818,9 +1818,9 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx,
return 0;
dmaengine_terminate_tx:
- dmaengine_terminate_all(controller->dma_tx);
+ dmaengine_terminate_sync(controller->dma_tx);
dmaengine_terminate_rx:
- dmaengine_terminate_all(controller->dma_rx);
+ dmaengine_terminate_sync(controller->dma_rx);
return -EINVAL;
}
diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c
index d8ef8f89330a..8c429c832ddd 100644
--- a/drivers/spi/spi-intel-pci.c
+++ b/drivers/spi/spi-intel-pci.c
@@ -66,39 +66,39 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
}
static const struct pci_device_id intel_spi_pci_ids[] = {
- { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x38a4), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0x4d23), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x5825), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x6e24), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x7723), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x7f24), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x9d24), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0x9da4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info },
- { PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xd323), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info },
- { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x02a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x06a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x18e0), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x19e0), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x1bca), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x34a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x38a4), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x43a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x4b24), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x4d23), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x4da4), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x51a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x54a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x5794), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x5825), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x6e24), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x7723), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x7a24), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x7aa4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x7e23), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x7f24), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x9d24), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0x9da4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa0a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa1a4), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0xa224), .driver_data = (unsigned long)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0xa2a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa324), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa3a4), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa823), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xd323), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xe323), .driver_data = (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xe423), .driver_data = (unsigned long)&cnl_info },
{ },
};
MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
index 1775ad39e633..7494b921a743 100644
--- a/drivers/spi/spi-intel.c
+++ b/drivers/spi/spi-intel.c
@@ -814,7 +814,7 @@ static int intel_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
struct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);
const struct intel_spi_mem_op *iop;
- iop = intel_spi_match_mem_op(ispi, &desc->info.op_tmpl);
+ iop = intel_spi_match_mem_op(ispi, desc->info.op_tmpl);
if (!iop)
return -EOPNOTSUPP;
@@ -827,7 +827,7 @@ static ssize_t intel_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs,
{
struct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);
const struct intel_spi_mem_op *iop = desc->priv;
- struct spi_mem_op op = desc->info.op_tmpl;
+ struct spi_mem_op op = *desc->info.op_tmpl;
int ret;
/* Fill in the gaps */
@@ -844,7 +844,7 @@ static ssize_t intel_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs
{
struct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);
const struct intel_spi_mem_op *iop = desc->priv;
- struct spi_mem_op op = desc->info.op_tmpl;
+ struct spi_mem_op op = *desc->info.op_tmpl;
int ret;
op.addr.val = offs;
diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c
index e37ca22e04ba..a75cd61ec7a3 100644
--- a/drivers/spi/spi-jcore.c
+++ b/drivers/spi/spi-jcore.c
@@ -146,11 +146,10 @@ static int jcore_spi_probe(struct platform_device *pdev)
struct resource *res;
u32 clock_freq;
struct clk *clk;
- int err = -ENODEV;
- host = spi_alloc_host(&pdev->dev, sizeof(struct jcore_spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct jcore_spi));
if (!host)
- return err;
+ return -ENOMEM;
/* Setup the host state. */
host->num_chipselect = 3;
@@ -167,14 +166,14 @@ static int jcore_spi_probe(struct platform_device *pdev)
/* Find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
- goto exit_busy;
+ return -EBUSY;
if (!devm_request_mem_region(&pdev->dev, res->start,
resource_size(res), pdev->name))
- goto exit_busy;
+ return -EBUSY;
hw->base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!hw->base)
- goto exit_busy;
+ return -EBUSY;
/*
* The SPI clock rate controlled via a configurable clock divider
@@ -200,17 +199,7 @@ static int jcore_spi_probe(struct platform_device *pdev)
jcore_spi_baudrate(hw, 400000);
/* Register our spi controller */
- err = devm_spi_register_controller(&pdev->dev, host);
- if (err)
- goto exit;
-
- return 0;
-
-exit_busy:
- err = -EBUSY;
-exit:
- spi_controller_put(host);
- return err;
+ return devm_spi_register_controller(&pdev->dev, host);
}
static const struct of_device_id jcore_spi_of_match[] = {
diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c
index 75b9af8cb5db..ecae50a50b14 100644
--- a/drivers/spi/spi-lantiq-ssc.c
+++ b/drivers/spi/spi-lantiq-ssc.c
@@ -913,7 +913,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
hwcfg = of_device_get_match_data(dev);
- host = spi_alloc_host(dev, sizeof(struct lantiq_ssc_spi));
+ host = devm_spi_alloc_host(dev, sizeof(struct lantiq_ssc_spi));
if (!host)
return -ENOMEM;
@@ -923,20 +923,16 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
spi->hwcfg = hwcfg;
platform_set_drvdata(pdev, spi);
spi->regbase = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(spi->regbase)) {
- err = PTR_ERR(spi->regbase);
- goto err_host_put;
- }
+ if (IS_ERR(spi->regbase))
+ return PTR_ERR(spi->regbase);
err = hwcfg->cfg_irq(pdev, spi);
if (err)
- goto err_host_put;
+ return err;
spi->spi_clk = devm_clk_get_enabled(dev, "gate");
- if (IS_ERR(spi->spi_clk)) {
- err = PTR_ERR(spi->spi_clk);
- goto err_host_put;
- }
+ if (IS_ERR(spi->spi_clk))
+ return PTR_ERR(spi->spi_clk);
/*
* Use the old clk_get_fpi() function on Lantiq platform, till it
@@ -947,10 +943,8 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
#else
spi->fpi_clk = clk_get(dev, "freq");
#endif
- if (IS_ERR(spi->fpi_clk)) {
- err = PTR_ERR(spi->fpi_clk);
- goto err_host_put;
- }
+ if (IS_ERR(spi->fpi_clk))
+ return PTR_ERR(spi->fpi_clk);
num_cs = 8;
of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
@@ -1006,8 +1000,6 @@ err_wq_destroy:
destroy_workqueue(spi->wq);
err_clk_put:
clk_put(spi->fpi_clk);
-err_host_put:
- spi_controller_put(host);
return err;
}
@@ -1016,8 +1008,6 @@ static void lantiq_ssc_remove(struct platform_device *pdev)
{
struct lantiq_ssc_spi *spi = platform_get_drvdata(pdev);
- spi_controller_get(spi->host);
-
spi_unregister_controller(spi->host);
lantiq_ssc_writel(spi, 0, LTQ_SPI_IRNEN);
@@ -1028,8 +1018,6 @@ static void lantiq_ssc_remove(struct platform_device *pdev)
destroy_workqueue(spi->wq);
clk_put(spi->fpi_clk);
-
- spi_controller_put(spi->host);
}
static struct platform_driver lantiq_ssc_driver = {
diff --git a/drivers/spi/spi-lp8841-rtc.c b/drivers/spi/spi-lp8841-rtc.c
index e466866d5e80..b2546a3a9eaa 100644
--- a/drivers/spi/spi-lp8841-rtc.c
+++ b/drivers/spi/spi-lp8841-rtc.c
@@ -185,7 +185,7 @@ spi_lp8841_rtc_probe(struct platform_device *pdev)
struct spi_controller *host;
struct spi_lp8841_rtc *data;
- host = spi_alloc_host(&pdev->dev, sizeof(*data));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*data));
if (!host)
return -ENOMEM;
platform_set_drvdata(pdev, host);
@@ -199,8 +199,6 @@ spi_lp8841_rtc_probe(struct platform_device *pdev)
host->set_cs = spi_lp8841_rtc_set_cs;
host->transfer_one = spi_lp8841_rtc_transfer_one;
host->bits_per_word_mask = SPI_BPW_MASK(8);
-#ifdef CONFIG_OF
-#endif
data = spi_controller_get_devdata(host);
@@ -208,23 +206,17 @@ spi_lp8841_rtc_probe(struct platform_device *pdev)
ret = PTR_ERR_OR_ZERO(data->iomem);
if (ret) {
dev_err(&pdev->dev, "failed to get IO address\n");
- goto err_put_host;
+ return ret;
}
/* register with the SPI framework */
ret = devm_spi_register_controller(&pdev->dev, host);
if (ret) {
dev_err(&pdev->dev, "cannot register spi host\n");
- goto err_put_host;
+ return ret;
}
- return ret;
-
-
-err_put_host:
- spi_controller_put(host);
-
- return ret;
+ return 0;
}
MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 93266848c6df..a88b9f038356 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -654,7 +654,7 @@ EXPORT_SYMBOL_GPL(spi_mem_calc_op_duration);
static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, void *buf)
{
- struct spi_mem_op op = desc->info.op_tmpl;
+ struct spi_mem_op op = *desc->info.op_tmpl;
int ret;
op.addr.val = desc->info.offset + offs;
@@ -674,7 +674,7 @@ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, const void *buf)
{
- struct spi_mem_op op = desc->info.op_tmpl;
+ struct spi_mem_op op = *desc->info.op_tmpl;
int ret;
op.addr.val = desc->info.offset + offs;
@@ -713,19 +713,37 @@ spi_mem_dirmap_create(struct spi_mem *mem,
int ret = -ENOTSUPP;
/* Make sure the number of address cycles is between 1 and 8 bytes. */
- if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
+ if (!info->primary_op_tmpl.addr.nbytes || info->primary_op_tmpl.addr.nbytes > 8)
return ERR_PTR(-EINVAL);
/* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
- if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
+ if (info->primary_op_tmpl.data.dir == SPI_MEM_NO_DATA)
return ERR_PTR(-EINVAL);
+ /* Apply similar constraints to the secondary template */
+ if (info->secondary_op_tmpl.cmd.opcode) {
+ if (!info->secondary_op_tmpl.addr.nbytes ||
+ info->secondary_op_tmpl.addr.nbytes > 8)
+ return ERR_PTR(-EINVAL);
+
+ if (info->secondary_op_tmpl.data.dir == SPI_MEM_NO_DATA)
+ return ERR_PTR(-EINVAL);
+
+ if (!spi_mem_supports_op(mem, &info->secondary_op_tmpl))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ if (ctlr->mem_ops && ctlr->mem_ops->dirmap_create &&
+ !spi_mem_controller_is_capable(ctlr, secondary_op_tmpl))
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
desc = kzalloc_obj(*desc);
if (!desc)
return ERR_PTR(-ENOMEM);
desc->mem = mem;
desc->info = *info;
+ desc->info.op_tmpl = &desc->info.primary_op_tmpl;
if (ctlr->mem_ops && ctlr->mem_ops->dirmap_create) {
ret = spi_mem_access_start(mem);
if (ret) {
@@ -740,7 +758,7 @@ spi_mem_dirmap_create(struct spi_mem *mem,
if (ret) {
desc->nodirmap = true;
- if (!spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))
+ if (!spi_mem_supports_op(desc->mem, &desc->info.primary_op_tmpl))
ret = -EOPNOTSUPP;
else
ret = 0;
@@ -864,7 +882,7 @@ ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
struct spi_controller *ctlr = desc->mem->spi->controller;
ssize_t ret;
- if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
+ if (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN)
return -EINVAL;
if (!len)
@@ -910,7 +928,7 @@ ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
struct spi_controller *ctlr = desc->mem->spi->controller;
ssize_t ret;
- if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_OUT)
+ if (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_OUT)
return -EINVAL;
if (!len)
diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index b80f9f457b66..fa2d2db2d6e7 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -539,9 +539,8 @@ static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc,
conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG);
/* Setup word width */
- conf &= ~SPICC_BITLENGTH_MASK;
- conf |= FIELD_PREP(SPICC_BITLENGTH_MASK,
- (spicc->bytes_per_word << 3) - 1);
+ FIELD_MODIFY(SPICC_BITLENGTH_MASK, &conf,
+ (spicc->bytes_per_word << 3) - 1);
/* Ignore if unchanged */
if (conf != conf_orig)
@@ -982,7 +981,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
struct meson_spicc_device *spicc;
int ret, irq;
- host = spi_alloc_host(&pdev->dev, sizeof(*spicc));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spicc));
if (!host) {
dev_err(&pdev->dev, "host allocation failed\n");
return -ENOMEM;
@@ -993,8 +992,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
spicc->data = of_device_get_match_data(&pdev->dev);
if (!spicc->data) {
dev_err(&pdev->dev, "failed to get match data\n");
- ret = -EINVAL;
- goto out_host;
+ return -EINVAL;
}
spicc->pdev = pdev;
@@ -1005,8 +1003,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
spicc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(spicc->base)) {
dev_err(&pdev->dev, "io resource mapping failed\n");
- ret = PTR_ERR(spicc->base);
- goto out_host;
+ return PTR_ERR(spicc->base);
}
/* Set master mode and enable controller */
@@ -1017,39 +1014,33 @@ static int meson_spicc_probe(struct platform_device *pdev)
writel_relaxed(0, spicc->base + SPICC_INTREG);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto out_host;
- }
+ if (irq < 0)
+ return irq;
ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq,
0, NULL, spicc);
if (ret) {
dev_err(&pdev->dev, "irq request failed\n");
- goto out_host;
+ return ret;
}
spicc->core = devm_clk_get_enabled(&pdev->dev, "core");
if (IS_ERR(spicc->core)) {
dev_err(&pdev->dev, "core clock request failed\n");
- ret = PTR_ERR(spicc->core);
- goto out_host;
+ return PTR_ERR(spicc->core);
}
if (spicc->data->has_pclk) {
spicc->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
if (IS_ERR(spicc->pclk)) {
dev_err(&pdev->dev, "pclk clock request failed\n");
- ret = PTR_ERR(spicc->pclk);
- goto out_host;
+ return PTR_ERR(spicc->pclk);
}
}
spicc->pinctrl = devm_pinctrl_get(&pdev->dev);
- if (IS_ERR(spicc->pinctrl)) {
- ret = PTR_ERR(spicc->pinctrl);
- goto out_host;
- }
+ if (IS_ERR(spicc->pinctrl))
+ return PTR_ERR(spicc->pinctrl);
device_reset_optional(&pdev->dev);
@@ -1070,43 +1061,34 @@ static int meson_spicc_probe(struct platform_device *pdev)
ret = meson_spicc_pow2_clk_init(spicc);
if (ret) {
dev_err(&pdev->dev, "pow2 clock registration failed\n");
- goto out_host;
+ return ret;
}
if (spicc->data->has_enhance_clk_div) {
ret = meson_spicc_enh_clk_init(spicc);
if (ret) {
dev_err(&pdev->dev, "clock registration failed\n");
- goto out_host;
+ return ret;
}
}
ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "spi registration failed\n");
- goto out_host;
+ return ret;
}
return 0;
-
-out_host:
- spi_controller_put(host);
-
- return ret;
}
static void meson_spicc_remove(struct platform_device *pdev)
{
struct meson_spicc_device *spicc = platform_get_drvdata(pdev);
- spi_controller_get(spicc->host);
-
spi_unregister_controller(spicc->host);
/* Disable SPI */
writel(0, spicc->base + SPICC_CONREG);
-
- spi_controller_put(spicc->host);
}
static const struct meson_spicc_data meson_spicc_gx_data = {
diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c
index b818950a8cb7..e36aa94bbdae 100644
--- a/drivers/spi/spi-meson-spifc.c
+++ b/drivers/spi/spi-meson-spifc.c
@@ -288,9 +288,9 @@ static int meson_spifc_probe(struct platform_device *pdev)
struct meson_spifc *spifc;
void __iomem *base;
unsigned int rate;
- int ret = 0;
+ int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(struct meson_spifc));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct meson_spifc));
if (!host)
return -ENOMEM;
@@ -300,23 +300,18 @@ static int meson_spifc_probe(struct platform_device *pdev)
spifc->dev = &pdev->dev;
base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(base)) {
- ret = PTR_ERR(base);
- goto out_err;
- }
+ if (IS_ERR(base))
+ return PTR_ERR(base);
spifc->regmap = devm_regmap_init_mmio(spifc->dev, base,
&spifc_regmap_config);
- if (IS_ERR(spifc->regmap)) {
- ret = PTR_ERR(spifc->regmap);
- goto out_err;
- }
+ if (IS_ERR(spifc->regmap))
+ return PTR_ERR(spifc->regmap);
spifc->clk = devm_clk_get_enabled(spifc->dev, NULL);
if (IS_ERR(spifc->clk)) {
dev_err(spifc->dev, "missing clock\n");
- ret = PTR_ERR(spifc->clk);
- goto out_err;
+ return PTR_ERR(spifc->clk);
}
rate = clk_get_rate(spifc->clk);
@@ -342,8 +337,7 @@ static int meson_spifc_probe(struct platform_device *pdev)
return 0;
out_pm:
pm_runtime_disable(spifc->dev);
-out_err:
- spi_controller_put(host);
+
return ret;
}
@@ -351,6 +345,7 @@ static void meson_spifc_remove(struct platform_device *pdev)
{
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microchip-core-qspi.c
index 4dee0fea1df8..c0ea65014d2e 100644
--- a/drivers/spi/spi-microchip-core-qspi.c
+++ b/drivers/spi/spi-microchip-core-qspi.c
@@ -99,7 +99,6 @@
#define REG_IEN (0x0c)
#define REG_STATUS (0x10)
#define REG_DIRECT_ACCESS (0x14)
-#define REG_UPPER_ACCESS (0x18)
#define REG_RX_DATA (0x40)
#define REG_TX_DATA (0x44)
#define REG_X4_RX_DATA (0x48)
@@ -632,7 +631,7 @@ static int mchp_coreqspi_prepare_message(struct spi_controller *ctlr, struct spi
ret = mchp_coreqspi_wait_for_ready(qspi);
if (ret) {
mutex_unlock(&qspi->op_lock);
- dev_err(&ctlr->dev, "Timeout waiting on QSPI ready.\n");
+ dev_err(&m->spi->dev, "Timeout waiting on QSPI ready.\n");
return ret;
}
diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c
index 924d820448fb..70d8e17e8c43 100644
--- a/drivers/spi/spi-mpc52xx.c
+++ b/drivers/spi/spi-mpc52xx.c
@@ -472,13 +472,15 @@ static int mpc52xx_spi_probe(struct platform_device *op)
if (ms->irq0 && ms->irq1) {
rc = request_irq(ms->irq0, mpc52xx_spi_irq, 0,
"mpc5200-spi-modf", ms);
- rc |= request_irq(ms->irq1, mpc52xx_spi_irq, 0,
- "mpc5200-spi-spif", ms);
- if (rc) {
- free_irq(ms->irq0, ms);
- free_irq(ms->irq1, ms);
- ms->irq0 = ms->irq1 = 0;
+ if (rc == 0) {
+ rc = request_irq(ms->irq1, mpc52xx_spi_irq, 0,
+ "mpc5200-spi-spif", ms);
+ if (rc)
+ free_irq(ms->irq0, ms);
}
+
+ if (rc)
+ ms->irq0 = ms->irq1 = 0;
} else {
/* operate in polled mode */
ms->irq0 = ms->irq1 = 0;
@@ -498,8 +500,10 @@ static int mpc52xx_spi_probe(struct platform_device *op)
err_register:
dev_err(&ms->host->dev, "initialization failed\n");
- free_irq(ms->irq0, ms);
- free_irq(ms->irq1, ms);
+ if (ms->irq0) {
+ free_irq(ms->irq0, ms);
+ free_irq(ms->irq1, ms);
+ }
cancel_work_sync(&ms->work);
err_gpio:
while (i-- > 0)
@@ -516,14 +520,16 @@ static int mpc52xx_spi_probe(struct platform_device *op)
static void mpc52xx_spi_remove(struct platform_device *op)
{
- struct spi_controller *host = spi_controller_get(platform_get_drvdata(op));
+ struct spi_controller *host = platform_get_drvdata(op);
struct mpc52xx_spi *ms = spi_controller_get_devdata(host);
int i;
spi_unregister_controller(host);
- free_irq(ms->irq0, ms);
- free_irq(ms->irq1, ms);
+ if (ms->irq0) {
+ free_irq(ms->irq0, ms);
+ free_irq(ms->irq1, ms);
+ }
cancel_work_sync(&ms->work);
diff --git a/drivers/spi/spi-mux.c b/drivers/spi/spi-mux.c
index bd122de152c0..08fe1fa32dea 100644
--- a/drivers/spi/spi-mux.c
+++ b/drivers/spi/spi-mux.c
@@ -127,9 +127,8 @@ static int spi_mux_probe(struct spi_device *spi)
{
struct spi_controller *ctlr;
struct spi_mux_priv *priv;
- int ret;
- ctlr = spi_alloc_host(&spi->dev, sizeof(*priv));
+ ctlr = devm_spi_alloc_host(&spi->dev, sizeof(*priv));
if (!ctlr)
return -ENOMEM;
@@ -146,9 +145,8 @@ static int spi_mux_probe(struct spi_device *spi)
priv->mux = devm_mux_control_get(&spi->dev, NULL);
if (IS_ERR(priv->mux)) {
- ret = dev_err_probe(&spi->dev, PTR_ERR(priv->mux),
- "failed to get control-mux\n");
- goto err_put_ctlr;
+ return dev_err_probe(&spi->dev, PTR_ERR(priv->mux),
+ "failed to get control-mux\n");
}
priv->current_cs = SPI_MUX_NO_CS;
@@ -164,16 +162,7 @@ static int spi_mux_probe(struct spi_device *spi)
ctlr->must_async = true;
ctlr->defer_optimize_message = true;
- ret = devm_spi_register_controller(&spi->dev, ctlr);
- if (ret)
- goto err_put_ctlr;
-
- return 0;
-
-err_put_ctlr:
- spi_controller_put(ctlr);
-
- return ret;
+ return devm_spi_register_controller(&spi->dev, ctlr);
}
static const struct spi_device_id spi_mux_id[] = {
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
index b0e7fc828a50..83b688e65284 100644
--- a/drivers/spi/spi-mxic.c
+++ b/drivers/spi/spi-mxic.c
@@ -403,20 +403,20 @@ static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (WARN_ON(offs + desc->info.offset + len > U32_MAX))
return -EINVAL;
- writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl.data.swap16),
+ writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl->data.swap16),
mxic->regs + HC_CFG);
- writel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len),
+ writel(mxic_spi_mem_prep_op_cfg(desc->info.op_tmpl, len),
mxic->regs + LRD_CFG);
writel(desc->info.offset + offs, mxic->regs + LRD_ADDR);
len = min_t(size_t, len, mxic->linear.size);
writel(len, mxic->regs + LRD_RANGE);
- writel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) |
+ writel(LMODE_CMD0(desc->info.op_tmpl->cmd.opcode) |
LMODE_SLV_ACT(spi_get_chipselect(desc->mem->spi, 0)) |
LMODE_EN,
mxic->regs + LRD_CTRL);
- if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) {
+ if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl->data.ecc) {
ret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine,
NAND_PAGE_READ,
mxic->linear.dma + offs);
@@ -448,20 +448,20 @@ static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
if (WARN_ON(offs + desc->info.offset + len > U32_MAX))
return -EINVAL;
- writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl.data.swap16),
+ writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl->data.swap16),
mxic->regs + HC_CFG);
- writel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len),
+ writel(mxic_spi_mem_prep_op_cfg(desc->info.op_tmpl, len),
mxic->regs + LWR_CFG);
writel(desc->info.offset + offs, mxic->regs + LWR_ADDR);
len = min_t(size_t, len, mxic->linear.size);
writel(len, mxic->regs + LWR_RANGE);
- writel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) |
+ writel(LMODE_CMD0(desc->info.op_tmpl->cmd.opcode) |
LMODE_SLV_ACT(spi_get_chipselect(desc->mem->spi, 0)) |
LMODE_EN,
mxic->regs + LWR_CTRL);
- if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) {
+ if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl->data.ecc) {
ret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine,
NAND_PAGE_WRITE,
mxic->linear.dma + offs);
@@ -509,7 +509,7 @@ static int mxic_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)
if (desc->info.offset + desc->info.length > U32_MAX)
return -EINVAL;
- if (!mxic_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))
+ if (!mxic_spi_mem_supports_op(desc->mem, desc->info.op_tmpl))
return -EOPNOTSUPP;
return 0;
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index 0164e04d59a1..fda1d260b296 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -563,7 +563,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
if (ret)
clk_freq = clk_freq_default;
- host = spi_alloc_host(&pdev->dev, sizeof(*spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi));
if (!host)
return -ENOMEM;
@@ -589,13 +589,12 @@ static int mxs_spi_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0,
dev_name(&pdev->dev), ssp);
if (ret)
- goto out_host_free;
+ return ret;
ssp->dmach = dma_request_chan(&pdev->dev, "rx-tx");
if (IS_ERR(ssp->dmach)) {
dev_err(ssp->dev, "Failed to request DMA\n");
- ret = PTR_ERR(ssp->dmach);
- goto out_host_free;
+ return PTR_ERR(ssp->dmach);
}
pm_runtime_enable(ssp->dev);
@@ -635,8 +634,7 @@ out_pm_runtime_disable:
pm_runtime_disable(ssp->dev);
out_dma_release:
dma_release_channel(ssp->dmach);
-out_host_free:
- spi_controller_put(host);
+
return ret;
}
@@ -650,8 +648,6 @@ static void mxs_spi_remove(struct platform_device *pdev)
spi = spi_controller_get_devdata(host);
ssp = &spi->ssp;
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_disable(&pdev->dev);
@@ -659,8 +655,6 @@ static void mxs_spi_remove(struct platform_device *pdev)
mxs_spi_runtime_suspend(&pdev->dev);
dma_release_channel(ssp->dmach);
-
- spi_controller_put(host);
}
static struct platform_driver mxs_spi_driver = {
diff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c
index 6617751009c3..4b825044038b 100644
--- a/drivers/spi/spi-npcm-fiu.c
+++ b/drivers/spi/spi-npcm-fiu.c
@@ -299,11 +299,11 @@ static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,
for (i = 0 ; i < len ; i++)
*(buf_rx + i) = ioread8(src + i);
} else {
- if (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth ||
- desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes ||
- desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode ||
- desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes)
- npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
+ if (desc->info.op_tmpl->addr.buswidth != fiu->drd_op.addr.buswidth ||
+ desc->info.op_tmpl->dummy.nbytes != fiu->drd_op.dummy.nbytes ||
+ desc->info.op_tmpl->cmd.opcode != fiu->drd_op.cmd.opcode ||
+ desc->info.op_tmpl->addr.nbytes != fiu->drd_op.addr.nbytes)
+ npcm_fiu_set_drd(fiu, desc->info.op_tmpl);
memcpy_fromio(buf_rx, src, len);
}
@@ -609,7 +609,7 @@ static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
}
if (!fiu->spix_mode &&
- desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
+ desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT) {
desc->nodirmap = true;
return 0;
}
@@ -644,9 +644,9 @@ static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
NPCM_FIU_CFG_FIU_FIX);
}
- if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
+ if (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_IN) {
if (!fiu->spix_mode)
- npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
+ npcm_fiu_set_drd(fiu, desc->info.op_tmpl);
else
npcm_fiux_set_direct_rd(fiu);
diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
index cffef0a5977d..a437a30d636c 100644
--- a/drivers/spi/spi-npcm-pspi.c
+++ b/drivers/spi/spi-npcm-pspi.c
@@ -345,7 +345,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
int irq;
int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*priv));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*priv));
if (!host)
return -ENOMEM;
@@ -356,21 +356,18 @@ static int npcm_pspi_probe(struct platform_device *pdev)
priv->is_save_param = false;
priv->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->base)) {
- ret = PTR_ERR(priv->base);
- goto out_host_put;
- }
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
priv->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
- ret = PTR_ERR(priv->clk);
- goto out_host_put;
+ return PTR_ERR(priv->clk);
}
ret = clk_prepare_enable(priv->clk);
if (ret)
- goto out_host_put;
+ return ret;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -424,8 +421,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
out_disable_clk:
clk_disable_unprepare(priv->clk);
-out_host_put:
- spi_controller_put(host);
return ret;
}
@@ -434,14 +429,10 @@ static void npcm_pspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct npcm_pspi *priv = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
npcm_pspi_reset_hw(priv);
clk_disable_unprepare(priv->clk);
-
- spi_controller_put(host);
}
static const struct of_device_id npcm_pspi_match[] = {
diff --git a/drivers/spi/spi-nxp-xspi.c b/drivers/spi/spi-nxp-xspi.c
index 385302a6e62f..037eac24e6fd 100644
--- a/drivers/spi/spi-nxp-xspi.c
+++ b/drivers/spi/spi-nxp-xspi.c
@@ -493,9 +493,8 @@ static void nxp_xspi_disable_ddr(struct nxp_xspi *xspi)
writel(reg, base + XSPI_MCR);
reg &= ~XSPI_MCR_DDR_EN;
- reg &= ~XSPI_MCR_DQS_FA_SEL_MASK;
/* Use dummy pad loopback mode to sample data */
- reg |= FIELD_PREP(XSPI_MCR_DQS_FA_SEL_MASK, 0x01);
+ FIELD_MODIFY(XSPI_MCR_DQS_FA_SEL_MASK, &reg, 0x01);
writel(reg, base + XSPI_MCR);
xspi->support_max_rate = 133000000;
@@ -524,15 +523,13 @@ static void nxp_xspi_enable_ddr(struct nxp_xspi *xspi)
writel(reg, base + XSPI_MCR);
reg |= XSPI_MCR_DDR_EN;
- reg &= ~XSPI_MCR_DQS_FA_SEL_MASK;
/* Use external dqs to sample data */
- reg |= FIELD_PREP(XSPI_MCR_DQS_FA_SEL_MASK, 0x03);
+ FIELD_MODIFY(XSPI_MCR_DQS_FA_SEL_MASK, &reg, 0x03);
writel(reg, base + XSPI_MCR);
xspi->support_max_rate = 200000000;
reg = readl(base + XSPI_FLSHCR);
- reg &= ~XSPI_FLSHCR_TDH_MASK;
- reg |= FIELD_PREP(XSPI_FLSHCR_TDH_MASK, 0x01);
+ FIELD_MODIFY(XSPI_FLSHCR_TDH_MASK, &reg, 0x01);
writel(reg, base + XSPI_FLSHCR);
reg = FIELD_PREP(XSPI_SMPR_DLLFSMPFA_MASK, 0x04);
@@ -1096,8 +1093,7 @@ static int nxp_xspi_default_setup(struct nxp_xspi *xspi)
/* Give read/write access right to EENV0 */
reg = readl(base + XSPI_FRAD0_WORD2);
- reg &= ~XSPI_FRAD0_WORD2_MD0ACP_MASK;
- reg |= FIELD_PREP(XSPI_FRAD0_WORD2_MD0ACP_MASK, 0x03);
+ FIELD_MODIFY(XSPI_FRAD0_WORD2_MD0ACP_MASK, &reg, 0x03);
writel(reg, base + XSPI_FRAD0_WORD2);
/* Enable the FRAD check for EENV0 */
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 56b30ff58771..9cc078acc13c 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -22,7 +22,6 @@
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/gcd.h>
#include <linux/spi/spi.h>
@@ -1481,12 +1480,11 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
int status = 0, i;
u32 regs_offset = 0;
struct device_node *node = pdev->dev.of_node;
- const struct of_device_id *match;
if (of_property_read_bool(node, "spi-slave"))
- ctlr = spi_alloc_target(&pdev->dev, sizeof(*mcspi));
+ ctlr = devm_spi_alloc_target(&pdev->dev, sizeof(*mcspi));
else
- ctlr = spi_alloc_host(&pdev->dev, sizeof(*mcspi));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*mcspi));
if (!ctlr)
return -ENOMEM;
@@ -1509,10 +1507,9 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
mcspi = spi_controller_get_devdata(ctlr);
mcspi->ctlr = ctlr;
- match = of_match_device(omap_mcspi_of_match, &pdev->dev);
- if (match) {
+ pdata = of_device_get_match_data(&pdev->dev);
+ if (pdata) {
u32 num_cs = 1; /* default number of chipselect */
- pdata = match->data;
of_property_read_u32(node, "ti,spi-num-cs", &num_cs);
ctlr->num_chipselect = num_cs;
@@ -1530,10 +1527,9 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
}
mcspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
- if (IS_ERR(mcspi->base)) {
- status = PTR_ERR(mcspi->base);
- goto free_ctlr;
- }
+ if (IS_ERR(mcspi->base))
+ return PTR_ERR(mcspi->base);
+
mcspi->phys = r->start + regs_offset;
mcspi->base += regs_offset;
@@ -1544,10 +1540,8 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
mcspi->dma_channels = devm_kcalloc(&pdev->dev, ctlr->num_chipselect,
sizeof(struct omap2_mcspi_dma),
GFP_KERNEL);
- if (mcspi->dma_channels == NULL) {
- status = -ENOMEM;
- goto free_ctlr;
- }
+ if (mcspi->dma_channels == NULL)
+ return -ENOMEM;
for (i = 0; i < ctlr->num_chipselect; i++) {
sprintf(mcspi->dma_channels[i].dma_rx_ch_name, "rx%d", i);
@@ -1556,26 +1550,27 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
status = omap2_mcspi_request_dma(mcspi,
&mcspi->dma_channels[i]);
if (status == -EPROBE_DEFER)
- goto free_ctlr;
+ goto err_release_dma;
}
status = platform_get_irq(pdev, 0);
if (status < 0)
- goto free_ctlr;
+ goto err_release_dma;
+
init_completion(&mcspi->txdone);
status = devm_request_irq(&pdev->dev, status,
omap2_mcspi_irq_handler, 0, pdev->name,
mcspi);
if (status) {
dev_err(&pdev->dev, "Cannot request IRQ");
- goto free_ctlr;
+ goto err_release_dma;
}
mcspi->ref_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
if (IS_ERR(mcspi->ref_clk)) {
status = PTR_ERR(mcspi->ref_clk);
dev_err_probe(&pdev->dev, status, "Failed to get ref_clk");
- goto free_ctlr;
+ goto err_release_dma;
}
if (mcspi->ref_clk)
mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk);
@@ -1590,21 +1585,21 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
status = omap2_mcspi_controller_setup(mcspi);
if (status < 0)
- goto disable_pm;
+ goto err_disable_rpm;
status = spi_register_controller(ctlr);
if (status < 0)
- goto disable_pm;
+ goto err_disable_rpm;
- return status;
+ return 0;
-disable_pm:
+err_disable_rpm:
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-free_ctlr:
+err_release_dma:
omap2_mcspi_release_dma(ctlr);
- spi_controller_put(ctlr);
+
return status;
}
@@ -1613,8 +1608,6 @@ static void omap2_mcspi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr);
- spi_controller_get(ctlr);
-
spi_unregister_controller(ctlr);
omap2_mcspi_release_dma(ctlr);
@@ -1622,8 +1615,6 @@ static void omap2_mcspi_remove(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(mcspi->dev);
pm_runtime_put_sync(mcspi->dev);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(ctlr);
}
/* work with hotplug and coldplug */
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 64bf215c1804..265708a94984 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -651,11 +651,9 @@ static int orion_spi_probe(struct platform_device *pdev)
struct device_node *np;
int status;
- host = spi_alloc_host(&pdev->dev, sizeof(*spi));
- if (host == NULL) {
- dev_dbg(&pdev->dev, "host allocation failed\n");
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi));
+ if (host == NULL)
return -ENOMEM;
- }
if (pdev->id != -1)
host->bus_num = pdev->id;
@@ -689,17 +687,14 @@ static int orion_spi_probe(struct platform_device *pdev)
spi->devdata = devdata;
spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
- if (IS_ERR(spi->clk)) {
- status = PTR_ERR(spi->clk);
- goto out;
- }
+ if (IS_ERR(spi->clk))
+ return PTR_ERR(spi->clk);
/* The following clock is only used by some SoCs */
spi->axi_clk = devm_clk_get(&pdev->dev, "axi");
- if (PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) {
- status = -EPROBE_DEFER;
- goto out;
- }
+ if (PTR_ERR(spi->axi_clk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
if (!IS_ERR(spi->axi_clk))
clk_prepare_enable(spi->axi_clk);
@@ -796,8 +791,7 @@ out_rel_pm:
pm_runtime_dont_use_autosuspend(&pdev->dev);
out_rel_axi_clk:
clk_disable_unprepare(spi->axi_clk);
-out:
- spi_controller_put(host);
+
return status;
}
@@ -807,15 +801,11 @@ static void orion_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct orion_spi *spi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(spi->axi_clk);
- spi_controller_put(host);
-
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
diff --git a/drivers/spi/spi-pci1xxxx.c b/drivers/spi/spi-pci1xxxx.c
index 8577a19705de..af6ed78493e3 100644
--- a/drivers/spi/spi-pci1xxxx.c
+++ b/drivers/spi/spi-pci1xxxx.c
@@ -173,27 +173,27 @@ struct pci1xxxx_spi {
};
static const struct pci_device_id pci1xxxx_spi_pci_id_table[] = {
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, 0x0001), 0, 0, 0x02},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, 0x0002), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, 0x0003), 0, 0, 0x11},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, PCI_ANY_ID), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, 0x0001), 0, 0, 0x02},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, 0x0002), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, 0x0003), 0, 0, 0x11},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, PCI_ANY_ID), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, 0x0001), 0, 0, 0x02},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, 0x0002), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, 0x0003), 0, 0, 0x11},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, PCI_ANY_ID), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, 0x0001), 0, 0, 0x02},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, 0x0002), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, 0x0003), 0, 0, 0x11},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, PCI_ANY_ID), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, 0x0001), 0, 0, 0x02},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, 0x0002), 0, 0, 0x01},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, 0x0003), 0, 0, 0x11},
- { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, PCI_ANY_ID), 0, 0, 0x01},
- { 0, }
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, 0x0001), .driver_data = 0x02 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, 0x0002), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, 0x0003), .driver_data = 0x11 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa004, PCI_ANY_ID, PCI_ANY_ID), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, 0x0001), .driver_data = 0x02 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, 0x0002), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, 0x0003), .driver_data = 0x11 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa014, PCI_ANY_ID, PCI_ANY_ID), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, 0x0001), .driver_data = 0x02 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, 0x0002), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, 0x0003), .driver_data = 0x11 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa024, PCI_ANY_ID, PCI_ANY_ID), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, 0x0001), .driver_data = 0x02 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, 0x0002), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, 0x0003), .driver_data = 0x11 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa034, PCI_ANY_ID, PCI_ANY_ID), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, 0x0001), .driver_data = 0x02 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, 0x0002), .driver_data = 0x01 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, 0x0003), .driver_data = 0x11 },
+ { PCI_DEVICE_SUB(VENDOR_ID_MCHP, 0xa044, PCI_ANY_ID, PCI_ANY_ID), .driver_data = 0x01 },
+ { }
};
MODULE_DEVICE_TABLE(pci, pci1xxxx_spi_pci_id_table);
diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c
index 41662992dbe5..5d3921e29461 100644
--- a/drivers/spi/spi-pic32-sqi.c
+++ b/drivers/spi/spi-pic32-sqi.c
@@ -572,7 +572,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
struct pic32_sqi *sqi;
int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*sqi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*sqi));
if (!host)
return -ENOMEM;
@@ -580,31 +580,25 @@ static int pic32_sqi_probe(struct platform_device *pdev)
sqi->host = host;
sqi->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(sqi->regs)) {
- ret = PTR_ERR(sqi->regs);
- goto err_free_host;
- }
+ if (IS_ERR(sqi->regs))
+ return PTR_ERR(sqi->regs);
/* irq */
sqi->irq = platform_get_irq(pdev, 0);
- if (sqi->irq < 0) {
- ret = sqi->irq;
- goto err_free_host;
- }
+ if (sqi->irq < 0)
+ return sqi->irq;
/* clocks */
sqi->sys_clk = devm_clk_get_enabled(&pdev->dev, "reg_ck");
if (IS_ERR(sqi->sys_clk)) {
- ret = PTR_ERR(sqi->sys_clk);
dev_err(&pdev->dev, "no sys_clk ?\n");
- goto err_free_host;
+ return PTR_ERR(sqi->sys_clk);
}
sqi->base_clk = devm_clk_get_enabled(&pdev->dev, "spi_ck");
if (IS_ERR(sqi->base_clk)) {
- ret = PTR_ERR(sqi->base_clk);
dev_err(&pdev->dev, "no base clk ?\n");
- goto err_free_host;
+ return PTR_ERR(sqi->base_clk);
}
init_completion(&sqi->xfer_done);
@@ -616,7 +610,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
ret = ring_desc_ring_alloc(sqi);
if (ret) {
dev_err(&pdev->dev, "ring alloc failed\n");
- goto err_free_host;
+ return ret;
}
/* install irq handlers */
@@ -656,8 +650,6 @@ static int pic32_sqi_probe(struct platform_device *pdev)
err_free_ring:
ring_desc_ring_free(sqi);
-err_free_host:
- spi_controller_put(host);
return ret;
}
@@ -665,15 +657,11 @@ static void pic32_sqi_remove(struct platform_device *pdev)
{
struct pic32_sqi *sqi = platform_get_drvdata(pdev);
- spi_controller_get(sqi->host);
-
spi_unregister_controller(sqi->host);
/* release resources */
free_irq(sqi->irq, sqi);
ring_desc_ring_free(sqi);
-
- spi_controller_put(sqi->host);
}
static const struct of_device_id pic32_sqi_of_ids[] = {
diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c
index 70427e529945..972128271e4b 100644
--- a/drivers/spi/spi-pic32.c
+++ b/drivers/spi/spi-pic32.c
@@ -752,7 +752,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
struct pic32_spi *pic32s;
int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*pic32s));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*pic32s));
if (!host)
return -ENOMEM;
@@ -761,7 +761,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
ret = pic32_spi_hw_probe(pdev, pic32s);
if (ret)
- goto err_host;
+ return ret;
host->dev.of_node = pdev->dev.of_node;
host->mode_bits = SPI_MODE_3 | SPI_MODE_0 | SPI_CS_HIGH;
@@ -833,8 +833,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
err_bailout:
pic32_spi_dma_unprep(pic32s);
-err_host:
- spi_controller_put(host);
+
return ret;
}
@@ -842,14 +841,10 @@ static void pic32_spi_remove(struct platform_device *pdev)
{
struct pic32_spi *pic32s = platform_get_drvdata(pdev);
- spi_controller_get(pic32s->host);
-
spi_unregister_controller(pic32s->host);
pic32_spi_disable(pic32s);
pic32_spi_dma_unprep(pic32s);
-
- spi_controller_put(pic32s->host);
}
static const struct of_device_id pic32_spi_of_match[] = {
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 9c0211f94fd0..95652df5fd09 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1868,7 +1868,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
}
/* Allocate host with space for data */
- host = spi_alloc_host(dev, sizeof(struct pl022));
+ host = devm_spi_alloc_host(dev, sizeof(struct pl022));
if (host == NULL) {
dev_err(&adev->dev, "probe - cannot alloc SPI host\n");
return -ENOMEM;
@@ -1907,7 +1907,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
status = amba_request_regions(adev, NULL);
if (status)
- goto err_no_ioregion;
+ return status;
pl022->phybase = adev->res.start;
pl022->virtbase = devm_ioremap(dev, adev->res.start,
@@ -1984,8 +1984,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
err_no_clk:
err_no_ioremap:
amba_release_regions(adev);
- err_no_ioregion:
- spi_controller_put(host);
+
return status;
}
@@ -1997,8 +1996,6 @@ pl022_remove(struct amba_device *adev)
if (!pl022)
return;
- spi_controller_get(pl022->host);
-
spi_unregister_controller(pl022->host);
/*
@@ -2012,8 +2009,6 @@ pl022_remove(struct amba_device *adev)
pl022_dma_remove(pl022);
amba_release_regions(adev);
-
- spi_controller_put(pl022->host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c
index 7e39038160e0..caf55a6f70b3 100644
--- a/drivers/spi/spi-qcom-qspi.c
+++ b/drivers/spi/spi-qcom-qspi.c
@@ -174,6 +174,7 @@ struct qcom_qspi {
void *virt_cmd_desc[QSPI_MAX_SG];
unsigned int n_cmd_desc;
struct icc_path *icc_path_cpu_to_qspi;
+ struct icc_path *icc_path_mem;
unsigned long last_speed;
/* Lock to protect data accessed by IRQs */
spinlock_t lock;
@@ -272,7 +273,7 @@ static void qcom_qspi_handle_err(struct spi_controller *host,
static int qcom_qspi_set_speed(struct qcom_qspi *ctrl, unsigned long speed_hz)
{
int ret;
- unsigned int avg_bw_cpu;
+ unsigned int avg_bw_cpu, avg_bw_mem;
if (speed_hz == ctrl->last_speed)
return 0;
@@ -285,7 +286,7 @@ static int qcom_qspi_set_speed(struct qcom_qspi *ctrl, unsigned long speed_hz)
}
/*
- * Set BW quota for CPU.
+ * Set BW quota for CPU and memory paths.
* We don't have explicit peak requirement so keep it equal to avg_bw.
*/
avg_bw_cpu = Bps_to_icc(speed_hz);
@@ -296,6 +297,13 @@ static int qcom_qspi_set_speed(struct qcom_qspi *ctrl, unsigned long speed_hz)
return ret;
}
+ avg_bw_mem = Bps_to_icc(speed_hz);
+ ret = icc_set_bw(ctrl->icc_path_mem, avg_bw_mem, avg_bw_mem);
+ if (ret) {
+ dev_err(ctrl->dev, "ICC BW voting failed for memory: %d\n", ret);
+ return ret;
+ }
+
ctrl->last_speed = speed_hz;
return 0;
@@ -729,6 +737,14 @@ static int qcom_qspi_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(ctrl->icc_path_cpu_to_qspi),
"Failed to get cpu path\n");
+ ctrl->icc_path_mem = devm_of_icc_get(dev, "qspi-memory");
+ if (IS_ERR(ctrl->icc_path_mem)) {
+ if (PTR_ERR(ctrl->icc_path_mem) != -ENODATA)
+ return dev_err_probe(dev, PTR_ERR(ctrl->icc_path_mem),
+ "Failed to get memory path\n");
+ ctrl->icc_path_mem = NULL;
+ }
+
/* Set BW vote for register access */
ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, Bps_to_icc(1000),
Bps_to_icc(1000));
@@ -818,20 +834,42 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev)
struct qcom_qspi *ctrl = spi_controller_get_devdata(host);
int ret;
- /* Drop the performance state vote */
- dev_pm_opp_set_rate(dev, 0);
clk_bulk_disable_unprepare(QSPI_NUM_CLKS, ctrl->clks);
ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
if (ret) {
dev_err_ratelimited(ctrl->dev, "%s: ICC disable failed for cpu: %d\n",
__func__, ret);
- return ret;
+ goto err_enable_clk;
}
- pinctrl_pm_select_sleep_state(dev);
+ ret = icc_disable(ctrl->icc_path_mem);
+ if (ret) {
+ dev_err_ratelimited(ctrl->dev, "ICC disable failed for memory: %d\n", ret);
+ goto err_enable_icc_cpu;
+ }
+
+ ret = pinctrl_pm_select_sleep_state(dev);
+ if (ret)
+ goto err_enable_icc_mem;
+
+ /* Drop the performance state vote */
+ ret = dev_pm_opp_set_rate(dev, 0);
+ if (ret)
+ goto err_select_default_state;
return 0;
+
+err_select_default_state:
+ pinctrl_pm_select_default_state(dev);
+err_enable_icc_mem:
+ icc_enable(ctrl->icc_path_mem);
+err_enable_icc_cpu:
+ icc_enable(ctrl->icc_path_cpu_to_qspi);
+err_enable_clk:
+ if (clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks))
+ dev_err_ratelimited(ctrl->dev, "Failed to re-enable clocks\n");
+ return ret;
}
static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev)
@@ -840,20 +878,42 @@ static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev)
struct qcom_qspi *ctrl = spi_controller_get_devdata(host);
int ret;
- pinctrl_pm_select_default_state(dev);
+ ret = dev_pm_opp_set_rate(dev, ctrl->last_speed * 4);
+ if (ret)
+ return ret;
+
+ ret = pinctrl_pm_select_default_state(dev);
+ if (ret)
+ goto err_opp_set_rate_zero;
ret = icc_enable(ctrl->icc_path_cpu_to_qspi);
if (ret) {
dev_err_ratelimited(ctrl->dev, "%s: ICC enable failed for cpu: %d\n",
__func__, ret);
- return ret;
+ goto err_select_sleep_state;
+ }
+
+ ret = icc_enable(ctrl->icc_path_mem);
+ if (ret) {
+ dev_err_ratelimited(ctrl->dev, "ICC enable failed for memory: %d\n", ret);
+ goto err_disable_icc_cpu;
}
ret = clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks);
if (ret)
- return ret;
+ goto err_disable_icc_mem;
+
+ return 0;
- return dev_pm_opp_set_rate(dev, ctrl->last_speed * 4);
+err_disable_icc_mem:
+ icc_disable(ctrl->icc_path_mem);
+err_disable_icc_cpu:
+ icc_disable(ctrl->icc_path_cpu_to_qspi);
+err_select_sleep_state:
+ pinctrl_pm_select_sleep_state(dev);
+err_opp_set_rate_zero:
+ dev_pm_opp_set_rate(dev, 0);
+ return ret;
}
static int __maybe_unused qcom_qspi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 50bb7701b9d5..034546b3f058 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -1074,11 +1074,9 @@ static int spi_qup_probe(struct platform_device *pdev)
if (ret && ret != -ENODEV)
return dev_err_probe(dev, ret, "invalid OPP table\n");
- host = spi_alloc_host(dev, sizeof(struct spi_qup));
- if (!host) {
- dev_err(dev, "cannot allocate host\n");
+ host = devm_spi_alloc_host(dev, sizeof(struct spi_qup));
+ if (!host)
return -ENOMEM;
- }
/* use num-cs unless not present or out of range */
if (of_property_read_u32(dev->of_node, "num-cs", &num_cs) ||
@@ -1111,7 +1109,7 @@ static int spi_qup_probe(struct platform_device *pdev)
ret = spi_qup_init_dma(host, res->start);
if (ret == -EPROBE_DEFER)
- goto error;
+ return ret;
else if (!ret)
host->can_dma = spi_qup_can_dma;
@@ -1209,8 +1207,7 @@ error_clk:
clk_disable_unprepare(iclk);
error_dma:
spi_qup_release_dma(host);
-error:
- spi_controller_put(host);
+
return ret;
}
@@ -1323,8 +1320,6 @@ static void spi_qup_remove(struct platform_device *pdev)
struct spi_qup *controller = spi_controller_get_devdata(host);
int ret;
- spi_controller_get(host);
-
spi_unregister_controller(host);
ret = pm_runtime_get_sync(&pdev->dev);
@@ -1346,8 +1341,6 @@ static void spi_qup_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(host);
}
static const struct of_device_id spi_qup_dt_match[] = {
diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c
index 6edc0c4db854..1ef7bd91b3b3 100644
--- a/drivers/spi/spi-rpc-if.c
+++ b/drivers/spi/spi-rpc-if.c
@@ -83,7 +83,7 @@ static ssize_t xspi_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
if (offs + desc->info.offset + len > U32_MAX)
return -EINVAL;
- rpcif_spi_mem_prepare(desc->mem->spi, &desc->info.op_tmpl, &offs, &len);
+ rpcif_spi_mem_prepare(desc->mem->spi, desc->info.op_tmpl, &offs, &len);
return xspi_dirmap_write(rpc->dev, offs, len, buf);
}
@@ -97,7 +97,7 @@ static ssize_t rpcif_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (offs + desc->info.offset + len > U32_MAX)
return -EINVAL;
- rpcif_spi_mem_prepare(desc->mem->spi, &desc->info.op_tmpl, &offs, &len);
+ rpcif_spi_mem_prepare(desc->mem->spi, desc->info.op_tmpl, &offs, &len);
return rpcif_dirmap_read(rpc->dev, offs, len, buf);
}
@@ -110,13 +110,13 @@ static int rpcif_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)
if (desc->info.offset + desc->info.length > U32_MAX)
return -EINVAL;
- if (!rpcif_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))
+ if (!rpcif_spi_mem_supports_op(desc->mem, desc->info.op_tmpl))
return -EOPNOTSUPP;
if (!rpc->dirmap)
return -EOPNOTSUPP;
- if (!rpc->xspi && desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
+ if (!rpc->xspi && desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN)
return -EOPNOTSUPP;
return 0;
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index a8180dece716..38df676774ee 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1171,14 +1171,10 @@ static void rspi_remove(struct platform_device *pdev)
{
struct rspi_data *rspi = platform_get_drvdata(pdev);
- spi_controller_get(rspi->ctlr);
-
spi_unregister_controller(rspi->ctlr);
rspi_release_dma(rspi->ctlr);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(rspi->ctlr);
}
static const struct spi_ops rspi_ops = {
@@ -1226,11 +1222,6 @@ static const struct of_device_id rspi_of_match[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, rspi_of_match);
#ifdef CONFIG_OF
-static void rspi_reset_control_assert(void *data)
-{
- reset_control_assert(data);
-}
-
static int rspi_parse_dt(struct device *dev, struct spi_controller *ctlr)
{
struct reset_control *rstc;
@@ -1246,22 +1237,10 @@ static int rspi_parse_dt(struct device *dev, struct spi_controller *ctlr)
ctlr->num_chipselect = num_cs;
- rstc = devm_reset_control_get_optional_exclusive(dev, NULL);
+ rstc = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL);
if (IS_ERR(rstc))
return dev_err_probe(dev, PTR_ERR(rstc),
- "failed to get reset ctrl\n");
-
- error = reset_control_deassert(rstc);
- if (error) {
- dev_err(dev, "failed to deassert reset %d\n", error);
- return error;
- }
-
- error = devm_add_action_or_reset(dev, rspi_reset_control_assert, rstc);
- if (error) {
- dev_err(dev, "failed to register assert devm action, %d\n", error);
- return error;
- }
+ "failed to get reset ctrl and deassert reset\n");
return 0;
}
@@ -1294,7 +1273,7 @@ static int rspi_probe(struct platform_device *pdev)
const struct spi_ops *ops;
unsigned long clksrc;
- ctlr = spi_alloc_host(&pdev->dev, sizeof(struct rspi_data));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(struct rspi_data));
if (ctlr == NULL)
return -ENOMEM;
@@ -1302,7 +1281,7 @@ static int rspi_probe(struct platform_device *pdev)
if (ops) {
ret = rspi_parse_dt(&pdev->dev, ctlr);
if (ret)
- goto error1;
+ return ret;
} else {
ops = (struct spi_ops *)pdev->id_entry->driver_data;
ctlr->num_chipselect = 2; /* default */
@@ -1314,16 +1293,13 @@ static int rspi_probe(struct platform_device *pdev)
rspi->ctlr = ctlr;
rspi->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(rspi->addr)) {
- ret = PTR_ERR(rspi->addr);
- goto error1;
- }
+ if (IS_ERR(rspi->addr))
+ return PTR_ERR(rspi->addr);
rspi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(rspi->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
- ret = PTR_ERR(rspi->clk);
- goto error1;
+ return PTR_ERR(rspi->clk);
}
rspi->pdev = pdev;
@@ -1396,15 +1372,13 @@ error3:
rspi_release_dma(ctlr);
error2:
pm_runtime_disable(&pdev->dev);
-error1:
- spi_controller_put(ctlr);
return ret;
}
static const struct platform_device_id spi_driver_ids[] = {
- { "rspi", (kernel_ulong_t)&rspi_ops },
- {},
+ { .name = "rspi", .driver_data = (kernel_ulong_t)&rspi_ops },
+ { }
};
MODULE_DEVICE_TABLE(platform, spi_driver_ids);
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index 6ed3fad873b8..0738d448160d 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -803,6 +803,23 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
return ret;
}
+static int rzv2h_rspi_suspend(struct device *dev)
+{
+ struct rzv2h_rspi_priv *rspi = dev_get_drvdata(dev);
+
+ return spi_controller_suspend(rspi->controller);
+}
+
+static int rzv2h_rspi_resume(struct device *dev)
+{
+ struct rzv2h_rspi_priv *rspi = dev_get_drvdata(dev);
+
+ return spi_controller_resume(rspi->controller);
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rzv2h_rspi_pm_ops, rzv2h_rspi_suspend,
+ rzv2h_rspi_resume);
+
static const struct rzv2h_rspi_info rzv2h_info = {
.find_tclk_rate = rzv2h_rspi_find_rate_fixed,
.tclk_name = "tclk",
@@ -838,6 +855,7 @@ static struct platform_driver rzv2h_rspi_drv = {
.driver = {
.name = "rzv2h_rspi",
.of_match_table = rzv2h_rspi_match,
+ .pm = pm_sleep_ptr(&rzv2h_rspi_pm_ops),
},
};
module_platform_driver(rzv2h_rspi_drv);
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 37176e557099..28c56b06fa99 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1613,10 +1613,10 @@ static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
{
- .name = "s3c6410-spi",
- .driver_data = (kernel_ulong_t)&s3c6410_spi_port_config,
+ .name = "s3c6410-spi",
+ .driver_data = (kernel_ulong_t)&s3c6410_spi_port_config,
},
- { },
+ { }
};
MODULE_DEVICE_TABLE(platform, s3c64xx_spi_driver_ids);
diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c
index 78c558e7228e..ae534ebd5e87 100644
--- a/drivers/spi/spi-sc18is602.c
+++ b/drivers/spi/spi-sc18is602.c
@@ -295,9 +295,9 @@ static int sc18is602_probe(struct i2c_client *client)
}
static const struct i2c_device_id sc18is602_id[] = {
- { "sc18is602", sc18is602 },
- { "sc18is602b", sc18is602b },
- { "sc18is603", sc18is603 },
+ { .name = "sc18is602", .driver_data = sc18is602 },
+ { .name = "sc18is602b", .driver_data = sc18is602b },
+ { .name = "sc18is603", .driver_data = sc18is603 },
{ }
};
MODULE_DEVICE_TABLE(i2c, sc18is602_id);
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c
index 1e3ca718ca73..f840467cfdb2 100644
--- a/drivers/spi/spi-sh-hspi.c
+++ b/drivers/spi/spi-sh-hspi.c
@@ -224,15 +224,14 @@ static int hspi_probe(struct platform_device *pdev)
return -EINVAL;
}
- ctlr = spi_alloc_host(&pdev->dev, sizeof(*hspi));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*hspi));
if (!ctlr)
return -ENOMEM;
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "couldn't get clock\n");
- ret = -EINVAL;
- goto error0;
+ return PTR_ERR(clk);
}
hspi = spi_controller_get_devdata(ctlr);
@@ -269,8 +268,6 @@ static int hspi_probe(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
error1:
clk_put(clk);
- error0:
- spi_controller_put(ctlr);
return ret;
}
@@ -279,15 +276,11 @@ static void hspi_remove(struct platform_device *pdev)
{
struct hspi_priv *hspi = platform_get_drvdata(pdev);
- spi_controller_get(hspi->ctlr);
-
spi_unregister_controller(hspi->ctlr);
pm_runtime_disable(&pdev->dev);
clk_put(hspi->clk);
-
- spi_controller_put(hspi->ctlr);
}
static const struct of_device_id hspi_of_match[] = {
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index f114b6313f4f..f23db85a1889 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -1215,9 +1215,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
info->dtdl = 200;
if (info->mode == MSIOF_SPI_TARGET)
- ctlr = spi_alloc_target(dev, sizeof(struct sh_msiof_spi_priv));
+ ctlr = devm_spi_alloc_target(dev, sizeof(struct sh_msiof_spi_priv));
else
- ctlr = spi_alloc_host(dev, sizeof(struct sh_msiof_spi_priv));
+ ctlr = devm_spi_alloc_host(dev, sizeof(struct sh_msiof_spi_priv));
if (ctlr == NULL)
return -ENOMEM;
@@ -1234,26 +1234,21 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
p->clk = devm_clk_get(dev, NULL);
if (IS_ERR(p->clk)) {
dev_err(dev, "cannot get clock\n");
- ret = PTR_ERR(p->clk);
- goto err1;
+ return PTR_ERR(p->clk);
}
i = platform_get_irq(pdev, 0);
- if (i < 0) {
- ret = i;
- goto err1;
- }
+ if (i < 0)
+ return i;
p->mapbase = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(p->mapbase)) {
- ret = PTR_ERR(p->mapbase);
- goto err1;
- }
+ if (IS_ERR(p->mapbase))
+ return PTR_ERR(p->mapbase);
ret = devm_request_irq(dev, i, sh_msiof_spi_irq, 0, dev_name(dev), p);
if (ret) {
dev_err(dev, "unable to request irq\n");
- goto err1;
+ return ret;
}
p->pdev = pdev;
@@ -1300,8 +1295,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
err2:
sh_msiof_release_dma(p);
pm_runtime_disable(dev);
- err1:
- spi_controller_put(ctlr);
+
return ret;
}
@@ -1309,19 +1303,15 @@ static void sh_msiof_spi_remove(struct platform_device *pdev)
{
struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
- spi_controller_get(p->ctlr);
-
spi_unregister_controller(p->ctlr);
sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(p->ctlr);
}
static const struct platform_device_id spi_driver_ids[] = {
- { "spi_sh_msiof", (kernel_ulong_t)&sh_data },
- {},
+ { .name = "spi_sh_msiof", .driver_data = (kernel_ulong_t)&sh_data },
+ { }
};
MODULE_DEVICE_TABLE(platform, spi_driver_ids);
diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index 74a3e32fd2b5..cee4d92e46f4 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -296,7 +296,7 @@ static int sifive_spi_probe(struct platform_device *pdev)
u32 cs_bits, max_bits_per_word;
struct spi_controller *host;
- host = spi_alloc_host(&pdev->dev, sizeof(struct sifive_spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct sifive_spi));
if (!host) {
dev_err(&pdev->dev, "out of memory\n");
return -ENOMEM;
@@ -307,24 +307,19 @@ static int sifive_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
spi->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(spi->regs)) {
- ret = PTR_ERR(spi->regs);
- goto put_host;
- }
+ if (IS_ERR(spi->regs))
+ return PTR_ERR(spi->regs);
/* Spin up the bus clock before hitting registers */
spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(spi->clk)) {
dev_err(&pdev->dev, "Unable to find bus clock\n");
- ret = PTR_ERR(spi->clk);
- goto put_host;
+ return PTR_ERR(spi->clk);
}
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto put_host;
- }
+ if (irq < 0)
+ return irq;
/* Optional parameters */
ret =
@@ -339,8 +334,7 @@ static int sifive_spi_probe(struct platform_device *pdev)
if (!ret && max_bits_per_word < 8) {
dev_err(&pdev->dev, "Only 8bit SPI words supported by the driver\n");
- ret = -EINVAL;
- goto put_host;
+ return -EINVAL;
}
/* probe the number of CS lines */
@@ -350,15 +344,13 @@ static int sifive_spi_probe(struct platform_device *pdev)
sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive);
if (!cs_bits) {
dev_err(&pdev->dev, "Could not auto probe CS lines\n");
- ret = -EINVAL;
- goto put_host;
+ return -EINVAL;
}
num_cs = ilog2(cs_bits) + 1;
if (num_cs > SIFIVE_SPI_MAX_CS) {
dev_err(&pdev->dev, "Invalid number of spi targets\n");
- ret = -EINVAL;
- goto put_host;
+ return -EINVAL;
}
/* Define our host */
@@ -386,7 +378,7 @@ static int sifive_spi_probe(struct platform_device *pdev)
dev_name(&pdev->dev), spi);
if (ret) {
dev_err(&pdev->dev, "Unable to bind to interrupt\n");
- goto put_host;
+ return ret;
}
dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
@@ -395,15 +387,10 @@ static int sifive_spi_probe(struct platform_device *pdev)
ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "spi_register_host failed\n");
- goto put_host;
+ return ret;
}
return 0;
-
-put_host:
- spi_controller_put(host);
-
- return ret;
}
static void sifive_spi_remove(struct platform_device *pdev)
@@ -411,14 +398,10 @@ static void sifive_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct sifive_spi *spi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
/* Disable all the interrupts just in case */
sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
-
- spi_controller_put(host);
}
static int sifive_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-slave-mt27xx.c b/drivers/spi/spi-slave-mt27xx.c
index 7aedeaa5889d..e60ab4c18bed 100644
--- a/drivers/spi/spi-slave-mt27xx.c
+++ b/drivers/spi/spi-slave-mt27xx.c
@@ -388,11 +388,9 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
int irq, ret;
const struct of_device_id *of_id;
- ctlr = spi_alloc_target(&pdev->dev, sizeof(*mdata));
- if (!ctlr) {
- dev_err(&pdev->dev, "failed to alloc spi target\n");
+ ctlr = devm_spi_alloc_target(&pdev->dev, sizeof(*mdata));
+ if (!ctlr)
return -ENOMEM;
- }
ctlr->auto_runtime_pm = true;
ctlr->mode_bits = SPI_CPOL | SPI_CPHA;
@@ -406,8 +404,7 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
of_id = of_match_node(mtk_spi_slave_of_match, pdev->dev.of_node);
if (!of_id) {
dev_err(&pdev->dev, "failed to probe of_node\n");
- ret = -EINVAL;
- goto err_put_ctlr;
+ return -EINVAL;
}
mdata = spi_controller_get_devdata(ctlr);
mdata->dev_comp = of_id->data;
@@ -420,35 +417,31 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
init_completion(&mdata->xfer_done);
mdata->dev = &pdev->dev;
mdata->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(mdata->base)) {
- ret = PTR_ERR(mdata->base);
- goto err_put_ctlr;
- }
+ if (IS_ERR(mdata->base))
+ return PTR_ERR(mdata->base);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto err_put_ctlr;
- }
+ if (irq < 0)
+ return irq;
ret = devm_request_irq(&pdev->dev, irq, mtk_spi_slave_interrupt,
IRQF_TRIGGER_NONE, dev_name(&pdev->dev), ctlr);
if (ret) {
dev_err(&pdev->dev, "failed to register irq (%d)\n", ret);
- goto err_put_ctlr;
+ return ret;
}
mdata->spi_clk = devm_clk_get(&pdev->dev, "spi");
if (IS_ERR(mdata->spi_clk)) {
ret = PTR_ERR(mdata->spi_clk);
dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
- goto err_put_ctlr;
+ return ret;
}
ret = clk_prepare_enable(mdata->spi_clk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
- goto err_put_ctlr;
+ return ret;
}
pm_runtime_enable(&pdev->dev);
@@ -465,8 +458,6 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
err_disable_runtime_pm:
pm_runtime_disable(&pdev->dev);
-err_put_ctlr:
- spi_controller_put(ctlr);
return ret;
}
@@ -475,13 +466,9 @@ static void mtk_spi_slave_remove(struct platform_device *pdev)
{
struct spi_controller *ctlr = platform_get_drvdata(pdev);
- spi_controller_get(ctlr);
-
spi_unregister_controller(ctlr);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(ctlr);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c
index b459d51cb3a8..f0320e96fe23 100644
--- a/drivers/spi/spi-sn-f-ospi.c
+++ b/drivers/spi/spi-sn-f-ospi.c
@@ -222,9 +222,8 @@ static void f_ospi_config_clk(struct f_ospi *ospi, u32 device_hz)
*/
val = readl(ospi->base + OSPI_CLK_CTL);
- val &= ~(OSPI_CLK_CTL_PHA | OSPI_CLK_CTL_DIV);
- val |= FIELD_PREP(OSPI_CLK_CTL_PHA, OSPI_CLK_CTL_PHA_180)
- | FIELD_PREP(OSPI_CLK_CTL_DIV, div_reg);
+ FIELD_MODIFY(OSPI_CLK_CTL_PHA, &val, OSPI_CLK_CTL_PHA_180);
+ FIELD_MODIFY(OSPI_CLK_CTL_DIV, &val, div_reg);
writel(val, ospi->base + OSPI_CLK_CTL);
}
diff --git a/drivers/spi/spi-spacemit-k1.c b/drivers/spi/spi-spacemit-k1.c
new file mode 100644
index 000000000000..215fe66d27b4
--- /dev/null
+++ b/drivers/spi/spi-spacemit-k1.c
@@ -0,0 +1,789 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// SpacemiT K1 SPI controller driver
+//
+// Copyright (C) 2026, RISCstar Solutions Corporation
+// Copyright (C) 2023, SpacemiT Corporation
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/scatterlist.h>
+#include <linux/sizes.h>
+#include <linux/spi/spi.h>
+#include <linux/units.h>
+
+#include "internals.h"
+
+/* This is the range of transfer rates supported by the K1 SoC */
+#define K1_SPI_MIN_SPEED_HZ 6250
+#define K1_SPI_MAX_SPEED_HZ 51200000
+
+/* DMA constraints */
+#define K1_SPI_DMA_ALIGNMENT 64
+#define K1_SPI_MAX_DMA_LEN SZ_512K
+
+/* SSP Top Control Register */
+#define SSP_TOP_CTRL 0x00
+#define TOP_SSE BIT(0) /* Enable port */
+#define TOP_FRF_MASK GENMASK(2, 1) /* Frame format */
+#define TOP_FRF_MOTOROLA 0 /* Motorola SPI */
+#define TOP_DSS_MASK GENMASK(9, 5) /* Data size (1-32) */
+#define TOP_SPO BIT(10) /* Polarity: 0=low */
+#define TOP_SPH BIT(11) /* Half-cycle phase */
+#define TOP_LBM BIT(12) /* Loopback mode */
+#define TOP_TRAIL BIT(13) /* Trailing bytes */
+#define TOP_HOLD_FRAME_LOW BIT(14) /* Chip select */
+
+/* SSP FIFO Control Register */
+#define SSP_FIFO_CTRL 0x04
+#define FIFO_TFT_MASK GENMASK(4, 0) /* TX FIFO threshold */
+#define FIFO_RFT_MASK GENMASK(9, 5) /* RX FIFO threshold */
+#define FIFO_TSRE BIT(10) /* TX service request */
+#define FIFO_RSRE BIT(11) /* RX service request */
+
+/* SSP Interrupt Enable Register */
+#define SSP_INT_EN 0x08
+#define SSP_INT_EN_TINTE BIT(1) /* RX timeout */
+#define SSP_INT_EN_RIE BIT(2) /* RX FIFO */
+#define SSP_INT_EN_TIE BIT(3) /* TX FIFO */
+#define SSP_INT_EN_RIM BIT(4) /* RX FIFO overrun */
+#define SSP_INT_EN_TIM BIT(5) /* TX FIFO underrun */
+#define SSP_INT_EN_EBCEI BIT(6) /* Bit count error */
+
+/* TX interrupts, RX interrupts, and error interrupts */
+#define SSP_INT_EN_TX SSP_INT_EN_TIE
+#define SSP_INT_EN_RX \
+ (SSP_INT_EN_TINTE | SSP_INT_EN_RIE)
+#define SSP_INT_EN_ERROR \
+ (SSP_INT_EN_RIM | SSP_INT_EN_TIM | SSP_INT_EN_EBCEI)
+
+/* SSP Time Out Register */
+#define SSP_TIMEOUT 0x0c
+#define SSP_TIMEOUT_MASK GENMASK(23, 0)
+
+/* SSP Data Register */
+#define SSP_DATAR 0x10
+
+/* SSP Status Register */
+#define SSP_STATUS 0x14
+#define SSP_STATUS_BSY BIT(0) /* SPI/I2S busy */
+#define SSP_STATUS_TNF BIT(6) /* TX FIFO not full */
+#define SSP_STATUS_TFL GENMASK(11, 7) /* TX FIFO level */
+#define SSP_STATUS_TUR BIT(12) /* TX FIFO underrun */
+#define SSP_STATUS_RNE BIT(14) /* RX FIFO not empty */
+#define SSP_STATUS_RFL GENMASK(19, 15) /* RX FIFO level */
+#define SSP_STATUS_ROR BIT(20) /* RX FIFO overrun */
+#define SSP_STATUS_BCE BIT(21) /* Bit count error */
+
+/* Error status mask */
+#define SSP_STATUS_ERROR \
+ (SSP_STATUS_TUR | SSP_STATUS_ROR | SSP_STATUS_BCE)
+
+/* The FIFO sizes and thresholds are the same for RX and TX */
+#define K1_SPI_FIFO_SIZE 32
+#define K1_SPI_THRESH (K1_SPI_FIFO_SIZE / 2)
+
+struct k1_spi_driver_data {
+ struct spi_controller *host;
+ void __iomem *base;
+ phys_addr_t base_addr;
+ unsigned long bus_rate;
+ struct clk *clk;
+ unsigned long rate;
+ int irq;
+
+ /* Current transfer information; not valid if message is null */
+ u32 bytes; /* Bytes used for bits_per_word */
+ unsigned int rx_resid; /* RX bytes left in transfer */
+ unsigned int tx_resid; /* TX bytes left in transfer */
+ struct spi_transfer *transfer; /* Current transfer */
+
+ bool dma_enabled;
+};
+
+/* Set our registers to a known initial state */
+static void
+k1_spi_register_reset(struct k1_spi_driver_data *drv_data, bool initial)
+{
+ u32 val = 0;
+
+ writel(0, drv_data->base + SSP_TOP_CTRL);
+
+ if (initial) {
+ /*
+ * The TX and RX FIFO thresholds are the same no matter
+ * what the speed or bits per word, so we can just set
+ * them once. The thresholds are one more than the values
+ * in the register.
+ */
+ val = FIELD_PREP(FIFO_RFT_MASK, K1_SPI_THRESH - 1);
+ val |= FIELD_PREP(FIFO_TFT_MASK, K1_SPI_THRESH - 1);
+ }
+ writel(val, drv_data->base + SSP_FIFO_CTRL);
+
+ writel(0, drv_data->base + SSP_INT_EN);
+ writel(0, drv_data->base + SSP_TIMEOUT);
+
+ /* Clear any pending interrupt conditions */
+ writel(~0, drv_data->base + SSP_STATUS);
+}
+
+/*
+ * The client can call the setup function multiple times, and each call
+ * can specify a different SPI mode (and transfer speed). Each transfer
+ * can specify its own speed though, and the core code ensures each
+ * transfer's speed is set to something nonzero and supported by both
+ * the controller and the device. We just set the speed for each transfer.
+ */
+static int k1_spi_setup(struct spi_device *spi)
+{
+ struct k1_spi_driver_data *drv_data;
+ u32 val;
+
+ drv_data = spi_controller_get_devdata(spi->controller);
+
+ /*
+ * Configure the message format for this device. We only
+ * support Motorola SPI format in master mode.
+ */
+ val = FIELD_PREP(TOP_FRF_MASK, TOP_FRF_MOTOROLA);
+
+ /* Translate the mode into the value used to program the hardware. */
+ if (spi->mode & SPI_CPHA)
+ val |= TOP_SPH; /* 1/2 cycle */
+ if (spi->mode & SPI_CPOL)
+ val |= TOP_SPO; /* active low */
+ if (spi->mode & SPI_LOOP)
+ val |= TOP_LBM; /* enable loopback */
+ writel(val, drv_data->base + SSP_TOP_CTRL);
+
+ return 0;
+}
+
+static void k1_spi_cleanup(struct spi_device *spi)
+{
+ struct k1_spi_driver_data *drv_data;
+
+ drv_data = spi_controller_get_devdata(spi->controller);
+ k1_spi_register_reset(drv_data, false);
+}
+
+static bool k1_spi_can_dma(struct spi_controller *host, struct spi_device *spi,
+ struct spi_transfer *transfer)
+{
+ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host);
+ u32 burst_size;
+
+ if (!drv_data->dma_enabled)
+ return false;
+
+ if (transfer->len > SZ_2K)
+ return false;
+
+ /* Don't bother with DMA if we can't do even a single burst */
+ burst_size = K1_SPI_THRESH * spi_bpw_to_bytes(transfer->bits_per_word);
+
+ return transfer->len >= burst_size;
+}
+
+static void k1_spi_dma_callback(void *param)
+{
+ struct k1_spi_driver_data *drv_data = param;
+ u32 val;
+
+ val = readl(drv_data->base + SSP_FIFO_CTRL);
+ val &= ~(FIFO_TSRE | FIFO_RSRE);
+ writel(val, drv_data->base + SSP_FIFO_CTRL);
+
+ val = readl(drv_data->base + SSP_TOP_CTRL);
+ val &= ~TOP_TRAIL;
+ writel(val, drv_data->base + SSP_TOP_CTRL);
+
+ /* Check for any error conditions */
+ val = readl(drv_data->base + SSP_STATUS);
+ if (val & SSP_STATUS_ERROR)
+ drv_data->transfer->error |= SPI_TRANS_FAIL_IO;
+
+ /* Disable the port */
+ val = readl(drv_data->base + SSP_TOP_CTRL);
+ val &= ~TOP_SSE;
+ writel(val, drv_data->base + SSP_TOP_CTRL);
+
+ drv_data->transfer = NULL;
+
+ spi_finalize_current_transfer(drv_data->host);
+}
+
+/* Prepare a descriptor for TX or RX DMA */
+static struct dma_async_tx_descriptor *
+k1_spi_dma_prep(struct k1_spi_driver_data *drv_data,
+ struct spi_transfer *transfer, bool tx)
+{
+ phys_addr_t addr = drv_data->base_addr + SSP_DATAR;
+ u32 burst_size = K1_SPI_THRESH * drv_data->bytes;
+ struct dma_slave_config cfg = { };
+ enum dma_transfer_direction dir;
+ enum dma_slave_buswidth width;
+ struct dma_chan *chan;
+ struct sg_table *sgt;
+
+ switch (drv_data->bytes) {
+ case 1:
+ width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ break;
+ case 2:
+ width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ default: /* bytes == 4 */
+ width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ }
+
+ if (tx) {
+ chan = drv_data->host->dma_tx;
+ sgt = &transfer->tx_sg;
+ dir = DMA_MEM_TO_DEV;
+
+ cfg.dst_addr = addr;
+ cfg.dst_addr_width = width;
+ cfg.dst_maxburst = burst_size;
+ } else {
+ chan = drv_data->host->dma_rx;
+ sgt = &transfer->rx_sg;
+ dir = DMA_DEV_TO_MEM;
+
+ cfg.src_addr = addr;
+ cfg.src_addr_width = width;
+ cfg.src_maxburst = burst_size;
+ }
+ cfg.direction = dir;
+
+ if (dmaengine_slave_config(chan, &cfg))
+ return NULL;
+
+ return dmaengine_prep_slave_sg(chan, sgt->sgl, sgt->nents, dir,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
+}
+
+static int k1_spi_dma_one(struct spi_controller *host, struct spi_device *spi,
+ struct spi_transfer *transfer)
+{
+ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host);
+ struct dma_async_tx_descriptor *desc;
+ u32 val;
+
+ /* Prepare the TX descriptor and submit it */
+ desc = k1_spi_dma_prep(drv_data, transfer, true);
+ if (!desc)
+ goto fallback;
+ dmaengine_submit(desc);
+
+ /* Prepare the RX descriptor and submit it */
+ desc = k1_spi_dma_prep(drv_data, transfer, false);
+ if (!desc)
+ goto fallback;
+
+ /* When RX is complete we also know TX has completed */
+ desc->callback = k1_spi_dma_callback;
+ desc->callback_param = drv_data;
+
+ dmaengine_submit(desc);
+
+ val = readl(drv_data->base + SSP_TOP_CTRL);
+ val |= TOP_TRAIL; /* Trailing bytes handled by DMA */
+ writel(val, drv_data->base + SSP_TOP_CTRL);
+
+ val = readl(drv_data->base + SSP_FIFO_CTRL);
+ val |= FIFO_TSRE | FIFO_RSRE;
+ writel(val, drv_data->base + SSP_FIFO_CTRL);
+
+ /* Start RX first so we're ready the instant we start transmitting */
+ dma_async_issue_pending(host->dma_rx);
+ dma_async_issue_pending(host->dma_tx);
+
+ return 1;
+fallback:
+ transfer->error |= SPI_TRANS_FAIL_NO_START;
+
+ return -EAGAIN;
+}
+
+/* Flush the RX FIFO of any leftover data before processing a message */
+static int k1_spi_prepare_message(struct spi_controller *host,
+ struct spi_message *message)
+{
+ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host);
+ u32 val = readl(drv_data->base + SSP_STATUS);
+ u32 count;
+
+ /* If there's nothing in the FIFO, we're done */
+ if (!(val & SSP_STATUS_RNE))
+ return 0;
+
+ /* Read and discard what's there (one more than what the field says) */
+ count = FIELD_GET(SSP_STATUS_RFL, val) + 1;
+ do
+ (void)readl(drv_data->base + SSP_DATAR);
+ while (--count);
+
+ return 0;
+}
+
+/* Set logic level of chip select line (high=true means CS deasserted) */
+static void k1_spi_set_cs(struct spi_device *spi, bool high)
+{
+ struct k1_spi_driver_data *drv_data;
+ u32 val;
+
+ drv_data = spi_controller_get_devdata(spi->controller);
+
+ val = readl(drv_data->base + SSP_TOP_CTRL);
+ if (high)
+ val &= ~TOP_HOLD_FRAME_LOW;
+ else
+ val |= TOP_HOLD_FRAME_LOW;
+ writel(val, drv_data->base + SSP_TOP_CTRL);
+}
+
+/* Set the transfer speed; the SPI core code ensures it is supported */
+static int k1_spi_set_speed(struct k1_spi_driver_data *drv_data,
+ struct spi_transfer *transfer)
+{
+ struct clk *clk = drv_data->clk;
+ u64 nsec_per_word;
+ u64 bus_ticks;
+ u32 timeout;
+ u32 val;
+ int ret;
+
+ ret = clk_set_rate(clk, transfer->speed_hz);
+ if (ret)
+ return ret;
+
+ drv_data->rate = clk_get_rate(clk);
+
+ /* No need for RX FIFO timeout if we're not receiving anything */
+ if (!transfer->rx_buf)
+ return 0;
+
+ /*
+ * Compute the RX FIFO inactivity timeout value that should be used.
+ * The inactivity timer restarts with each word that lands in the
+ * FIFO. If several "word transfer times" pass without any new data
+ * in the RX FIFO, we might as well read what's there.
+ *
+ * The rate at which words land in the FIFO is determined by the
+ * word size and the transfer rate. One bit is transferred per
+ * clock tick, and 8 (or 16 or 32) bits are transferred per word.
+ *
+ * So we can get word transfer time (in nanoseconds) from:
+ * nsec_per_tick = NSEC_PER_SEC / drv_data->rate;
+ * ticks_per_word = BITS_PER_BYTE * drv_data->bytes;
+ * We do the divide last for better accuracy.
+ */
+ nsec_per_word = (u64)NSEC_PER_SEC * BITS_PER_BYTE * drv_data->bytes;
+ nsec_per_word = DIV_ROUND_UP_ULL(nsec_per_word, drv_data->rate);
+
+ /*
+ * The timeout (which we'll set to three word transfer times) is
+ * expressed as a number of APB clock ticks.
+ * bus_ticks = 3 * nsec * (drv_data->bus_rate / NSEC_PER_SEC)
+ */
+ bus_ticks = 3 * nsec_per_word * drv_data->bus_rate;
+ timeout = DIV_ROUND_UP_ULL(bus_ticks, NSEC_PER_SEC);
+
+ /* Set the RX timeout period (required for both DMA and PIO) */
+ val = FIELD_PREP(SSP_TIMEOUT_MASK, timeout);
+ writel(val, drv_data->base + SSP_TIMEOUT);
+
+ return 0;
+}
+
+static int k1_spi_transfer_one(struct spi_controller *host,
+ struct spi_device *spi,
+ struct spi_transfer *transfer)
+{
+ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host);
+ u32 ctrl;
+ u32 val;
+ int ret;
+
+ /* Bits per word can change on a per-transfer basis */
+ drv_data->bytes = spi_bpw_to_bytes(transfer->bits_per_word);
+
+ /* Each transfer can also specify a different rate */
+ ret = k1_spi_set_speed(drv_data, transfer);
+ if (ret) {
+ dev_err(&host->dev,
+ "failed to set transfer speed: %d\n", ret);
+ return ret;
+ }
+
+ drv_data->rx_resid = transfer->len;
+ drv_data->tx_resid = transfer->len;
+
+ drv_data->transfer = transfer;
+
+ /* Clear any existing interrupt conditions */
+ writel(~0, drv_data->base + SSP_STATUS);
+
+ /* Set the data (word) size, and enable the port */
+ ctrl = readl(drv_data->base + SSP_TOP_CTRL);
+ ctrl &= ~TOP_DSS_MASK;
+ ctrl |= FIELD_PREP(TOP_DSS_MASK, transfer->bits_per_word - 1);
+ ctrl |= TOP_SSE;
+ writel(ctrl, drv_data->base + SSP_TOP_CTRL);
+
+ if (spi_xfer_is_dma_mapped(host, spi, transfer))
+ return k1_spi_dma_one(host, spi, transfer);
+
+ /* An interrupt will initiate the transfer */
+ val = SSP_INT_EN_TX | SSP_INT_EN_RX | SSP_INT_EN_ERROR;
+ writel(val, drv_data->base + SSP_INT_EN);
+
+ return 1; /* We will call spi_finalize_current_transfer() */
+}
+
+static void
+k1_spi_handle_err(struct spi_controller *host, struct spi_message *message)
+{
+ struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host);
+
+ if (drv_data->dma_enabled) {
+ dmaengine_terminate_sync(host->dma_rx);
+ dmaengine_terminate_sync(host->dma_tx);
+ }
+}
+
+static void k1_spi_write_word(struct k1_spi_driver_data *drv_data)
+{
+ struct spi_transfer *transfer = drv_data->transfer;
+ u32 bytes = drv_data->bytes;
+ u32 val;
+
+ if (transfer->tx_buf) {
+ const void *buf;
+
+ buf = transfer->tx_buf + (transfer->len - drv_data->tx_resid);
+ if (bytes == 1)
+ val = *(u8 *)buf;
+ else if (bytes == 2)
+ val = *(u16 *)buf;
+ else /* bytes == 4 */
+ val = *(u32 *)buf;
+ } else {
+ val = 0; /* Null writer; write 1, 2, or 4 zero bytes */
+ }
+ /* Fill the next TX FIFO entry */
+ writel(val, drv_data->base + SSP_DATAR);
+
+ drv_data->tx_resid -= bytes;
+}
+
+/* The last-read status value is provided; we know SSP_STATUS_TNF is set */
+static bool k1_spi_write(struct k1_spi_driver_data *drv_data, u32 val)
+{
+ unsigned int count;
+
+ /* Get the number of open slots in the FIFO; zero means all */
+ count = FIELD_GET(SSP_STATUS_TFL, val) ? : K1_SPI_FIFO_SIZE;
+
+ /*
+ * Limit how much we try to send at a time, to reduce the
+ * chance the other side can overrun our RX FIFO.
+ */
+ count = min3(count, K1_SPI_THRESH, drv_data->tx_resid / drv_data->bytes);
+ do
+ k1_spi_write_word(drv_data);
+ while (--count);
+
+ return !drv_data->tx_resid;
+}
+
+static void k1_spi_read_word(struct k1_spi_driver_data *drv_data)
+{
+ struct spi_transfer *transfer = drv_data->transfer;
+ u32 bytes = drv_data->bytes;
+ u32 val;
+
+ /* Consume the next RX FIFO entry */
+ val = readl(drv_data->base + SSP_DATAR);
+ if (transfer->rx_buf) {
+ void *buf;
+
+ buf = transfer->rx_buf + (transfer->len - drv_data->rx_resid);
+
+ if (bytes == 1)
+ *(u8 *)buf = val;
+ else if (bytes == 2)
+ *(u16 *)buf = val;
+ else /* bytes == 4 */
+ *(u32 *)buf = val;
+ } /* Otherwise null reader: discard the data */
+
+ drv_data->rx_resid -= bytes;
+}
+
+/* The last-read status value is provided; we know SSP_STATUS_RNE is set */
+static bool k1_spi_read(struct k1_spi_driver_data *drv_data, u32 val)
+{
+ do {
+ unsigned int count = FIELD_GET(SSP_STATUS_RFL, val) + 1;
+
+ /* Only read what we need */
+ count = min(count, drv_data->rx_resid / drv_data->bytes);
+ do
+ k1_spi_read_word(drv_data);
+ while (--count);
+
+ /* If there's no more to read, we're done */
+ if (!drv_data->rx_resid)
+ return true;
+
+ /* Check again in case more became available to read */
+ val = readl(drv_data->base + SSP_STATUS);
+ if (val & SSP_STATUS_RNE)
+ writel(SSP_STATUS_RNE, drv_data->base + SSP_STATUS);
+ else
+ return false;
+ } while (true);
+}
+
+static irqreturn_t k1_spi_ssp_isr(int irq, void *dev_id)
+{
+ struct k1_spi_driver_data *drv_data = dev_id;
+ u32 status;
+ u32 top_ctrl;
+
+ /* Get status and clear pending interrupts */
+ status = readl(drv_data->base + SSP_STATUS);
+ writel(status, drv_data->base + SSP_STATUS);
+
+ /* If no actionable status bits are set, this is not our interrupt */
+ if (!(status & (SSP_STATUS_ERROR | SSP_STATUS_TNF | SSP_STATUS_RNE)))
+ return IRQ_NONE;
+
+ /* Check for any error conditions first */
+ if (status & SSP_STATUS_ERROR) {
+ if (drv_data->transfer)
+ drv_data->transfer->error |= SPI_TRANS_FAIL_IO;
+ goto done;
+ }
+
+ /*
+ * For SPI, bytes are transferred in both directions equally, and
+ * RX always follows TX. Start by writing if there is anything to
+ * write, then read. Once there's no more to read, we're done.
+ */
+ if (drv_data->tx_resid && (status & SSP_STATUS_TNF)) {
+ /* If we finish writing, disable TX interrupts */
+ if (k1_spi_write(drv_data, status))
+ writel(SSP_INT_EN_RX | SSP_INT_EN_ERROR,
+ drv_data->base + SSP_INT_EN);
+ }
+
+ /* We're not done unless we've read all that was requested */
+ if (drv_data->rx_resid) {
+ /* Read more if the FIFO is not empty */
+ if (status & SSP_STATUS_RNE)
+ if (k1_spi_read(drv_data, status))
+ goto done;
+
+ return IRQ_HANDLED;
+ }
+done:
+ /* Disable the port */
+ top_ctrl = readl(drv_data->base + SSP_TOP_CTRL);
+ top_ctrl &= ~TOP_SSE;
+ writel(top_ctrl, drv_data->base + SSP_TOP_CTRL);
+
+ /* Disable all interrupts */
+ writel(0, drv_data->base + SSP_INT_EN);
+
+ if (drv_data->transfer) {
+ drv_data->transfer = NULL;
+ spi_finalize_current_transfer(drv_data->host);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int
+k1_spi_dma_setup(struct k1_spi_driver_data *drv_data, struct device *dev)
+{
+ struct spi_controller *host = drv_data->host;
+ struct dma_chan *chan;
+
+ chan = dma_request_chan(dev, "tx");
+ if (IS_ERR(chan))
+ return PTR_ERR(chan);
+ host->dma_tx = chan;
+
+ chan = dma_request_chan(dev, "rx");
+ if (IS_ERR(chan)) {
+ dma_release_channel(host->dma_tx);
+ host->dma_tx = NULL;
+ return PTR_ERR(chan);
+ }
+ host->dma_rx = chan;
+
+ drv_data->dma_enabled = true;
+
+ return 0;
+}
+
+static void k1_spi_dma_cleanup(struct device *dev, void *res)
+{
+ struct k1_spi_driver_data **ptr = res;
+ struct k1_spi_driver_data *drv_data = *ptr;
+ struct spi_controller *host = drv_data->host;
+
+ if (!drv_data->dma_enabled)
+ return;
+
+ drv_data->dma_enabled = false;
+
+ dma_release_channel(host->dma_rx);
+ host->dma_rx = NULL;
+ dma_release_channel(host->dma_tx);
+ host->dma_tx = NULL;
+}
+
+static int
+devm_k1_spi_dma_setup(struct k1_spi_driver_data *drv_data, struct device *dev)
+{
+ struct k1_spi_driver_data **ptr;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_MMP_PDMA)) {
+ dev_info(dev, "DMA not available; using PIO\n");
+ return 0;
+ }
+
+ ptr = devres_alloc(k1_spi_dma_cleanup, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = k1_spi_dma_setup(drv_data, dev);
+ if (ret) {
+ devres_free(ptr);
+ return ret;
+ }
+
+ *ptr = drv_data;
+ devres_add(dev, ptr);
+
+ return 0;
+}
+
+static int k1_spi_probe(struct platform_device *pdev)
+{
+ struct k1_spi_driver_data *drv_data;
+ struct device *dev = &pdev->dev;
+ struct reset_control *reset;
+ struct spi_controller *host;
+ struct resource *iores;
+ struct clk *clk_bus;
+ int ret;
+
+ host = devm_spi_alloc_host(dev, sizeof(*drv_data));
+ if (!host)
+ return -ENOMEM;
+ drv_data = spi_controller_get_devdata(host);
+ drv_data->host = host;
+ platform_set_drvdata(pdev, drv_data);
+
+ ret = devm_k1_spi_dma_setup(drv_data, dev);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ if (ret)
+ dev_warn(dev, "DMA setup failed (%d), falling back to PIO\n", ret);
+
+ drv_data->base = devm_platform_get_and_ioremap_resource(pdev, 0,
+ &iores);
+ if (IS_ERR(drv_data->base))
+ return dev_err_probe(dev, PTR_ERR(drv_data->base),
+ "error mapping memory\n");
+ drv_data->base_addr = iores->start;
+
+ clk_bus = devm_clk_get_enabled(dev, "bus");
+ if (IS_ERR(clk_bus))
+ return dev_err_probe(dev, PTR_ERR(clk_bus),
+ "error getting/enabling bus clock\n");
+ drv_data->bus_rate = clk_get_rate(clk_bus);
+
+ drv_data->clk = devm_clk_get_enabled(dev, "core");
+ if (IS_ERR(drv_data->clk))
+ return dev_err_probe(dev, PTR_ERR(drv_data->clk),
+ "error getting/enabling core clock\n");
+
+ reset = devm_reset_control_get_exclusive_deasserted(dev, NULL);
+ if (IS_ERR(reset))
+ return dev_err_probe(dev, PTR_ERR(reset),
+ "error getting/deasserting reset\n");
+
+ k1_spi_register_reset(drv_data, true);
+
+ drv_data->irq = platform_get_irq(pdev, 0);
+ if (drv_data->irq < 0)
+ return dev_err_probe(dev, drv_data->irq, "error getting IRQ\n");
+
+ ret = devm_request_irq(dev, drv_data->irq, k1_spi_ssp_isr,
+ IRQF_SHARED, dev_name(dev), drv_data);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "error requesting IRQ\n");
+
+ /* Initialize the host structure, then register it */
+ host->dev.of_node = dev_of_node(dev);
+ host->dev.parent = dev;
+ host->num_chipselect = 1;
+ if (drv_data->dma_enabled)
+ host->dma_alignment = K1_SPI_DMA_ALIGNMENT;
+ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
+ host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+ host->min_speed_hz = K1_SPI_MIN_SPEED_HZ;
+ host->max_speed_hz = K1_SPI_MAX_SPEED_HZ;
+ host->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
+ host->max_dma_len = K1_SPI_MAX_DMA_LEN;
+
+ host->setup = k1_spi_setup;
+ host->cleanup = k1_spi_cleanup;
+ host->can_dma = k1_spi_can_dma;
+ host->prepare_message = k1_spi_prepare_message;
+ host->set_cs = k1_spi_set_cs;
+ host->transfer_one = k1_spi_transfer_one;
+ host->handle_err = k1_spi_handle_err;
+
+ ret = devm_spi_register_controller(dev, host);
+ if (ret)
+ dev_err(dev, "error registering controller\n");
+
+ return ret;
+}
+
+static const struct of_device_id k1_spi_dt_ids[] = {
+ { .compatible = "spacemit,k1-spi", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, k1_spi_dt_ids);
+
+static struct platform_driver k1_spi_driver = {
+ .probe = k1_spi_probe,
+ .driver = {
+ .name = "k1-spi",
+ .of_match_table = k1_spi_dt_ids,
+ },
+};
+module_platform_driver(k1_spi_driver);
+
+MODULE_DESCRIPTION("SpacemiT K1 SPI controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-sprd.c b/drivers/spi/spi-sprd.c
index acebf9c2e795..29380938ef65 100644
--- a/drivers/spi/spi-sprd.c
+++ b/drivers/spi/spi-sprd.c
@@ -923,16 +923,14 @@ static int sprd_spi_probe(struct platform_device *pdev)
int ret;
pdev->id = of_alias_get_id(pdev->dev.of_node, "spi");
- sctlr = spi_alloc_host(&pdev->dev, sizeof(*ss));
+ sctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*ss));
if (!sctlr)
return -ENOMEM;
ss = spi_controller_get_devdata(sctlr);
ss->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(ss->base)) {
- ret = PTR_ERR(ss->base);
- goto free_controller;
- }
+ if (IS_ERR(ss->base))
+ return PTR_ERR(ss->base);
ss->phy_base = res->start;
ss->dev = &pdev->dev;
@@ -949,15 +947,15 @@ static int sprd_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sctlr);
ret = sprd_spi_clk_init(pdev, ss);
if (ret)
- goto free_controller;
+ return ret;
ret = sprd_spi_irq_init(pdev, ss);
if (ret)
- goto free_controller;
+ return ret;
ret = sprd_spi_dma_init(pdev, ss);
if (ret)
- goto free_controller;
+ return ret;
ret = clk_prepare_enable(ss->clk);
if (ret)
@@ -993,8 +991,6 @@ disable_clk:
release_dma:
if (ss->dma.enable)
sprd_spi_dma_release(ss);
-free_controller:
- spi_controller_put(sctlr);
return ret;
}
@@ -1009,8 +1005,6 @@ static void sprd_spi_remove(struct platform_device *pdev)
if (ret < 0)
dev_err(ss->dev, "failed to resume SPI controller\n");
- spi_controller_get(sctlr);
-
spi_unregister_controller(sctlr);
if (ret >= 0) {
@@ -1020,8 +1014,6 @@ static void sprd_spi_remove(struct platform_device *pdev)
}
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- spi_controller_put(sctlr);
}
static int __maybe_unused sprd_spi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c
index 9c8099fe6e19..df61094fc444 100644
--- a/drivers/spi/spi-st-ssc4.c
+++ b/drivers/spi/spi-st-ssc4.c
@@ -279,7 +279,7 @@ static int spi_st_probe(struct platform_device *pdev)
int irq, ret = 0;
u32 var;
- host = spi_alloc_host(&pdev->dev, sizeof(*spi_st));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi_st));
if (!host)
return -ENOMEM;
@@ -296,13 +296,12 @@ static int spi_st_probe(struct platform_device *pdev)
spi_st->clk = devm_clk_get(&pdev->dev, "ssc");
if (IS_ERR(spi_st->clk)) {
dev_err(&pdev->dev, "Unable to request clock\n");
- ret = PTR_ERR(spi_st->clk);
- goto put_host;
+ return PTR_ERR(spi_st->clk);
}
ret = clk_prepare_enable(spi_st->clk);
if (ret)
- goto put_host;
+ return ret;
init_completion(&spi_st->done);
@@ -361,8 +360,7 @@ rpm_disable:
pm_runtime_disable(&pdev->dev);
clk_disable:
clk_disable_unprepare(spi_st->clk);
-put_host:
- spi_controller_put(host);
+
return ret;
}
@@ -371,16 +369,12 @@ static void spi_st_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct spi_st *spi_st = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(spi_st->clk);
- spi_controller_put(host);
-
pinctrl_pm_select_sleep_state(&pdev->dev);
}
diff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c
index 4461c6e24b9e..fa0e8e83cb1b 100644
--- a/drivers/spi/spi-stm32-ospi.c
+++ b/drivers/spi/spi-stm32-ospi.c
@@ -470,10 +470,9 @@ static int stm32_ospi_send(struct spi_device *spi, const struct spi_mem_op *op)
u8 cs = spi->chip_select[ffs(spi->cs_index_mask) - 1];
cr = readl_relaxed(ospi->regs_base + OSPI_CR);
- cr &= ~CR_CSSEL;
- cr |= FIELD_PREP(CR_CSSEL, cs);
- cr &= ~CR_FMODE_MASK;
- cr |= FIELD_PREP(CR_FMODE_MASK, ospi->fmode);
+ FIELD_MODIFY(CR_CSSEL, &cr, cs);
+
+ FIELD_MODIFY(CR_FMODE_MASK, &cr, ospi->fmode);
writel_relaxed(cr, regs_base + OSPI_CR);
if (op->data.nbytes)
@@ -602,11 +601,11 @@ static int stm32_ospi_dirmap_create(struct spi_mem_dirmap_desc *desc)
{
struct stm32_ospi *ospi = spi_controller_get_devdata(desc->mem->spi->controller);
- if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)
+ if (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT)
return -EOPNOTSUPP;
/* Should never happen, as mm_base == null is an error probe exit condition */
- if (!ospi->mm_base && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)
+ if (!ospi->mm_base && desc->info.op_tmpl->data.dir == SPI_MEM_DATA_IN)
return -EOPNOTSUPP;
if (!ospi->mm_size)
@@ -633,7 +632,7 @@ static ssize_t stm32_ospi_dirmap_read(struct spi_mem_dirmap_desc *desc,
* spi_mem_op template with offs, len and *buf in order to get
* all needed transfer information into struct spi_mem_op
*/
- memcpy(&op, &desc->info.op_tmpl, sizeof(struct spi_mem_op));
+ memcpy(&op, desc->info.op_tmpl, sizeof(struct spi_mem_op));
dev_dbg(ospi->dev, "%s len = 0x%zx offs = 0x%llx buf = 0x%p\n", __func__, len, offs, buf);
op.data.nbytes = len;
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index df1bbacec90a..b77daba6db83 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -374,9 +374,8 @@ static int stm32_qspi_send(struct spi_device *spi, const struct spi_mem_op *op)
int timeout, err = 0, err_poll_status = 0;
cr = readl_relaxed(qspi->io_base + QSPI_CR);
- cr &= ~CR_PRESC_MASK & ~CR_FSEL;
- cr |= FIELD_PREP(CR_PRESC_MASK, flash->presc);
- cr |= FIELD_PREP(CR_FSEL, flash->cs);
+ FIELD_MODIFY(CR_PRESC_MASK, &cr, flash->presc);
+ FIELD_MODIFY(CR_FSEL, &cr, flash->cs);
writel_relaxed(cr, qspi->io_base + QSPI_CR);
if (op->data.nbytes)
@@ -506,11 +505,11 @@ static int stm32_qspi_dirmap_create(struct spi_mem_dirmap_desc *desc)
{
struct stm32_qspi *qspi = spi_controller_get_devdata(desc->mem->spi->controller);
- if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)
+ if (desc->info.op_tmpl->data.dir == SPI_MEM_DATA_OUT)
return -EOPNOTSUPP;
/* should never happen, as mm_base == null is an error probe exit condition */
- if (!qspi->mm_base && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)
+ if (!qspi->mm_base && desc->info.op_tmpl->data.dir == SPI_MEM_DATA_IN)
return -EOPNOTSUPP;
if (!qspi->mm_size)
@@ -536,7 +535,7 @@ static ssize_t stm32_qspi_dirmap_read(struct spi_mem_dirmap_desc *desc,
* spi_mem_op template with offs, len and *buf in order to get
* all needed transfer information into struct spi_mem_op
*/
- memcpy(&op, &desc->info.op_tmpl, sizeof(struct spi_mem_op));
+ memcpy(&op, desc->info.op_tmpl, sizeof(struct spi_mem_op));
dev_dbg(qspi->dev, "%s len = 0x%zx offs = 0x%llx buf = 0x%p\n", __func__, len, offs, buf);
op.data.nbytes = len;
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index b7fbb5270edb..d5c16392cd4d 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -434,32 +434,26 @@ static int sun4i_spi_probe(struct platform_device *pdev)
struct sun4i_spi *sspi;
int ret = 0, irq;
- host = spi_alloc_host(&pdev->dev, sizeof(struct sun4i_spi));
- if (!host) {
- dev_err(&pdev->dev, "Unable to allocate SPI Host\n");
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct sun4i_spi));
+ if (!host)
return -ENOMEM;
- }
platform_set_drvdata(pdev, host);
sspi = spi_controller_get_devdata(host);
sspi->base_addr = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(sspi->base_addr)) {
- ret = PTR_ERR(sspi->base_addr);
- goto err_free_host;
- }
+ if (IS_ERR(sspi->base_addr))
+ return PTR_ERR(sspi->base_addr);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = -ENXIO;
- goto err_free_host;
- }
+ if (irq < 0)
+ return -ENXIO;
ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler,
0, "sun4i-spi", sspi);
if (ret) {
dev_err(&pdev->dev, "Cannot request IRQ\n");
- goto err_free_host;
+ return ret;
}
sspi->host = host;
@@ -477,15 +471,13 @@ static int sun4i_spi_probe(struct platform_device *pdev)
sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(sspi->hclk)) {
dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
- ret = PTR_ERR(sspi->hclk);
- goto err_free_host;
+ return PTR_ERR(sspi->hclk);
}
sspi->mclk = devm_clk_get(&pdev->dev, "mod");
if (IS_ERR(sspi->mclk)) {
dev_err(&pdev->dev, "Unable to acquire module clock\n");
- ret = PTR_ERR(sspi->mclk);
- goto err_free_host;
+ return PTR_ERR(sspi->mclk);
}
init_completion(&sspi->done);
@@ -497,7 +489,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
ret = sun4i_spi_runtime_resume(&pdev->dev);
if (ret) {
dev_err(&pdev->dev, "Couldn't resume the device\n");
- goto err_free_host;
+ return ret;
}
pm_runtime_set_active(&pdev->dev);
@@ -515,8 +507,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
err_pm_disable:
pm_runtime_disable(&pdev->dev);
sun4i_spi_runtime_suspend(&pdev->dev);
-err_free_host:
- spi_controller_put(host);
+
return ret;
}
@@ -524,13 +515,9 @@ static void sun4i_spi_remove(struct platform_device *pdev)
{
struct spi_controller *host = platform_get_drvdata(pdev);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_force_suspend(&pdev->dev);
-
- spi_controller_put(host);
}
static const struct of_device_id sun4i_spi_match[] = {
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index 5ac73d324d06..4631e9c7ca1d 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -633,7 +633,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
struct resource *mem;
int ret = 0, irq;
- host = spi_alloc_host(&pdev->dev, sizeof(struct sun6i_spi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(struct sun6i_spi));
if (!host) {
dev_err(&pdev->dev, "Unable to allocate SPI Host\n");
return -ENOMEM;
@@ -643,22 +643,18 @@ static int sun6i_spi_probe(struct platform_device *pdev)
sspi = spi_controller_get_devdata(host);
sspi->base_addr = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
- if (IS_ERR(sspi->base_addr)) {
- ret = PTR_ERR(sspi->base_addr);
- goto err_free_host;
- }
+ if (IS_ERR(sspi->base_addr))
+ return PTR_ERR(sspi->base_addr);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = -ENXIO;
- goto err_free_host;
- }
+ if (irq < 0)
+ return -ENXIO;
ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler,
0, "sun6i-spi", sspi);
if (ret) {
dev_err(&pdev->dev, "Cannot request IRQ\n");
- goto err_free_host;
+ return ret;
}
sspi->host = host;
@@ -679,15 +675,13 @@ static int sun6i_spi_probe(struct platform_device *pdev)
sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(sspi->hclk)) {
dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
- ret = PTR_ERR(sspi->hclk);
- goto err_free_host;
+ return PTR_ERR(sspi->hclk);
}
sspi->mclk = devm_clk_get(&pdev->dev, "mod");
if (IS_ERR(sspi->mclk)) {
dev_err(&pdev->dev, "Unable to acquire module clock\n");
- ret = PTR_ERR(sspi->mclk);
- goto err_free_host;
+ return PTR_ERR(sspi->mclk);
}
init_completion(&sspi->done);
@@ -696,17 +690,14 @@ static int sun6i_spi_probe(struct platform_device *pdev)
sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(sspi->rstc)) {
dev_err(&pdev->dev, "Couldn't get reset controller\n");
- ret = PTR_ERR(sspi->rstc);
- goto err_free_host;
+ return PTR_ERR(sspi->rstc);
}
host->dma_tx = dma_request_chan(&pdev->dev, "tx");
if (IS_ERR(host->dma_tx)) {
/* Check tx to see if we need defer probing driver */
- if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
- ret = -EPROBE_DEFER;
- goto err_free_host;
- }
+ if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
dev_warn(&pdev->dev, "Failed to request TX DMA channel\n");
host->dma_tx = NULL;
}
@@ -759,8 +750,7 @@ err_free_dma_rx:
err_free_dma_tx:
if (host->dma_tx)
dma_release_channel(host->dma_tx);
-err_free_host:
- spi_controller_put(host);
+
return ret;
}
@@ -768,8 +758,6 @@ static void sun6i_spi_remove(struct platform_device *pdev)
{
struct spi_controller *host = platform_get_drvdata(pdev);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_force_suspend(&pdev->dev);
@@ -778,8 +766,6 @@ static void sun6i_spi_remove(struct platform_device *pdev)
dma_release_channel(host->dma_tx);
if (host->dma_rx)
dma_release_channel(host->dma_rx);
-
- spi_controller_put(host);
}
static const struct sun6i_spi_cfg sun6i_a31_spi_cfg = {
diff --git a/drivers/spi/spi-sunplus-sp7021.c b/drivers/spi/spi-sunplus-sp7021.c
index 35601212fb78..c1870322d976 100644
--- a/drivers/spi/spi-sunplus-sp7021.c
+++ b/drivers/spi/spi-sunplus-sp7021.c
@@ -290,8 +290,7 @@ static void sp7021_spi_setup_clk(struct spi_controller *ctlr, struct spi_transfe
div = max(2U, clk_rate / xfer->speed_hz);
clk_sel = (div / 2) - 1;
- pspim->xfer_conf &= ~SP7021_CLK_MASK;
- pspim->xfer_conf |= FIELD_PREP(SP7021_CLK_MASK, clk_sel);
+ FIELD_MODIFY(SP7021_CLK_MASK, &pspim->xfer_conf, clk_sel);
writel(pspim->xfer_conf, pspim->m_base + SP7021_SPI_CONFIG_REG);
}
diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c
index 290c439897c4..c14225e39fd1 100644
--- a/drivers/spi/spi-synquacer.c
+++ b/drivers/spi/spi-synquacer.c
@@ -605,7 +605,7 @@ static int synquacer_spi_probe(struct platform_device *pdev)
int ret;
int rx_irq, tx_irq;
- host = spi_alloc_host(&pdev->dev, sizeof(*sspi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*sspi));
if (!host)
return -ENOMEM;
@@ -617,10 +617,8 @@ static int synquacer_spi_probe(struct platform_device *pdev)
init_completion(&sspi->transfer_done);
sspi->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(sspi->regs)) {
- ret = PTR_ERR(sspi->regs);
- goto put_spi;
- }
+ if (IS_ERR(sspi->regs))
+ return PTR_ERR(sspi->regs);
sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK; /* Default */
device_property_read_u32(&pdev->dev, "socionext,ihclk-rate",
@@ -637,21 +635,19 @@ static int synquacer_spi_probe(struct platform_device *pdev)
sspi->clk = devm_clk_get(sspi->dev, "iPCLK");
} else {
dev_err(&pdev->dev, "specified wrong clock source\n");
- ret = -EINVAL;
- goto put_spi;
+ return -EINVAL;
}
if (IS_ERR(sspi->clk)) {
- ret = dev_err_probe(&pdev->dev, PTR_ERR(sspi->clk),
- "clock not found\n");
- goto put_spi;
+ return dev_err_probe(&pdev->dev, PTR_ERR(sspi->clk),
+ "clock not found\n");
}
ret = clk_prepare_enable(sspi->clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock (%d)\n",
ret);
- goto put_spi;
+ return ret;
}
host->max_speed_hz = clk_get_rate(sspi->clk);
@@ -726,8 +722,6 @@ disable_pm:
pm_runtime_disable(sspi->dev);
disable_clk:
clk_disable_unprepare(sspi->clk);
-put_spi:
- spi_controller_put(host);
return ret;
}
@@ -737,15 +731,11 @@ static void synquacer_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct synquacer_spi *sspi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
pm_runtime_disable(sspi->dev);
clk_disable_unprepare(sspi->clk);
-
- spi_controller_put(host);
}
static int __maybe_unused synquacer_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index b8b0ebe0fe93..aa44ffd09e61 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -1302,7 +1302,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
int ret, spi_irq;
int bus_num;
- host = spi_alloc_host(&pdev->dev, sizeof(*tspi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*tspi));
if (!host) {
dev_err(&pdev->dev, "host allocation failed\n");
return -ENOMEM;
@@ -1336,36 +1336,31 @@ static int tegra_spi_probe(struct platform_device *pdev)
tspi->soc_data = of_device_get_match_data(&pdev->dev);
if (!tspi->soc_data) {
dev_err(&pdev->dev, "unsupported tegra\n");
- ret = -ENODEV;
- goto exit_free_host;
+ return -ENODEV;
}
tspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
- if (IS_ERR(tspi->base)) {
- ret = PTR_ERR(tspi->base);
- goto exit_free_host;
- }
+ if (IS_ERR(tspi->base))
+ return PTR_ERR(tspi->base);
+
tspi->phys = r->start;
spi_irq = platform_get_irq(pdev, 0);
- if (spi_irq < 0) {
- ret = spi_irq;
- goto exit_free_host;
- }
+ if (spi_irq < 0)
+ return spi_irq;
+
tspi->irq = spi_irq;
tspi->clk = devm_clk_get(&pdev->dev, "spi");
if (IS_ERR(tspi->clk)) {
dev_err(&pdev->dev, "can not get clock\n");
- ret = PTR_ERR(tspi->clk);
- goto exit_free_host;
+ return PTR_ERR(tspi->clk);
}
tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
- ret = PTR_ERR(tspi->rst);
- goto exit_free_host;
+ return PTR_ERR(tspi->rst);
}
tspi->max_buf_size = SPI_FIFO_DEPTH << 2;
@@ -1373,7 +1368,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
ret = tegra_spi_init_dma_param(tspi, true);
if (ret < 0)
- goto exit_free_host;
+ return ret;
ret = tegra_spi_init_dma_param(tspi, false);
if (ret < 0)
goto exit_rx_dma_free;
@@ -1431,8 +1426,7 @@ exit_pm_disable:
tegra_spi_deinit_dma_param(tspi, false);
exit_rx_dma_free:
tegra_spi_deinit_dma_param(tspi, true);
-exit_free_host:
- spi_controller_put(host);
+
return ret;
}
@@ -1441,8 +1435,6 @@ static void tegra_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_spi_data *tspi = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
free_irq(tspi->irq, tspi);
@@ -1456,8 +1448,6 @@ static void tegra_spi_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_spi_runtime_suspend(&pdev->dev);
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c
index 9256729f2d49..2caa33f0a52c 100644
--- a/drivers/spi/spi-tegra20-sflash.c
+++ b/drivers/spi/spi-tegra20-sflash.c
@@ -427,11 +427,9 @@ static int tegra_sflash_probe(struct platform_device *pdev)
return -ENODEV;
}
- host = spi_alloc_host(&pdev->dev, sizeof(*tsd));
- if (!host) {
- dev_err(&pdev->dev, "host allocation failed\n");
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*tsd));
+ if (!host)
return -ENOMEM;
- }
/* the spi->mode bits understood by this driver: */
host->mode_bits = SPI_CPOL | SPI_CPHA;
@@ -450,14 +448,13 @@ static int tegra_sflash_probe(struct platform_device *pdev)
host->max_speed_hz = 25000000; /* 25MHz */
tsd->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(tsd->base)) {
- ret = PTR_ERR(tsd->base);
- goto exit_free_host;
- }
+ if (IS_ERR(tsd->base))
+ return PTR_ERR(tsd->base);
ret = platform_get_irq(pdev, 0);
if (ret < 0)
- goto exit_free_host;
+ return ret;
+
tsd->irq = ret;
ret = request_irq(tsd->irq, tegra_sflash_isr, 0,
@@ -465,7 +462,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
tsd->irq);
- goto exit_free_host;
+ return ret;
}
tsd->clk = devm_clk_get(&pdev->dev, NULL);
@@ -518,8 +515,7 @@ exit_pm_disable:
tegra_sflash_runtime_suspend(&pdev->dev);
exit_free_irq:
free_irq(tsd->irq, tsd);
-exit_free_host:
- spi_controller_put(host);
+
return ret;
}
@@ -528,8 +524,6 @@ static void tegra_sflash_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_sflash_data *tsd = spi_controller_get_devdata(host);
- spi_controller_get(host);
-
spi_unregister_controller(host);
free_irq(tsd->irq, tsd);
@@ -537,8 +531,6 @@ static void tegra_sflash_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_sflash_runtime_suspend(&pdev->dev);
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index db28dd556484..588a929a9785 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -226,11 +226,13 @@ struct tegra_qspi {
struct completion xfer_completion;
struct spi_transfer *curr_xfer;
+ struct device *rx_dma_dev;
struct dma_chan *rx_dma_chan;
u32 *rx_dma_buf;
dma_addr_t rx_dma_phys;
struct dma_async_tx_descriptor *rx_dma_desc;
+ struct device *tx_dma_dev;
struct dma_chan *tx_dma_chan;
u32 *tx_dma_buf;
dma_addr_t tx_dma_phys;
@@ -574,15 +576,15 @@ static int tegra_qspi_dma_map_xfer(struct tegra_qspi *tqspi, struct spi_transfer
len = DIV_ROUND_UP(tqspi->curr_dma_words * tqspi->bytes_per_word, 4) * 4;
if (t->tx_buf) {
- t->tx_dma = dma_map_single(tqspi->dev, (void *)tx_buf, len, DMA_TO_DEVICE);
- if (dma_mapping_error(tqspi->dev, t->tx_dma))
+ t->tx_dma = dma_map_single(tqspi->tx_dma_dev, (void *)tx_buf, len, DMA_TO_DEVICE);
+ if (dma_mapping_error(tqspi->tx_dma_dev, t->tx_dma))
return -ENOMEM;
}
if (t->rx_buf) {
- t->rx_dma = dma_map_single(tqspi->dev, (void *)rx_buf, len, DMA_FROM_DEVICE);
- if (dma_mapping_error(tqspi->dev, t->rx_dma)) {
- dma_unmap_single(tqspi->dev, t->tx_dma, len, DMA_TO_DEVICE);
+ t->rx_dma = dma_map_single(tqspi->rx_dma_dev, (void *)rx_buf, len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(tqspi->rx_dma_dev, t->rx_dma)) {
+ dma_unmap_single(tqspi->tx_dma_dev, t->tx_dma, len, DMA_TO_DEVICE);
return -ENOMEM;
}
}
@@ -597,9 +599,9 @@ static void tegra_qspi_dma_unmap_xfer(struct tegra_qspi *tqspi, struct spi_trans
len = DIV_ROUND_UP(tqspi->curr_dma_words * tqspi->bytes_per_word, 4) * 4;
if (t->tx_buf)
- dma_unmap_single(tqspi->dev, t->tx_dma, len, DMA_TO_DEVICE);
+ dma_unmap_single(tqspi->tx_dma_dev, t->tx_dma, len, DMA_TO_DEVICE);
if (t->rx_buf)
- dma_unmap_single(tqspi->dev, t->rx_dma, len, DMA_FROM_DEVICE);
+ dma_unmap_single(tqspi->rx_dma_dev, t->rx_dma, len, DMA_FROM_DEVICE);
}
static int tegra_qspi_start_dma_based_transfer(struct tegra_qspi *tqspi, struct spi_transfer *t)
@@ -745,7 +747,7 @@ static int tegra_qspi_start_cpu_based_transfer(struct tegra_qspi *qspi, struct s
static void tegra_qspi_deinit_dma(struct tegra_qspi *tqspi)
{
if (tqspi->tx_dma_buf) {
- dma_free_coherent(tqspi->dev, tqspi->dma_buf_size,
+ dma_free_coherent(tqspi->tx_dma_dev, tqspi->dma_buf_size,
tqspi->tx_dma_buf, tqspi->tx_dma_phys);
tqspi->tx_dma_buf = NULL;
}
@@ -756,7 +758,7 @@ static void tegra_qspi_deinit_dma(struct tegra_qspi *tqspi)
}
if (tqspi->rx_dma_buf) {
- dma_free_coherent(tqspi->dev, tqspi->dma_buf_size,
+ dma_free_coherent(tqspi->rx_dma_dev, tqspi->dma_buf_size,
tqspi->rx_dma_buf, tqspi->rx_dma_phys);
tqspi->rx_dma_buf = NULL;
}
@@ -782,6 +784,7 @@ static int tegra_qspi_init_dma(struct tegra_qspi *tqspi)
}
tqspi->rx_dma_chan = dma_chan;
+ tqspi->rx_dma_dev = dmaengine_get_dma_device(tqspi->rx_dma_chan);
dma_chan = dma_request_chan(tqspi->dev, "tx");
if (IS_ERR(dma_chan)) {
@@ -790,15 +793,19 @@ static int tegra_qspi_init_dma(struct tegra_qspi *tqspi)
}
tqspi->tx_dma_chan = dma_chan;
+ tqspi->tx_dma_dev = dmaengine_get_dma_device(tqspi->tx_dma_chan);
} else {
if (!device_iommu_mapped(tqspi->dev)) {
dev_warn(tqspi->dev,
"IOMMU not enabled in device-tree, falling back to PIO mode\n");
return 0;
}
+
+ tqspi->rx_dma_dev = tqspi->dev;
+ tqspi->tx_dma_dev = tqspi->dev;
}
- dma_buf = dma_alloc_coherent(tqspi->dev, tqspi->dma_buf_size, &dma_phys, GFP_KERNEL);
+ dma_buf = dma_alloc_coherent(tqspi->rx_dma_dev, tqspi->dma_buf_size, &dma_phys, GFP_KERNEL);
if (!dma_buf) {
err = -ENOMEM;
goto err_out;
@@ -807,7 +814,7 @@ static int tegra_qspi_init_dma(struct tegra_qspi *tqspi)
tqspi->rx_dma_buf = dma_buf;
tqspi->rx_dma_phys = dma_phys;
- dma_buf = dma_alloc_coherent(tqspi->dev, tqspi->dma_buf_size, &dma_phys, GFP_KERNEL);
+ dma_buf = dma_alloc_coherent(tqspi->tx_dma_dev, tqspi->dma_buf_size, &dma_phys, GFP_KERNEL);
if (!dma_buf) {
err = -ENOMEM;
goto err_out;
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index e3b413b9828c..34b154922ff2 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -765,7 +765,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
int ret = 0, num_cs, irq;
dma_cap_mask_t mask;
- host = spi_alloc_host(&pdev->dev, sizeof(*qspi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*qspi));
if (!host)
return -ENOMEM;
@@ -793,8 +793,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "missing platform data\n");
- ret = -ENODEV;
- goto free_host;
+ return -ENODEV;
}
}
@@ -812,28 +811,22 @@ static int ti_qspi_probe(struct platform_device *pdev)
qspi->mmap_size = resource_size(res_mmap);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto free_host;
- }
+ if (irq < 0)
+ return irq;
mutex_init(&qspi->list_lock);
qspi->base = devm_ioremap_resource(&pdev->dev, r);
- if (IS_ERR(qspi->base)) {
- ret = PTR_ERR(qspi->base);
- goto free_host;
- }
+ if (IS_ERR(qspi->base))
+ return PTR_ERR(qspi->base);
if (of_property_present(np, "syscon-chipselects")) {
qspi->ctrl_base =
syscon_regmap_lookup_by_phandle_args(np, "syscon-chipselects",
1, &qspi->ctrl_reg);
- if (IS_ERR(qspi->ctrl_base)) {
- ret = PTR_ERR(qspi->ctrl_base);
- goto free_host;
- }
+ if (IS_ERR(qspi->ctrl_base))
+ return PTR_ERR(qspi->ctrl_base);
}
qspi->fclk = devm_clk_get(&pdev->dev, "fck");
@@ -890,14 +883,16 @@ no_dma:
qspi->current_cs = -1;
ret = spi_register_controller(host);
- if (!ret)
- return 0;
+ if (ret)
+ goto err_free_dma;
+ return 0;
+
+err_free_dma:
ti_qspi_dma_cleanup(qspi);
pm_runtime_disable(&pdev->dev);
-free_host:
- spi_controller_put(host);
+
return ret;
}
@@ -905,16 +900,12 @@ static void ti_qspi_remove(struct platform_device *pdev)
{
struct ti_qspi *qspi = platform_get_drvdata(pdev);
- spi_controller_get(qspi->host);
-
spi_unregister_controller(qspi->host);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
ti_qspi_dma_cleanup(qspi);
-
- spi_controller_put(qspi->host);
}
static const struct dev_pm_ops ti_qspi_pm_ops = {
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 14d11450e86d..c5409ca7faef 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -207,10 +207,10 @@ struct pch_pd_dev_save {
};
static const struct pci_device_id pch_spi_pcidev_id[] = {
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_SPI), 1, },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), .driver_data = 1 },
+ { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), .driver_data = 2 },
+ { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), .driver_data = 1 },
+ { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_SPI), .driver_data = 1 },
{ }
};
@@ -1406,8 +1406,6 @@ static void pch_spi_pd_remove(struct platform_device *plat_dev)
dev_dbg(&plat_dev->dev, "%s:[ch%d] irq=%d\n",
__func__, plat_dev->id, board_dat->pdev->irq);
- spi_controller_get(data->host);
-
spi_unregister_controller(data->host);
/* check for any pending messages; no action is taken if the queue
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index eac6c3e8908b..cc20fd11f03f 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -184,14 +184,12 @@ static void uniphier_spi_set_transfer_size(struct spi_device *spi, int size)
u32 val;
val = readl(priv->base + SSI_TXWDS);
- val &= ~(SSI_TXWDS_WDLEN_MASK | SSI_TXWDS_DTLEN_MASK);
- val |= FIELD_PREP(SSI_TXWDS_WDLEN_MASK, size);
- val |= FIELD_PREP(SSI_TXWDS_DTLEN_MASK, size);
+ FIELD_MODIFY(SSI_TXWDS_WDLEN_MASK, &val, size);
+ FIELD_MODIFY(SSI_TXWDS_DTLEN_MASK, &val, size);
writel(val, priv->base + SSI_TXWDS);
val = readl(priv->base + SSI_RXWDS);
- val &= ~SSI_RXWDS_DTLEN_MASK;
- val |= FIELD_PREP(SSI_RXWDS_DTLEN_MASK, size);
+ FIELD_MODIFY(SSI_RXWDS_DTLEN_MASK, &val, size);
writel(val, priv->base + SSI_RXWDS);
}
@@ -308,9 +306,8 @@ static void uniphier_spi_set_fifo_threshold(struct uniphier_spi_priv *priv,
u32 val;
val = readl(priv->base + SSI_FC);
- val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK);
- val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold);
- val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold);
+ FIELD_MODIFY(SSI_FC_TXFTH_MASK, &val, SSI_FIFO_DEPTH - threshold);
+ FIELD_MODIFY(SSI_FC_RXFTH_MASK, &val, threshold);
writel(val, priv->base + SSI_FC);
}
@@ -649,7 +646,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
int irq;
int ret;
- host = spi_alloc_host(&pdev->dev, sizeof(*priv));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*priv));
if (!host)
return -ENOMEM;
@@ -660,30 +657,26 @@ static int uniphier_spi_probe(struct platform_device *pdev)
priv->is_save_param = false;
priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base)) {
- ret = PTR_ERR(priv->base);
- goto out_host_put;
- }
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
priv->base_dma_addr = res->start;
priv->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
- ret = PTR_ERR(priv->clk);
- goto out_host_put;
+ return PTR_ERR(priv->clk);
}
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto out_host_put;
- }
+ if (irq < 0)
+ return irq;
ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
0, "uniphier-spi", priv);
if (ret) {
dev_err(&pdev->dev, "failed to request IRQ\n");
- goto out_host_put;
+ return ret;
}
init_completion(&priv->xfer_done);
@@ -710,10 +703,9 @@ static int uniphier_spi_probe(struct platform_device *pdev)
host->dma_tx = dma_request_chan(&pdev->dev, "tx");
if (IS_ERR_OR_NULL(host->dma_tx)) {
- if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
- ret = -EPROBE_DEFER;
- goto out_host_put;
- }
+ if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
host->dma_tx = NULL;
dma_tx_burst = INT_MAX;
} else {
@@ -762,8 +754,6 @@ out_release_dma:
host->dma_tx = NULL;
}
-out_host_put:
- spi_controller_put(host);
return ret;
}
@@ -771,16 +761,12 @@ static void uniphier_spi_remove(struct platform_device *pdev)
{
struct spi_controller *host = platform_get_drvdata(pdev);
- spi_controller_get(host);
-
spi_unregister_controller(host);
if (host->dma_tx)
dma_release_channel(host->dma_tx);
if (host->dma_rx)
dma_release_channel(host->dma_rx);
-
- spi_controller_put(host);
}
static const struct of_device_id uniphier_spi_match[] = {
diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
index 0e26ff178505..cd78e927953d 100644
--- a/drivers/spi/spi-wpcm-fiu.c
+++ b/drivers/spi/spi-wpcm-fiu.c
@@ -377,7 +377,7 @@ static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller);
int cs = spi_get_chipselect(desc->mem->spi, 0);
- if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
+ if (desc->info.op_tmpl->data.dir != SPI_MEM_DATA_IN)
return -EOPNOTSUPP;
/*
diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c
index 130a3d716dd4..e40ec6ebe4e5 100644
--- a/drivers/spi/spi-xcomm.c
+++ b/drivers/spi/spi-xcomm.c
@@ -269,8 +269,8 @@ static int spi_xcomm_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id spi_xcomm_ids[] = {
- { "spi-xcomm" },
- { },
+ { .name = "spi-xcomm" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, spi_xcomm_ids);
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 9f065d4e27d1..dc1e968659e1 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -285,7 +285,11 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
if (use_irq) {
xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
- wait_for_completion(&xspi->done);
+ if (!wait_for_completion_timeout(&xspi->done, secs_to_jiffies(1))) {
+ dev_err(&spi->dev, "SPI transfer timed out\n");
+ xspi_init_hw(xspi);
+ return -ETIMEDOUT;
+ }
/* A transmit has just completed. Process received data
* and check for more data to transmit. Always inhibit
* the transmitter while the Isr refills the transmit
@@ -371,11 +375,18 @@ static int xilinx_spi_find_buffer_size(struct xilinx_spi *xspi)
xspi->regs + XIPIF_V123B_RESETR_OFFSET);
/* Fill the Tx FIFO with as many words as possible */
- do {
+ while (1) {
xspi->write_fn(0, xspi->regs + XSPI_TXD_OFFSET);
sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
+ if (sr & XSPI_SR_TX_FULL_MASK)
+ break;
+
n_words++;
- } while (!(sr & XSPI_SR_TX_FULL_MASK));
+ }
+
+ /* Handle the NO FIFO case separately */
+ if (!n_words)
+ return 1;
return n_words;
}
@@ -515,8 +526,6 @@ static void xilinx_spi_remove(struct platform_device *pdev)
xspi->write_fn(0, regs_base + XIPIF_V123B_IIER_OFFSET);
/* Disable the global IPIF interrupt */
xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET);
-
- spi_controller_put(xspi->bitbang.ctlr);
}
/* work with hotplug and coldplug */
diff --git a/drivers/spi/spi-xlp.c b/drivers/spi/spi-xlp.c
index be8bbe1cbba3..d014955e6d4b 100644
--- a/drivers/spi/spi-xlp.c
+++ b/drivers/spi/spi-xlp.c
@@ -398,7 +398,7 @@ static int xlp_spi_probe(struct platform_device *pdev)
xspi->spi_clk = clk_get_rate(clk);
- host = spi_alloc_host(&pdev->dev, 0);
+ host = devm_spi_alloc_host(&pdev->dev, 0);
if (!host) {
dev_err(&pdev->dev, "could not alloc host\n");
return -ENOMEM;
@@ -418,7 +418,6 @@ static int xlp_spi_probe(struct platform_device *pdev)
err = devm_spi_register_controller(&pdev->dev, host);
if (err) {
dev_err(&pdev->dev, "spi register host failed!\n");
- spi_controller_put(host);
return err;
}
diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c
index 71f0f176cfd9..d47a1e548fce 100644
--- a/drivers/spi/spi-xtensa-xtfpga.c
+++ b/drivers/spi/spi-xtensa-xtfpga.c
@@ -122,7 +122,6 @@ static void xtfpga_spi_remove(struct platform_device *pdev)
struct xtfpga_spi *xspi = spi_controller_get_devdata(host);
spi_bitbang_stop(&xspi->bitbang);
- spi_controller_put(host);
}
MODULE_ALIAS("platform:" XTFPGA_SPI_NAME);
diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index 406fd9d5337e..d762aaf452af 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -637,7 +637,7 @@ static int zynq_qspi_probe(struct platform_device *pdev)
struct zynq_qspi *xqspi;
u32 num_cs;
- ctlr = spi_alloc_host(&pdev->dev, sizeof(*xqspi));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*xqspi));
if (!ctlr)
return -ENOMEM;
@@ -645,16 +645,13 @@ static int zynq_qspi_probe(struct platform_device *pdev)
xqspi->dev = dev;
platform_set_drvdata(pdev, ctlr);
xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(xqspi->regs)) {
- ret = PTR_ERR(xqspi->regs);
- goto remove_ctlr;
- }
+ if (IS_ERR(xqspi->regs))
+ return PTR_ERR(xqspi->regs);
xqspi->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
if (IS_ERR(xqspi->pclk)) {
dev_err(&pdev->dev, "pclk clock not found.\n");
- ret = PTR_ERR(xqspi->pclk);
- goto remove_ctlr;
+ return PTR_ERR(xqspi->pclk);
}
init_completion(&xqspi->data_completion);
@@ -662,21 +659,18 @@ static int zynq_qspi_probe(struct platform_device *pdev)
xqspi->refclk = devm_clk_get_enabled(&pdev->dev, "ref_clk");
if (IS_ERR(xqspi->refclk)) {
dev_err(&pdev->dev, "ref_clk clock not found.\n");
- ret = PTR_ERR(xqspi->refclk);
- goto remove_ctlr;
+ return PTR_ERR(xqspi->refclk);
}
xqspi->irq = platform_get_irq(pdev, 0);
- if (xqspi->irq < 0) {
- ret = xqspi->irq;
- goto remove_ctlr;
- }
+ if (xqspi->irq < 0)
+ return xqspi->irq;
+
ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq,
0, pdev->name, xqspi);
if (ret != 0) {
- ret = -ENXIO;
dev_err(&pdev->dev, "request_irq failed\n");
- goto remove_ctlr;
+ return -ENXIO;
}
ret = of_property_read_u32(np, "num-cs",
@@ -684,9 +678,8 @@ static int zynq_qspi_probe(struct platform_device *pdev)
if (ret < 0) {
ctlr->num_chipselect = 1;
} else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) {
- ret = -EINVAL;
dev_err(&pdev->dev, "only 2 chip selects are available\n");
- goto remove_ctlr;
+ return -EINVAL;
} else {
ctlr->num_chipselect = num_cs;
}
@@ -705,15 +698,10 @@ static int zynq_qspi_probe(struct platform_device *pdev)
ret = spi_register_controller(ctlr);
if (ret) {
dev_err(&pdev->dev, "failed to register controller\n");
- goto remove_ctlr;
+ return ret;
}
- return ret;
-
-remove_ctlr:
- spi_controller_put(ctlr);
-
- return ret;
+ return 0;
}
/**
@@ -731,13 +719,9 @@ static void zynq_qspi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
- spi_controller_get(ctlr);
-
spi_unregister_controller(ctlr);
zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
-
- spi_controller_put(ctlr);
}
static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 889e1eecc757..76e3563c523f 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -732,8 +732,6 @@ static int __spi_add_device(struct spi_device *spi, struct spi_device *parent)
}
if (ctlr->cs_gpiods) {
- u8 cs;
-
for (idx = 0; idx < spi->num_chipselect; idx++) {
cs = spi_get_chipselect(spi, idx);
spi_set_csgpiod(spi, idx, ctlr->cs_gpiods[cs]);
@@ -3226,9 +3224,9 @@ extern struct class spi_target_class; /* dummy */
* This must be called from context that can sleep.
*
* The caller is responsible for assigning the bus number and initializing the
- * controller's methods before calling spi_register_controller(); and (after
- * errors adding the device) calling spi_controller_put() to prevent a memory
- * leak.
+ * controller's methods before calling spi_register_controller(); and calling
+ * spi_controller_put() to prevent a memory leak when done with the
+ * controller.
*
* Return: the SPI controller structure on success, else NULL.
*/
@@ -3312,8 +3310,6 @@ struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
if (ret)
return NULL;
- ctlr->devm_allocated = true;
-
return ctlr;
}
EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller);
@@ -3552,7 +3548,8 @@ int spi_register_controller(struct spi_controller *ctlr)
/* Register devices from the device tree and ACPI */
of_register_spi_devices(ctlr);
acpi_register_spi_devices(ctlr);
- return status;
+
+ return 0;
del_ctrl:
device_del(&ctlr->dev);
@@ -3560,6 +3557,7 @@ free_bus_id:
mutex_lock(&board_lock);
idr_remove(&spi_controller_idr, ctlr->bus_num);
mutex_unlock(&board_lock);
+
return status;
}
EXPORT_SYMBOL_GPL(spi_register_controller);
@@ -3577,8 +3575,7 @@ static void devm_spi_unregister_controller(void *ctlr)
* Context: can sleep
*
* Register a SPI device as with spi_register_controller() which will
- * automatically be unregistered (and freed unless it has been allocated using
- * devm_spi_alloc_host/target()).
+ * automatically be unregistered.
*
* Return: zero on success, else a negative error code.
*/
@@ -3591,19 +3588,7 @@ int devm_spi_register_controller(struct device *dev,
if (ret)
return ret;
- /*
- * Prevent controller from being freed by spi_unregister_controller()
- * if devm_add_action_or_reset() fails for a non-devres allocated
- * controller.
- */
- spi_controller_get(ctlr);
-
- ret = devm_add_action_or_reset(dev, devm_spi_unregister_controller, ctlr);
-
- if (ret == 0 || ctlr->devm_allocated)
- spi_controller_put(ctlr);
-
- return ret;
+ return devm_add_action_or_reset(dev, devm_spi_unregister_controller, ctlr);
}
EXPORT_SYMBOL_GPL(devm_spi_register_controller);
@@ -3622,9 +3607,6 @@ static int __unregister(struct device *dev, void *null)
* only ones directly touching chip registers.
*
* This must be called from context that can sleep.
- *
- * Note that this function also drops a reference to the controller unless it
- * has been allocated using devm_spi_alloc_host/target().
*/
void spi_unregister_controller(struct spi_controller *ctlr)
{
@@ -3659,13 +3641,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
mutex_unlock(&ctlr->add_lock);
-
- /*
- * Release the last reference on the controller if its driver
- * has not yet been converted to devm_spi_alloc_host/target().
- */
- if (!ctlr->devm_allocated)
- put_device(&ctlr->dev);
}
EXPORT_SYMBOL_GPL(spi_unregister_controller);
diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c
index 24e9c909fa02..e4d1ae8308aa 100644
--- a/drivers/staging/greybus/spilib.c
+++ b/drivers/staging/greybus/spilib.c
@@ -547,13 +547,10 @@ int gb_spilib_master_init(struct gb_connection *connection, struct device *dev,
return 0;
-exit_spi_put:
- spi_controller_put(ctlr);
-
- return ret;
-
exit_spi_unregister:
spi_unregister_controller(ctlr);
+exit_spi_put:
+ spi_controller_put(ctlr);
return ret;
}
@@ -564,6 +561,7 @@ void gb_spilib_master_exit(struct gb_connection *connection)
struct spi_controller *ctlr = gb_connection_get_data(connection);
spi_unregister_controller(ctlr);
+ spi_controller_put(ctlr);
}
EXPORT_SYMBOL_GPL(gb_spilib_master_exit);