mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 07:51:31 -04:00
Merge tag 'spi-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"A busy release for SPI, almost all of it in a couple of larger fix and
cleanup series for patterns that affected many drivers. We do have a
couple of core API additions as well, relatively application specific
but they enable some new use cases.
- A packed command operation for spi-mem devices
- Improvements to the ancillary device support to enable some IIO use
cases from Antoniu Miclaus
- Fixes for a registration ordering issue pattern caused by the
handover between allocation and registration of controllers in
concert with devm from Johan Hovold
- Improvements to handling of clock allocation from Pei Xiao
- Cleanups in the fsl-lpspi driver from Marc Kleine-Budde
- Support for Renesas RZ/G3E and RZ/G3L"
* tag 'spi-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (115 commits)
spi: sn-f-ospi: fix incorrect return code for invalid num-cs
spi: spi-mem: Add a packed command operation
spi: cadence-qspi: Revert the filtering of certain opcodes in ODTR
spi: mtk-snfi: unregister ECC engine on probe failure and remove() callback
spi: s3c64xx: fix NULL-deref on driver unbind
spi: zynq-qspi: fix controller deregistration
spi: zynqmp-gqspi: fix controller deregistration
spi: uniphier: fix controller deregistration
spi: ti-qspi: fix controller deregistration
spi: tegra20-sflash: fix controller deregistration
spi: tegra114: fix controller deregistration
spi: syncuacer: fix controller deregistration
spi: sun6i: fix controller deregistration
spi: sun4i: fix controller deregistration
spi: st-ssc4: fix controller deregistration
spi: sprd: fix controller deregistration
spi: slave-mt27xx: fix controller deregistration
spi: sifive: fix controller deregistration
spi: sh-msiof: fix controller deregistration
spi: sh-hspi: fix controller deregistration
...
This commit is contained in:
@@ -35,10 +35,10 @@ properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
microchip,apb-datawidth:
|
||||
|
||||
@@ -13,10 +13,13 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- renesas,r9a08g046-rspi # RZ/G3L
|
||||
- renesas,r9a09g057-rspi # RZ/V2H(P)
|
||||
- renesas,r9a09g077-rspi # RZ/T2H
|
||||
- items:
|
||||
- const: renesas,r9a09g056-rspi # RZ/V2N
|
||||
- enum:
|
||||
- renesas,r9a09g047-rspi # RZ/G3E
|
||||
- renesas,r9a09g056-rspi # RZ/V2N
|
||||
- const: renesas,r9a09g057-rspi
|
||||
- items:
|
||||
- const: renesas,r9a09g087-rspi # RZ/N2H
|
||||
@@ -58,12 +61,19 @@ properties:
|
||||
- const: tresetn
|
||||
|
||||
dmas:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 10
|
||||
description:
|
||||
Must contain a list of pairs of references to DMA specifiers, one for
|
||||
transmission, and one for reception.
|
||||
|
||||
dma-names:
|
||||
minItems: 2
|
||||
maxItems: 10
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
enum:
|
||||
- rx
|
||||
- tx
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
@@ -81,6 +91,34 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: spi-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- renesas,r9a08g046-rspi
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: tclk
|
||||
|
||||
dmas:
|
||||
maxItems: 2
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
required:
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@@ -121,6 +159,12 @@ allOf:
|
||||
resets: false
|
||||
reset-names: false
|
||||
|
||||
dmas:
|
||||
maxItems: 6
|
||||
|
||||
dma-names:
|
||||
maxItems: 6
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -138,7 +138,7 @@ config SPI_AR934X
|
||||
|
||||
config SPI_ATCSPI200
|
||||
tristate "Andes ATCSPI200 SPI controller"
|
||||
depends on ARCH_ANDES
|
||||
depends on ARCH_ANDES || COMPILE_TEST
|
||||
help
|
||||
SPI driver for Andes ATCSPI200 SPI controller.
|
||||
ATCSPI200 controller supports DMA and PIO modes. When DMA
|
||||
@@ -866,7 +866,7 @@ config SPI_PIC32_SQI
|
||||
|
||||
config SPI_PL022
|
||||
tristate "ARM AMBA PL022 SSP controller"
|
||||
depends on ARM_AMBA
|
||||
depends on ARM_AMBA || COMPILE_TEST
|
||||
default y if ARCH_REALVIEW
|
||||
default y if INTEGRATOR_IMPD1
|
||||
default y if ARCH_VERSATILE
|
||||
|
||||
@@ -647,13 +647,13 @@ static int aml_spisg_clk_init(struct spisg_device *spisg, void __iomem *base)
|
||||
int ret, i;
|
||||
|
||||
spisg->core = devm_clk_get_enabled(dev, "core");
|
||||
if (IS_ERR_OR_NULL(spisg->core)) {
|
||||
if (IS_ERR(spisg->core)) {
|
||||
dev_err(dev, "core clock request failed\n");
|
||||
return PTR_ERR(spisg->core);
|
||||
}
|
||||
|
||||
spisg->pclk = devm_clk_get_enabled(dev, "pclk");
|
||||
if (IS_ERR_OR_NULL(spisg->pclk)) {
|
||||
if (IS_ERR(spisg->pclk)) {
|
||||
dev_err(dev, "pclk clock request failed\n");
|
||||
return PTR_ERR(spisg->pclk);
|
||||
}
|
||||
@@ -703,7 +703,7 @@ static int aml_spisg_clk_init(struct spisg_device *spisg, void __iomem *base)
|
||||
}
|
||||
|
||||
spisg->sclk = devm_clk_hw_get_clk(dev, &div->hw, NULL);
|
||||
if (IS_ERR_OR_NULL(spisg->sclk)) {
|
||||
if (IS_ERR(spisg->sclk)) {
|
||||
dev_err(dev, "get clock failed\n");
|
||||
return PTR_ERR(spisg->sclk);
|
||||
}
|
||||
@@ -800,7 +800,7 @@ static int aml_spisg_probe(struct platform_device *pdev)
|
||||
goto out_clk;
|
||||
}
|
||||
|
||||
ret = devm_spi_register_controller(dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "spi controller registration failed\n");
|
||||
goto out_clk;
|
||||
@@ -823,6 +823,8 @@ static void aml_spisg_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spisg_device *spisg = platform_get_drvdata(pdev);
|
||||
|
||||
spi_unregister_controller(spisg->controller);
|
||||
|
||||
if (!pm_runtime_suspended(&pdev->dev)) {
|
||||
pinctrl_pm_select_sleep_state(&spisg->pdev->dev);
|
||||
clk_disable_unprepare(spisg->core);
|
||||
|
||||
@@ -972,7 +972,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
aspi = spi_controller_get_devdata(ctlr);
|
||||
platform_set_drvdata(pdev, aspi);
|
||||
platform_set_drvdata(pdev, ctlr);
|
||||
aspi->data = data;
|
||||
aspi->dev = dev;
|
||||
|
||||
@@ -1021,7 +1021,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_spi_register_controller(dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "spi_register_controller failed\n");
|
||||
|
||||
@@ -1030,7 +1030,10 @@ static int aspeed_spi_probe(struct platform_device *pdev)
|
||||
|
||||
static void aspeed_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct aspeed_spi *aspi = platform_get_drvdata(pdev);
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
struct aspeed_spi *aspi = spi_controller_get_devdata(ctlr);
|
||||
|
||||
spi_unregister_controller(ctlr);
|
||||
|
||||
aspeed_spi_enable(aspi, false);
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&aus->lock);
|
||||
init_completion(&aus->xfer_completion);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, controller);
|
||||
ret = spi_register_controller(controller);
|
||||
if (ret)
|
||||
goto at91_usart_fail_register_controller;
|
||||
|
||||
@@ -634,8 +634,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 = {
|
||||
|
||||
@@ -494,11 +494,6 @@ static int atcspi_init_resources(struct platform_device *pdev,
|
||||
return dev_err_probe(spi->dev, PTR_ERR(spi->regmap),
|
||||
"Failed to init regmap\n");
|
||||
|
||||
spi->clk = devm_clk_get(spi->dev, NULL);
|
||||
if (IS_ERR(spi->clk))
|
||||
return dev_err_probe(spi->dev, PTR_ERR(spi->clk),
|
||||
"Failed to get SPI clock\n");
|
||||
|
||||
spi->sclk_rate = ATCSPI_MAX_SPEED_HZ;
|
||||
return 0;
|
||||
}
|
||||
@@ -520,13 +515,10 @@ static int atcspi_configure_dma(struct atcspi_dev *spi)
|
||||
|
||||
static int atcspi_enable_clk(struct atcspi_dev *spi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(spi->clk);
|
||||
if (ret)
|
||||
return dev_err_probe(spi->dev, ret,
|
||||
"Failed to enable clock\n");
|
||||
|
||||
spi->clk = devm_clk_get_enabled(spi->dev, NULL);
|
||||
if (IS_ERR(spi->clk))
|
||||
return dev_err_probe(spi->dev, PTR_ERR(spi->clk),
|
||||
"Failed to get SPI clock\n");
|
||||
spi->clk_rate = clk_get_rate(spi->clk);
|
||||
if (!spi->clk_rate)
|
||||
return dev_err_probe(spi->dev, -EINVAL,
|
||||
@@ -567,6 +559,8 @@ static int atcspi_probe(struct platform_device *pdev)
|
||||
spi->dev = &pdev->dev;
|
||||
dev_set_drvdata(&pdev->dev, host);
|
||||
|
||||
mutex_init(&spi->mutex_lock);
|
||||
|
||||
ret = atcspi_init_resources(pdev, spi, &mem_res);
|
||||
if (ret)
|
||||
goto free_controller;
|
||||
@@ -579,15 +573,14 @@ static int atcspi_probe(struct platform_device *pdev)
|
||||
|
||||
ret = atcspi_setup(spi);
|
||||
if (ret)
|
||||
goto disable_clk;
|
||||
goto free_controller;
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
if (ret) {
|
||||
dev_err_probe(spi->dev, ret,
|
||||
"Failed to register SPI controller\n");
|
||||
goto disable_clk;
|
||||
goto free_controller;
|
||||
}
|
||||
|
||||
spi->use_dma = false;
|
||||
if (ATCSPI_DMA_SUPPORT) {
|
||||
ret = atcspi_configure_dma(spi);
|
||||
@@ -597,14 +590,11 @@ static int atcspi_probe(struct platform_device *pdev)
|
||||
else
|
||||
spi->use_dma = true;
|
||||
}
|
||||
mutex_init(&spi->mutex_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(spi->clk);
|
||||
|
||||
free_controller:
|
||||
mutex_destroy(&spi->mutex_lock);
|
||||
spi_controller_put(host);
|
||||
return ret;
|
||||
}
|
||||
@@ -661,7 +651,6 @@ static struct platform_driver atcspi_driver = {
|
||||
.probe = atcspi_probe,
|
||||
.driver = {
|
||||
.name = "atcspi200",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = atcspi_of_match,
|
||||
.pm = pm_sleep_ptr(&atcspi_pm_ops)
|
||||
}
|
||||
|
||||
@@ -1654,7 +1654,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto out_free_dma;
|
||||
|
||||
@@ -1688,8 +1688,12 @@ 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) {
|
||||
atmel_spi_stop_dma(host);
|
||||
@@ -1716,6 +1720,8 @@ 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)
|
||||
|
||||
@@ -842,7 +842,6 @@ static int ax_spi_probe(struct platform_device *pdev)
|
||||
|
||||
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
ctlr->mem_ops = &ax_spi_mem_ops;
|
||||
|
||||
@@ -758,8 +758,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
clk = devm_clk_get(dev, "hsspi");
|
||||
|
||||
clk = devm_clk_get_enabled(dev, "hsspi");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
@@ -767,41 +766,26 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(reset))
|
||||
return PTR_ERR(reset);
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_reset(reset);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to reset device: %d\n", ret);
|
||||
goto out_disable_clk;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "unable to reset device: %d\n", ret);
|
||||
|
||||
rate = clk_get_rate(clk);
|
||||
if (!rate) {
|
||||
pll_clk = devm_clk_get(dev, "pll");
|
||||
|
||||
if (IS_ERR(pll_clk)) {
|
||||
ret = PTR_ERR(pll_clk);
|
||||
goto out_disable_clk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(pll_clk);
|
||||
if (ret)
|
||||
goto out_disable_clk;
|
||||
pll_clk = devm_clk_get_enabled(dev, "pll");
|
||||
if (IS_ERR(pll_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(pll_clk),
|
||||
"failed enable pll clk\n");
|
||||
|
||||
rate = clk_get_rate(pll_clk);
|
||||
if (!rate) {
|
||||
ret = -EINVAL;
|
||||
goto out_disable_pll_clk;
|
||||
}
|
||||
if (!rate)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"failed get pll clk rate\n");
|
||||
}
|
||||
|
||||
host = spi_alloc_host(&pdev->dev, sizeof(*bs));
|
||||
if (!host) {
|
||||
ret = -ENOMEM;
|
||||
goto out_disable_pll_clk;
|
||||
}
|
||||
if (!host)
|
||||
return dev_err_probe(dev, -ENOMEM, "alloc host no mem\n");
|
||||
|
||||
bs = spi_controller_get_devdata(host);
|
||||
bs->pdev = pdev;
|
||||
@@ -873,7 +857,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* register and we are done */
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto out_sysgroup_disable;
|
||||
|
||||
@@ -887,10 +871,6 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
out_put_host:
|
||||
spi_controller_put(host);
|
||||
out_disable_pll_clk:
|
||||
clk_disable_unprepare(pll_clk);
|
||||
out_disable_clk:
|
||||
clk_disable_unprepare(clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -900,11 +880,15 @@ 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);
|
||||
clk_disable_unprepare(bs->pll_clk);
|
||||
clk_disable_unprepare(bs->clk);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group);
|
||||
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -602,7 +602,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
|
||||
goto out_clk_disable;
|
||||
|
||||
/* register and we are done */
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(dev, "spi register failed\n");
|
||||
goto out_clk_disable;
|
||||
@@ -625,11 +625,17 @@ 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 */
|
||||
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
|
||||
|
||||
/* HW shutdown */
|
||||
clk_disable_unprepare(bs->clk);
|
||||
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
static int bcm63xx_spi_suspend(struct device *dev)
|
||||
|
||||
@@ -452,39 +452,30 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(spim_ctrl))
|
||||
return PTR_ERR(spim_ctrl);
|
||||
|
||||
clk = devm_clk_get(dev, "hsspi");
|
||||
clk = devm_clk_get_enabled(dev, "hsspi");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"Failed to get hsspi clock\n");
|
||||
|
||||
rate = clk_get_rate(clk);
|
||||
if (!rate) {
|
||||
pll_clk = devm_clk_get(dev, "pll");
|
||||
pll_clk = devm_clk_get_enabled(dev, "pll");
|
||||
|
||||
if (IS_ERR(pll_clk)) {
|
||||
ret = PTR_ERR(pll_clk);
|
||||
goto out_disable_clk;
|
||||
return dev_err_probe(dev, PTR_ERR(pll_clk),
|
||||
"Failed to get pll clock\n");
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(pll_clk);
|
||||
if (ret)
|
||||
goto out_disable_clk;
|
||||
|
||||
rate = clk_get_rate(pll_clk);
|
||||
if (!rate) {
|
||||
ret = -EINVAL;
|
||||
goto out_disable_pll_clk;
|
||||
}
|
||||
if (!rate)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"Failed to get pll clock rate\n");
|
||||
}
|
||||
|
||||
host = devm_spi_alloc_host(&pdev->dev, sizeof(*bs));
|
||||
if (!host) {
|
||||
ret = -ENOMEM;
|
||||
goto out_disable_pll_clk;
|
||||
}
|
||||
if (!host)
|
||||
return dev_err_probe(dev, -ENOMEM,
|
||||
"Failed alloc spi host\n");
|
||||
|
||||
bs = spi_controller_get_devdata(host);
|
||||
bs->pdev = pdev;
|
||||
@@ -535,21 +526,19 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
|
||||
ret = devm_request_irq(dev, irq, bcmbca_hsspi_interrupt, IRQF_SHARED,
|
||||
pdev->name, bs);
|
||||
if (ret)
|
||||
goto out_disable_pll_clk;
|
||||
return dev_err_probe(dev, ret, "Failed request irq\n");
|
||||
}
|
||||
|
||||
ret = devm_pm_runtime_enable(&pdev->dev);
|
||||
if (ret)
|
||||
goto out_disable_pll_clk;
|
||||
return dev_err_probe(dev, ret, "Failed pm runtime enable\n");
|
||||
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "couldn't register sysfs group\n");
|
||||
goto out_disable_pll_clk;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "couldn't register sysfs group\n");
|
||||
|
||||
/* register and we are done */
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto out_sysgroup_disable;
|
||||
|
||||
@@ -559,10 +548,6 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
|
||||
|
||||
out_sysgroup_disable:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
|
||||
out_disable_pll_clk:
|
||||
clk_disable_unprepare(pll_clk);
|
||||
out_disable_clk:
|
||||
clk_disable_unprepare(clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -571,10 +556,10 @@ static void bcmbca_hsspi_remove(struct platform_device *pdev)
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
|
||||
|
||||
spi_unregister_controller(host);
|
||||
|
||||
/* reset the hardware and block queue progress */
|
||||
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
|
||||
clk_disable_unprepare(bs->pll_clk);
|
||||
clk_disable_unprepare(bs->clk);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
|
||||
}
|
||||
|
||||
|
||||
@@ -1544,10 +1544,6 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
|
||||
if (op->data.nbytes && op->data.buswidth != 8)
|
||||
return false;
|
||||
|
||||
/* A single opcode is supported, it will be repeated */
|
||||
if ((op->cmd.opcode >> 8) != (op->cmd.opcode & 0xFF))
|
||||
return false;
|
||||
|
||||
if (cqspi->is_rzn1)
|
||||
return false;
|
||||
} else if (!all_false) {
|
||||
|
||||
@@ -54,7 +54,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
|
||||
host->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
host->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
|
||||
|
||||
err = devm_spi_register_controller(&pdev->dev, host);
|
||||
err = spi_register_controller(host);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "register host failed: %d\n", err);
|
||||
goto fail;
|
||||
@@ -73,8 +73,14 @@ 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[] = {
|
||||
|
||||
@@ -70,7 +70,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
|
||||
|
||||
pci_set_drvdata(pdev, host);
|
||||
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
@@ -90,8 +90,14 @@ 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[] = {
|
||||
|
||||
@@ -152,7 +152,7 @@ static int ch341_probe(struct usb_interface *intf,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctrl = devm_spi_alloc_host(&udev->dev, sizeof(struct ch341_spi_dev));
|
||||
ctrl = devm_spi_alloc_host(&intf->dev, sizeof(struct ch341_spi_dev));
|
||||
if (!ctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -163,7 +163,7 @@ static int ch341_probe(struct usb_interface *intf,
|
||||
ch341->read_pipe = usb_rcvbulkpipe(udev, usb_endpoint_num(in));
|
||||
|
||||
ch341->rx_len = usb_endpoint_maxp(in);
|
||||
ch341->rx_buf = devm_kzalloc(&udev->dev, ch341->rx_len, GFP_KERNEL);
|
||||
ch341->rx_buf = devm_kzalloc(&intf->dev, ch341->rx_len, GFP_KERNEL);
|
||||
if (!ch341->rx_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -171,19 +171,18 @@ static int ch341_probe(struct usb_interface *intf,
|
||||
if (!ch341->rx_urb)
|
||||
return -ENOMEM;
|
||||
|
||||
ch341->tx_buf =
|
||||
devm_kzalloc(&udev->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
|
||||
if (!ch341->tx_buf)
|
||||
return -ENOMEM;
|
||||
ch341->tx_buf = devm_kzalloc(&intf->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
|
||||
if (!ch341->tx_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_urb;
|
||||
}
|
||||
|
||||
usb_fill_bulk_urb(ch341->rx_urb, udev, ch341->read_pipe, ch341->rx_buf,
|
||||
ch341->rx_len, ch341_recv, ch341);
|
||||
|
||||
ret = usb_submit_urb(ch341->rx_urb, GFP_KERNEL);
|
||||
if (ret) {
|
||||
usb_free_urb(ch341->rx_urb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (ret)
|
||||
goto err_free_urb;
|
||||
|
||||
ctrl->bus_num = -1;
|
||||
ctrl->mode_bits = SPI_CPHA;
|
||||
@@ -195,21 +194,34 @@ static int ch341_probe(struct usb_interface *intf,
|
||||
|
||||
ret = ch341_config_stream(ch341);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_kill_urb;
|
||||
|
||||
ret = ch341_enable_pins(ch341, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_kill_urb;
|
||||
|
||||
ret = spi_register_controller(ctrl);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_disable_pins;
|
||||
|
||||
ch341->spidev = spi_new_device(ctrl, &chip);
|
||||
if (!ch341->spidev)
|
||||
return -ENOMEM;
|
||||
if (!ch341->spidev) {
|
||||
ret = -ENOMEM;
|
||||
goto err_unregister;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
spi_unregister_controller(ctrl);
|
||||
err_disable_pins:
|
||||
ch341_enable_pins(ch341, false);
|
||||
err_kill_urb:
|
||||
usb_kill_urb(ch341->rx_urb);
|
||||
err_free_urb:
|
||||
usb_free_urb(ch341->rx_urb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ch341_disconnect(struct usb_interface *intf)
|
||||
@@ -219,6 +231,7 @@ static void ch341_disconnect(struct usb_interface *intf)
|
||||
spi_unregister_device(ch341->spidev);
|
||||
spi_unregister_controller(ch341->ctrl);
|
||||
ch341_enable_pins(ch341, false);
|
||||
usb_kill_urb(ch341->rx_urb);
|
||||
usb_free_urb(ch341->rx_urb);
|
||||
}
|
||||
|
||||
|
||||
@@ -410,9 +410,9 @@ static int mcfqspi_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, host);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
status = devm_spi_register_controller(&pdev->dev, host);
|
||||
status = spi_register_controller(host);
|
||||
if (status) {
|
||||
dev_dbg(&pdev->dev, "devm_spi_register_controller failed\n");
|
||||
dev_dbg(&pdev->dev, "failed to register controller\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
@@ -436,11 +436,17 @@ 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);
|
||||
/* disable the hardware (set the baud rate to 0) */
|
||||
mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
|
||||
|
||||
mcfqspi_cs_teardown(mcfqspi);
|
||||
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -367,10 +367,10 @@ static int cs42l43_spi_probe(struct platform_device *pdev)
|
||||
ret = devm_add_action_or_reset(priv->dev, cs42l43_release_of_node, fwnode);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
fwnode_property_read_u32(xu_fwnode, "01fa-sidecar-instances", &nsidecars);
|
||||
}
|
||||
|
||||
fwnode_property_read_u32(xu_fwnode, "01fa-sidecar-instances", &nsidecars);
|
||||
|
||||
/*
|
||||
* Depending on the value of nsidecars we either create a software node
|
||||
* or assign an fwnode. We don't want software node to be attached to
|
||||
|
||||
@@ -758,7 +758,7 @@ static int dln2_spi_probe(struct platform_device *pdev)
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register host\n");
|
||||
goto exit_register;
|
||||
@@ -783,10 +783,16 @@ 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
|
||||
|
||||
@@ -689,7 +689,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
|
||||
/* make sure that the hardware is disabled */
|
||||
writel(0, espi->mmio + SSPCR1);
|
||||
|
||||
error = devm_spi_register_controller(&pdev->dev, host);
|
||||
error = spi_register_controller(host);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to register SPI host\n");
|
||||
goto fail_free_dma;
|
||||
@@ -713,7 +713,13 @@ 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[] = {
|
||||
|
||||
@@ -718,7 +718,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret < 0)
|
||||
goto err_pm;
|
||||
|
||||
@@ -782,7 +782,15 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
|
||||
|
||||
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
|
||||
|
||||
@@ -75,14 +75,20 @@
|
||||
#define CFGR1_PCSPOL_MASK GENMASK(11, 8)
|
||||
#define CFGR1_NOSTALL BIT(3)
|
||||
#define CFGR1_HOST BIT(0)
|
||||
#define FCR_RXWATER GENMASK(18, 16)
|
||||
#define FCR_TXWATER GENMASK(2, 0)
|
||||
#define FSR_TXCOUNT (0xFF)
|
||||
#define RSR_RXEMPTY BIT(1)
|
||||
#define TCR_CPOL BIT(31)
|
||||
#define TCR_CPHA BIT(30)
|
||||
#define TCR_MODE GENMASK(31, 30)
|
||||
#define TCR_PRESCALE GENMASK(29, 27)
|
||||
#define TCR_PCS GENMASK(25, 24)
|
||||
#define TCR_CONT BIT(21)
|
||||
#define TCR_CONTC BIT(20)
|
||||
#define TCR_RXMSK BIT(19)
|
||||
#define TCR_TXMSK BIT(18)
|
||||
#define TCR_FRAMESZ GENMASK(11, 0)
|
||||
|
||||
#define SR_CLEAR_MASK GENMASK(13, 8)
|
||||
|
||||
@@ -95,7 +101,7 @@ struct lpspi_config {
|
||||
u8 bpw;
|
||||
u8 chip_select;
|
||||
u8 prescale;
|
||||
u16 mode;
|
||||
u32 mode;
|
||||
u32 speed_hz;
|
||||
u32 effective_speed_hz;
|
||||
};
|
||||
@@ -112,8 +118,8 @@ struct fsl_lpspi_data {
|
||||
|
||||
void *rx_buf;
|
||||
const void *tx_buf;
|
||||
void (*tx)(struct fsl_lpspi_data *);
|
||||
void (*rx)(struct fsl_lpspi_data *);
|
||||
void (*tx)(struct fsl_lpspi_data *fsl_lpspi);
|
||||
void (*rx)(struct fsl_lpspi_data *fsl_lpspi);
|
||||
|
||||
u32 remain;
|
||||
u8 watermark;
|
||||
@@ -256,9 +262,7 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
|
||||
|
||||
txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
|
||||
|
||||
while (txfifo_cnt < fsl_lpspi->txfifosize) {
|
||||
if (!fsl_lpspi->remain)
|
||||
break;
|
||||
while (txfifo_cnt < fsl_lpspi->txfifosize && fsl_lpspi->remain) {
|
||||
fsl_lpspi->tx(fsl_lpspi);
|
||||
txfifo_cnt++;
|
||||
}
|
||||
@@ -271,8 +275,9 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
|
||||
}
|
||||
|
||||
fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
|
||||
} else
|
||||
} else {
|
||||
fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE);
|
||||
}
|
||||
}
|
||||
|
||||
static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
|
||||
@@ -281,16 +286,14 @@ static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
|
||||
fsl_lpspi->rx(fsl_lpspi);
|
||||
}
|
||||
|
||||
static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
|
||||
struct spi_device *spi)
|
||||
static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
|
||||
{
|
||||
u32 temp = 0;
|
||||
|
||||
temp |= fsl_lpspi->config.bpw - 1;
|
||||
temp |= (fsl_lpspi->config.mode & 0x3) << 30;
|
||||
temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
|
||||
temp |= FIELD_PREP(TCR_FRAMESZ, fsl_lpspi->config.bpw - 1);
|
||||
temp |= FIELD_PREP(TCR_PCS, fsl_lpspi->config.chip_select);
|
||||
if (!fsl_lpspi->is_target) {
|
||||
temp |= fsl_lpspi->config.prescale << 27;
|
||||
temp |= FIELD_PREP(TCR_PRESCALE, fsl_lpspi->config.prescale);
|
||||
/*
|
||||
* Set TCR_CONT will keep SS asserted after current transfer.
|
||||
* For the first transfer, clear TCR_CONTC to assert SS.
|
||||
@@ -305,10 +308,10 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
|
||||
}
|
||||
}
|
||||
|
||||
if (spi->mode & SPI_CPOL)
|
||||
if (fsl_lpspi->config.mode & SPI_CPOL)
|
||||
temp |= TCR_CPOL;
|
||||
|
||||
if (spi->mode & SPI_CPHA)
|
||||
if (fsl_lpspi->config.mode & SPI_CPHA)
|
||||
temp |= TCR_CPHA;
|
||||
|
||||
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
|
||||
@@ -318,17 +321,18 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
|
||||
|
||||
static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
|
||||
{
|
||||
u8 watermark = fsl_lpspi->watermark >> 1;
|
||||
u32 temp;
|
||||
|
||||
if (!fsl_lpspi->usedma)
|
||||
temp = fsl_lpspi->watermark >> 1 |
|
||||
(fsl_lpspi->watermark >> 1) << 16;
|
||||
temp = FIELD_PREP(FCR_TXWATER, watermark) |
|
||||
FIELD_PREP(FCR_RXWATER, watermark);
|
||||
else
|
||||
temp = fsl_lpspi->watermark >> 1;
|
||||
temp = FIELD_PREP(FCR_TXWATER, watermark);
|
||||
|
||||
writel(temp, fsl_lpspi->base + IMX7ULP_FCR);
|
||||
|
||||
dev_dbg(fsl_lpspi->dev, "FCR=0x%x\n", temp);
|
||||
dev_dbg(fsl_lpspi->dev, "FCR=0x%08x\n", temp);
|
||||
}
|
||||
|
||||
static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
|
||||
@@ -348,11 +352,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (config.speed_hz > perclk_rate / 2) {
|
||||
if (config.speed_hz > perclk_rate / 2)
|
||||
div = 2;
|
||||
} else {
|
||||
else
|
||||
div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
|
||||
}
|
||||
|
||||
for (prescale = 0; prescale <= prescale_max; prescale++) {
|
||||
scldiv = div / (1 << prescale) - 2;
|
||||
@@ -466,9 +469,6 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
|
||||
struct fsl_lpspi_data *fsl_lpspi =
|
||||
spi_controller_get_devdata(spi->controller);
|
||||
|
||||
if (t == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
fsl_lpspi->config.mode = spi->mode;
|
||||
fsl_lpspi->config.bpw = t->bits_per_word;
|
||||
fsl_lpspi->config.speed_hz = t->speed_hz;
|
||||
@@ -517,15 +517,12 @@ static int fsl_lpspi_prepare_message(struct spi_controller *controller,
|
||||
fsl_lpspi->usedma = false;
|
||||
ret = fsl_lpspi_setup_transfer(controller, spi, t);
|
||||
|
||||
if (fsl_lpspi_can_dma(controller, spi, t))
|
||||
fsl_lpspi->usedma = true;
|
||||
else
|
||||
fsl_lpspi->usedma = false;
|
||||
fsl_lpspi->usedma = fsl_lpspi_can_dma(controller, spi, t);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
fsl_lpspi_set_cmd(fsl_lpspi, spi);
|
||||
fsl_lpspi_set_cmd(fsl_lpspi);
|
||||
|
||||
/* No IRQs */
|
||||
writel(0, fsl_lpspi->base + IMX7ULP_IER);
|
||||
@@ -574,7 +571,7 @@ static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
|
||||
static void fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
|
||||
{
|
||||
u32 temp;
|
||||
|
||||
@@ -589,8 +586,6 @@ static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
|
||||
|
||||
/* W1C for all flags in SR */
|
||||
writel(SR_CLEAR_MASK, fsl_lpspi->base + IMX7ULP_SR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fsl_lpspi_dma_rx_callback(void *cookie)
|
||||
@@ -794,10 +789,7 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
|
||||
spi_controller_get_devdata(controller);
|
||||
int ret;
|
||||
|
||||
if (fsl_lpspi_can_dma(controller, spi, t))
|
||||
fsl_lpspi->usedma = true;
|
||||
else
|
||||
fsl_lpspi->usedma = false;
|
||||
fsl_lpspi->usedma = fsl_lpspi_can_dma(controller, spi, t);
|
||||
|
||||
ret = fsl_lpspi_setup_transfer(controller, spi, t);
|
||||
if (ret < 0)
|
||||
@@ -805,7 +797,7 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
|
||||
|
||||
t->effective_speed_hz = fsl_lpspi->config.effective_speed_hz;
|
||||
|
||||
fsl_lpspi_set_cmd(fsl_lpspi, spi);
|
||||
fsl_lpspi_set_cmd(fsl_lpspi);
|
||||
fsl_lpspi->is_first_byte = false;
|
||||
|
||||
if (fsl_lpspi->usedma)
|
||||
|
||||
@@ -633,7 +633,7 @@ static int fsl_qspi_do_op(struct fsl_qspi *q, const struct spi_mem_op *op)
|
||||
void __iomem *base = q->iobase;
|
||||
int err = 0;
|
||||
|
||||
init_completion(&q->c);
|
||||
reinit_completion(&q->c);
|
||||
|
||||
/*
|
||||
* Always start the sequence at the same index since we update
|
||||
@@ -965,6 +965,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
init_completion(&q->c);
|
||||
ret = devm_request_irq(dev, ret,
|
||||
fsl_qspi_irq_handler, 0, pdev->name, q);
|
||||
if (ret) {
|
||||
|
||||
@@ -614,7 +614,7 @@ static struct spi_controller *fsl_spi_probe(struct device *dev,
|
||||
|
||||
mpc8xxx_spi_write_reg(®_base->mode, regval);
|
||||
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret < 0)
|
||||
goto err_probe;
|
||||
|
||||
@@ -705,7 +705,13 @@ 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 = {
|
||||
@@ -751,7 +757,13 @@ 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");
|
||||
|
||||
@@ -196,9 +196,22 @@ static void hisi_spi_flush_fifo(struct hisi_spi *hs)
|
||||
unsigned long limit = loops_per_jiffy << 1;
|
||||
|
||||
do {
|
||||
while (hisi_spi_rx_not_empty(hs))
|
||||
unsigned long inner_limit = loops_per_jiffy;
|
||||
|
||||
while (hisi_spi_rx_not_empty(hs) && --inner_limit) {
|
||||
readl(hs->regs + HISI_SPI_DOUT);
|
||||
} while (hisi_spi_busy(hs) && limit--);
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
if (!inner_limit) {
|
||||
dev_warn_ratelimited(hs->dev, "RX FIFO flush timeout\n");
|
||||
break;
|
||||
}
|
||||
|
||||
} while (hisi_spi_busy(hs) && --limit);
|
||||
|
||||
if (!limit)
|
||||
dev_warn_ratelimited(hs->dev, "SPI busy timeout\n");
|
||||
}
|
||||
|
||||
/* Disable the controller and all interrupts */
|
||||
|
||||
@@ -643,7 +643,7 @@ static int img_spfi_probe(struct platform_device *pdev)
|
||||
pm_runtime_set_active(spfi->dev);
|
||||
pm_runtime_enable(spfi->dev);
|
||||
|
||||
ret = devm_spi_register_controller(spfi->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto disable_pm;
|
||||
|
||||
@@ -669,6 +669,10 @@ 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)
|
||||
dma_release_channel(spfi->tx_ch);
|
||||
if (spfi->rx_ch)
|
||||
@@ -679,6 +683,8 @@ 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
|
||||
|
||||
@@ -2231,11 +2231,9 @@ static int spi_imx_probe(struct platform_device *pdev)
|
||||
target_mode = devtype_data->has_targetmode &&
|
||||
of_property_read_bool(np, "spi-slave");
|
||||
if (target_mode)
|
||||
controller = spi_alloc_target(&pdev->dev,
|
||||
sizeof(struct spi_imx_data));
|
||||
controller = devm_spi_alloc_target(&pdev->dev, sizeof(*spi_imx));
|
||||
else
|
||||
controller = spi_alloc_host(&pdev->dev,
|
||||
sizeof(struct spi_imx_data));
|
||||
controller = devm_spi_alloc_host(&pdev->dev, sizeof(*spi_imx));
|
||||
if (!controller)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2304,40 +2302,31 @@ static int spi_imx_probe(struct platform_device *pdev)
|
||||
init_completion(&spi_imx->xfer_done);
|
||||
|
||||
spi_imx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(spi_imx->base)) {
|
||||
ret = PTR_ERR(spi_imx->base);
|
||||
goto out_controller_put;
|
||||
}
|
||||
if (IS_ERR(spi_imx->base))
|
||||
return PTR_ERR(spi_imx->base);
|
||||
|
||||
spi_imx->base_phys = res->start;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
goto out_controller_put;
|
||||
}
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, spi_imx_isr, 0,
|
||||
dev_name(&pdev->dev), spi_imx);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
|
||||
goto out_controller_put;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "can't get irq%d\n", irq);
|
||||
|
||||
spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
|
||||
if (IS_ERR(spi_imx->clk_ipg)) {
|
||||
ret = PTR_ERR(spi_imx->clk_ipg);
|
||||
goto out_controller_put;
|
||||
}
|
||||
if (IS_ERR(spi_imx->clk_ipg))
|
||||
return PTR_ERR(spi_imx->clk_ipg);
|
||||
|
||||
spi_imx->clk_per = devm_clk_get(&pdev->dev, "per");
|
||||
if (IS_ERR(spi_imx->clk_per)) {
|
||||
ret = PTR_ERR(spi_imx->clk_per);
|
||||
goto out_controller_put;
|
||||
}
|
||||
if (IS_ERR(spi_imx->clk_per))
|
||||
return PTR_ERR(spi_imx->clk_per);
|
||||
|
||||
ret = clk_prepare_enable(spi_imx->clk_per);
|
||||
if (ret)
|
||||
goto out_controller_put;
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(spi_imx->clk_ipg);
|
||||
if (ret)
|
||||
@@ -2389,8 +2378,6 @@ static int spi_imx_probe(struct platform_device *pdev)
|
||||
clk_disable_unprepare(spi_imx->clk_ipg);
|
||||
out_put_per:
|
||||
clk_disable_unprepare(spi_imx->clk_per);
|
||||
out_controller_put:
|
||||
spi_controller_put(controller);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -994,7 +994,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
|
||||
"Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
|
||||
revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
|
||||
|
||||
err = devm_spi_register_controller(dev, host);
|
||||
err = spi_register_controller(host);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to register spi host\n");
|
||||
goto err_wq_destroy;
|
||||
@@ -1016,6 +1016,10 @@ 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);
|
||||
lantiq_ssc_writel(spi, 0, LTQ_SPI_CLC);
|
||||
rx_fifo_flush(spi);
|
||||
@@ -1024,6 +1028,8 @@ 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 = {
|
||||
|
||||
@@ -1081,7 +1081,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "spi registration failed\n");
|
||||
goto out_host;
|
||||
@@ -1099,8 +1099,14 @@ 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 = {
|
||||
|
||||
@@ -692,7 +692,7 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
qspi = spi_controller_get_devdata(ctlr);
|
||||
platform_set_drvdata(pdev, qspi);
|
||||
platform_set_drvdata(pdev, ctlr);
|
||||
|
||||
qspi->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(qspi->regs))
|
||||
@@ -732,7 +732,7 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
|
||||
ctlr->num_chipselect = 2;
|
||||
ctlr->use_gpio_descriptors = true;
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"spi_register_controller failed\n");
|
||||
@@ -742,9 +742,13 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
|
||||
|
||||
static void mchp_coreqspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mchp_coreqspi *qspi = platform_get_drvdata(pdev);
|
||||
u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
struct mchp_coreqspi *qspi = spi_controller_get_devdata(ctlr);
|
||||
u32 control;
|
||||
|
||||
spi_unregister_controller(ctlr);
|
||||
|
||||
control = readl_relaxed(qspi->regs + REG_CONTROL);
|
||||
mchp_coreqspi_disable_ints(qspi);
|
||||
control &= ~CONTROL_ENABLE;
|
||||
writel_relaxed(control, qspi->regs + REG_CONTROL);
|
||||
|
||||
@@ -384,7 +384,7 @@ static int mchp_corespi_probe(struct platform_device *pdev)
|
||||
|
||||
mchp_corespi_init(host, spi);
|
||||
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
mchp_corespi_disable_ints(spi);
|
||||
mchp_corespi_disable(spi);
|
||||
@@ -399,6 +399,8 @@ static void mchp_corespi_remove(struct platform_device *pdev)
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct mchp_corespi *spi = spi_controller_get_devdata(host);
|
||||
|
||||
spi_unregister_controller(host);
|
||||
|
||||
mchp_corespi_disable_ints(spi);
|
||||
mchp_corespi_disable(spi);
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ static int mpfs_spi_probe(struct platform_device *pdev)
|
||||
|
||||
mpfs_spi_init(host, spi);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
mpfs_spi_disable_ints(spi);
|
||||
mpfs_spi_disable(spi);
|
||||
@@ -592,6 +592,8 @@ static void mpfs_spi_remove(struct platform_device *pdev)
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct mpfs_spi *spi = spi_controller_get_devdata(host);
|
||||
|
||||
spi_unregister_controller(host);
|
||||
|
||||
mpfs_spi_disable_ints(spi);
|
||||
mpfs_spi_disable(spi);
|
||||
}
|
||||
|
||||
@@ -1325,7 +1325,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
pm_runtime_disable(dev);
|
||||
return dev_err_probe(dev, ret, "failed to register host\n");
|
||||
@@ -1340,6 +1340,8 @@ static void mtk_spi_remove(struct platform_device *pdev)
|
||||
struct mtk_spi *mdata = spi_controller_get_devdata(host);
|
||||
int ret;
|
||||
|
||||
spi_unregister_controller(host);
|
||||
|
||||
cpu_latency_qos_remove_request(&mdata->qos_request);
|
||||
if (mdata->use_spimem && !completion_done(&mdata->spimem_done))
|
||||
complete(&mdata->spimem_done);
|
||||
|
||||
@@ -913,7 +913,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret < 0)
|
||||
goto err_probe;
|
||||
|
||||
@@ -938,6 +938,8 @@ static void mtk_nor_remove(struct platform_device *pdev)
|
||||
struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
|
||||
struct mtk_nor *sp = spi_controller_get_devdata(ctlr);
|
||||
|
||||
spi_unregister_controller(ctlr);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
|
||||
@@ -1303,6 +1303,13 @@ static const struct spi_controller_mem_caps mtk_snand_mem_caps = {
|
||||
.ecc = true,
|
||||
};
|
||||
|
||||
static void mtk_unregister_ecc_engine(void *data)
|
||||
{
|
||||
struct nand_ecc_engine *eng = data;
|
||||
|
||||
nand_ecc_unregister_on_host_hw_engine(eng);
|
||||
}
|
||||
|
||||
static irqreturn_t mtk_snand_irq(int irq, void *id)
|
||||
{
|
||||
struct mtk_snand *snf = id;
|
||||
@@ -1443,6 +1450,13 @@ static int mtk_snand_probe(struct platform_device *pdev)
|
||||
goto release_ecc;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(&pdev->dev, mtk_unregister_ecc_engine,
|
||||
&ms->ecc_eng);
|
||||
if (ret) {
|
||||
dev_err_probe(&pdev->dev, ret, "failed to add ECC unregister action\n");
|
||||
goto release_ecc;
|
||||
}
|
||||
|
||||
ctlr->num_chipselect = 1;
|
||||
ctlr->mem_ops = &mtk_snand_mem_ops;
|
||||
ctlr->mem_caps = &mtk_snand_mem_caps;
|
||||
|
||||
@@ -619,7 +619,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto out_pm_runtime_put;
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Cannot register SPI host, %d\n", ret);
|
||||
goto out_pm_runtime_put;
|
||||
@@ -650,11 +650,17 @@ 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);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
mxs_spi_runtime_suspend(&pdev->dev);
|
||||
|
||||
dma_release_channel(ssp->dmach);
|
||||
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
static struct platform_driver mxs_spi_driver = {
|
||||
|
||||
@@ -715,7 +715,6 @@ static int npcm_fiu_probe(struct platform_device *pdev)
|
||||
|
||||
fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
|
||||
|
||||
platform_set_drvdata(pdev, fiu);
|
||||
fiu->dev = dev;
|
||||
|
||||
regbase = devm_platform_ioremap_resource_byname(pdev, "control");
|
||||
@@ -738,8 +737,6 @@ static int npcm_fiu_probe(struct platform_device *pdev)
|
||||
fiu->spix_mode = of_property_read_bool(dev->of_node,
|
||||
"nuvoton,spix-mode");
|
||||
|
||||
platform_set_drvdata(pdev, fiu);
|
||||
|
||||
ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
|
||||
| SPI_TX_DUAL | SPI_TX_QUAD;
|
||||
ctrl->setup = npcm_fiu_setup;
|
||||
@@ -750,10 +747,6 @@ static int npcm_fiu_probe(struct platform_device *pdev)
|
||||
return devm_spi_register_controller(dev, ctrl);
|
||||
}
|
||||
|
||||
static void npcm_fiu_remove(struct platform_device *pdev)
|
||||
{
|
||||
}
|
||||
|
||||
MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
|
||||
|
||||
static struct platform_driver npcm_fiu_driver = {
|
||||
@@ -763,7 +756,6 @@ static struct platform_driver npcm_fiu_driver = {
|
||||
.of_match_table = npcm_fiu_dt_ids,
|
||||
},
|
||||
.probe = npcm_fiu_probe,
|
||||
.remove = npcm_fiu_remove,
|
||||
};
|
||||
module_platform_driver(npcm_fiu_driver);
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
|
||||
/* set to default clock rate */
|
||||
npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto out_disable_clk;
|
||||
|
||||
@@ -434,8 +434,14 @@ 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[] = {
|
||||
|
||||
@@ -996,7 +996,7 @@ static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
|
||||
reg = reg | FSPI_IPRXFCR_CLR;
|
||||
fspi_writel(f, reg, base + FSPI_IPRXFCR);
|
||||
|
||||
init_completion(&f->c);
|
||||
reinit_completion(&f->c);
|
||||
|
||||
fspi_writel(f, op->addr.val, base + FSPI_IPCR0);
|
||||
/*
|
||||
@@ -1365,6 +1365,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to disable clock");
|
||||
|
||||
init_completion(&f->c);
|
||||
ret = devm_request_irq(dev, irq,
|
||||
nxp_fspi_irq_handler, 0, pdev->name, f);
|
||||
if (ret)
|
||||
|
||||
@@ -958,7 +958,7 @@ static int nxp_xspi_do_op(struct nxp_xspi *xspi, const struct spi_mem_op *op)
|
||||
writel(reg, base + XSPI_RBCT);
|
||||
}
|
||||
|
||||
init_completion(&xspi->c);
|
||||
reinit_completion(&xspi->c);
|
||||
|
||||
/* Config the data address */
|
||||
writel(op->addr.val + xspi->memmap_phy, base + XSPI_SFP_TG_SFAR);
|
||||
@@ -1273,6 +1273,7 @@ static int nxp_xspi_probe(struct platform_device *pdev)
|
||||
|
||||
nxp_xspi_default_setup(xspi);
|
||||
|
||||
init_completion(&xspi->c);
|
||||
ret = devm_request_irq(dev, irq,
|
||||
nxp_xspi_irq_handler, 0, pdev->name, xspi);
|
||||
if (ret)
|
||||
|
||||
@@ -942,10 +942,16 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
|
||||
|
||||
l = mcspi_cached_chconf0(spi);
|
||||
|
||||
/* standard 4-wire host mode: SCK, MOSI/out, MISO/in, nCS
|
||||
* REVISIT: this controller could support SPI_3WIRE mode.
|
||||
*/
|
||||
if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
|
||||
if (spi->mode & SPI_3WIRE) {
|
||||
if (t && !t->tx_buf) {
|
||||
l &= ~OMAP2_MCSPI_CHCONF_IS;
|
||||
l |= OMAP2_MCSPI_CHCONF_DPE0;
|
||||
} else if (t && !t->rx_buf) {
|
||||
l |= OMAP2_MCSPI_CHCONF_IS;
|
||||
l &= ~OMAP2_MCSPI_CHCONF_DPE0;
|
||||
}
|
||||
l |= OMAP2_MCSPI_CHCONF_DPE1;
|
||||
} else if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
|
||||
l &= ~OMAP2_MCSPI_CHCONF_IS;
|
||||
l &= ~OMAP2_MCSPI_CHCONF_DPE1;
|
||||
l |= OMAP2_MCSPI_CHCONF_DPE0;
|
||||
@@ -1178,6 +1184,7 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr,
|
||||
omap2_mcspi_set_cs(spi, spi->mode & SPI_CS_HIGH);
|
||||
|
||||
if (par_override ||
|
||||
(spi->mode & SPI_3WIRE) ||
|
||||
(t->speed_hz != spi->max_speed_hz) ||
|
||||
(t->bits_per_word != spi->bits_per_word)) {
|
||||
par_override = 1;
|
||||
@@ -1484,7 +1491,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* the spi->mode bits understood by this driver: */
|
||||
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
|
||||
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_3WIRE;
|
||||
ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
|
||||
ctlr->setup = omap2_mcspi_setup;
|
||||
ctlr->auto_runtime_pm = true;
|
||||
@@ -1585,7 +1592,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
|
||||
if (status < 0)
|
||||
goto disable_pm;
|
||||
|
||||
status = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
status = spi_register_controller(ctlr);
|
||||
if (status < 0)
|
||||
goto disable_pm;
|
||||
|
||||
@@ -1606,11 +1613,17 @@ 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);
|
||||
|
||||
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 */
|
||||
|
||||
@@ -642,7 +642,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
|
||||
host->prepare_transfer_hardware = pic32_sqi_prepare_hardware;
|
||||
host->unprepare_transfer_hardware = pic32_sqi_unprepare_hardware;
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&host->dev, "failed registering spi host\n");
|
||||
free_irq(sqi->irq, sqi);
|
||||
@@ -665,9 +665,15 @@ 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[] = {
|
||||
|
||||
@@ -821,7 +821,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* register host */
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&host->dev, "failed registering spi host\n");
|
||||
goto err_bailout;
|
||||
@@ -840,11 +840,16 @@ static int pic32_spi_probe(struct platform_device *pdev)
|
||||
|
||||
static void pic32_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pic32_spi *pic32s;
|
||||
struct pic32_spi *pic32s = platform_get_drvdata(pdev);
|
||||
|
||||
spi_controller_get(pic32s->host);
|
||||
|
||||
spi_unregister_controller(pic32s->host);
|
||||
|
||||
pic32s = platform_get_drvdata(pdev);
|
||||
pic32_spi_disable(pic32s);
|
||||
pic32_spi_dma_unprep(pic32s);
|
||||
|
||||
spi_controller_put(pic32s->host);
|
||||
}
|
||||
|
||||
static const struct of_device_id pic32_spi_of_match[] = {
|
||||
|
||||
@@ -1127,11 +1127,11 @@ static inline void pl022_dma_remove(struct pl022 *pl022)
|
||||
*
|
||||
* This function handles interrupts generated for an interrupt based transfer.
|
||||
* If a receive overrun (ROR) interrupt is there then we disable SSP, flag the
|
||||
* current message's state as STATE_ERROR and schedule the tasklet
|
||||
* pump_transfers which will do the postprocessing of the current message by
|
||||
* calling giveback(). Otherwise it reads data from RX FIFO till there is no
|
||||
* more data, and writes data in TX FIFO till it is not full. If we complete
|
||||
* the transfer we move to the next transfer and schedule the tasklet.
|
||||
* current transfer with SPI_TRANS_FAIL_IO and call
|
||||
* spi_finalize_current_transfer() to let the core finish the message.
|
||||
* Otherwise it reads data from RX FIFO till there is no more data, and writes
|
||||
* data in TX FIFO till it is not full. When the transfer is complete we call
|
||||
* spi_finalize_current_transfer() so the core can schedule the next one.
|
||||
*/
|
||||
static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
|
||||
{
|
||||
@@ -1956,7 +1956,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
|
||||
/* Register with the SPI framework */
|
||||
amba_set_drvdata(adev, pl022);
|
||||
status = devm_spi_register_controller(&adev->dev, host);
|
||||
status = spi_register_controller(host);
|
||||
if (status != 0) {
|
||||
dev_err_probe(&adev->dev, status,
|
||||
"problem registering spi host\n");
|
||||
@@ -1997,6 +1997,10 @@ pl022_remove(struct amba_device *adev)
|
||||
if (!pl022)
|
||||
return;
|
||||
|
||||
spi_controller_get(pl022->host);
|
||||
|
||||
spi_unregister_controller(pl022->host);
|
||||
|
||||
/*
|
||||
* undo pm_runtime_put() in probe. I assume that we're not
|
||||
* accessing the primecell here.
|
||||
@@ -2008,6 +2012,8 @@ pl022_remove(struct amba_device *adev)
|
||||
pl022_dma_remove(pl022);
|
||||
|
||||
amba_release_regions(adev);
|
||||
|
||||
spi_controller_put(pl022->host);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -29,9 +29,9 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
|
||||
|
||||
/*
|
||||
* It is possible that one CPU is handling ROR interrupt and other
|
||||
* just gets DMA completion. Calling pump_transfers() twice for the
|
||||
* same transfer leads to problems thus we prevent concurrent calls
|
||||
* by using dma_running.
|
||||
* just gets DMA completion. Calling spi_finalize_current_transfer()
|
||||
* twice for the same transfer leads to problems thus we prevent
|
||||
* concurrent calls by using dma_running.
|
||||
*/
|
||||
if (atomic_dec_and_test(&drv_data->dma_running)) {
|
||||
/*
|
||||
|
||||
@@ -796,7 +796,7 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
|
||||
* The function calculates parameters for all cases and chooses the one closest
|
||||
* to the asked baud rate.
|
||||
*/
|
||||
static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)
|
||||
static unsigned int quark_x1000_get_clk_div(u32 rate, u32 *dds)
|
||||
{
|
||||
unsigned long xtal = 200000000;
|
||||
unsigned long fref = xtal / 2; /* mandatory division by 2,
|
||||
@@ -885,12 +885,12 @@ static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)
|
||||
return q - 1;
|
||||
}
|
||||
|
||||
static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
|
||||
static unsigned int ssp_get_clk_div(struct driver_data *drv_data, u32 rate)
|
||||
{
|
||||
unsigned long ssp_clk = drv_data->controller->max_speed_hz;
|
||||
u32 ssp_clk = drv_data->controller->max_speed_hz;
|
||||
const struct ssp_device *ssp = drv_data->ssp;
|
||||
|
||||
rate = min_t(int, ssp_clk, rate);
|
||||
rate = min(ssp_clk, rate);
|
||||
|
||||
/*
|
||||
* Calculate the divisor for the SCR (Serial Clock Rate), avoiding
|
||||
@@ -902,8 +902,7 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
|
||||
return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff;
|
||||
}
|
||||
|
||||
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
|
||||
int rate)
|
||||
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, u32 rate)
|
||||
{
|
||||
struct chip_data *chip =
|
||||
spi_get_ctldata(drv_data->controller->cur_msg->spi);
|
||||
|
||||
@@ -1193,7 +1193,7 @@ static int spi_qup_probe(struct platform_device *pdev)
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = devm_spi_register_controller(dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto disable_pm;
|
||||
|
||||
@@ -1320,6 +1320,10 @@ 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);
|
||||
|
||||
if (ret >= 0) {
|
||||
@@ -1339,6 +1343,8 @@ 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[] = {
|
||||
|
||||
@@ -767,9 +767,9 @@ static int rockchip_spi_probe(struct platform_device *pdev)
|
||||
target_mode = of_property_read_bool(np, "spi-slave");
|
||||
|
||||
if (target_mode)
|
||||
ctlr = spi_alloc_target(&pdev->dev, sizeof(struct rockchip_spi));
|
||||
ctlr = devm_spi_alloc_target(&pdev->dev, sizeof(*rs));
|
||||
else
|
||||
ctlr = spi_alloc_host(&pdev->dev, sizeof(struct rockchip_spi));
|
||||
ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*rs));
|
||||
|
||||
if (!ctlr)
|
||||
return -ENOMEM;
|
||||
@@ -780,35 +780,31 @@ static int rockchip_spi_probe(struct platform_device *pdev)
|
||||
|
||||
/* Get basic io resource and map it */
|
||||
rs->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
|
||||
if (IS_ERR(rs->regs)) {
|
||||
ret = PTR_ERR(rs->regs);
|
||||
goto err_put_ctlr;
|
||||
}
|
||||
if (IS_ERR(rs->regs))
|
||||
return PTR_ERR(rs->regs);
|
||||
|
||||
rs->apb_pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk");
|
||||
if (IS_ERR(rs->apb_pclk)) {
|
||||
ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk),
|
||||
"Failed to get apb_pclk\n");
|
||||
goto err_put_ctlr;
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk),
|
||||
"Failed to get apb_pclk\n");
|
||||
}
|
||||
|
||||
rs->spiclk = devm_clk_get_enabled(&pdev->dev, "spiclk");
|
||||
if (IS_ERR(rs->spiclk)) {
|
||||
ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk),
|
||||
"Failed to get spi_pclk\n");
|
||||
goto err_put_ctlr;
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk),
|
||||
"Failed to get spi_pclk\n");
|
||||
}
|
||||
|
||||
spi_enable_chip(rs, false);
|
||||
|
||||
ret = platform_get_irq(pdev, 0);
|
||||
if (ret < 0)
|
||||
goto err_put_ctlr;
|
||||
return ret;
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, ret, rockchip_spi_isr, 0,
|
||||
dev_name(&pdev->dev), ctlr);
|
||||
if (ret)
|
||||
goto err_put_ctlr;
|
||||
return ret;
|
||||
|
||||
rs->dev = &pdev->dev;
|
||||
rs->freq = clk_get_rate(rs->spiclk);
|
||||
@@ -830,10 +826,8 @@ static int rockchip_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
rs->fifo_len = get_fifo_len(rs);
|
||||
if (!rs->fifo_len) {
|
||||
ret = dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n");
|
||||
goto err_put_ctlr;
|
||||
}
|
||||
if (!rs->fifo_len)
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n");
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, ROCKCHIP_AUTOSUSPEND_TIMEOUT);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
@@ -908,7 +902,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register controller\n");
|
||||
goto err_free_dma_rx;
|
||||
@@ -924,18 +918,18 @@ static int rockchip_spi_probe(struct platform_device *pdev)
|
||||
dma_release_channel(ctlr->dma_tx);
|
||||
err_disable_pm_runtime:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
err_put_ctlr:
|
||||
spi_controller_put(ctlr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rockchip_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr = spi_controller_get(platform_get_drvdata(pdev));
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
spi_unregister_controller(ctlr);
|
||||
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
@@ -944,8 +938,6 @@ static void rockchip_spi_remove(struct platform_device *pdev)
|
||||
dma_release_channel(ctlr->dma_tx);
|
||||
if (ctlr->dma_rx)
|
||||
dma_release_channel(ctlr->dma_rx);
|
||||
|
||||
spi_controller_put(ctlr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -1171,8 +1171,14 @@ 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 = {
|
||||
@@ -1376,9 +1382,9 @@ static int rspi_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
dev_warn(&pdev->dev, "DMA not available, using PIO\n");
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
|
||||
dev_err(&pdev->dev, "failed to register controller\n");
|
||||
goto error3;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
|
||||
/* Register SPBR */
|
||||
#define RSPI_SPBR_SPR_MIN 0
|
||||
#define RSPI_SPBR_SPR_PCLK_MIN 1
|
||||
#define RSPI_SPBR_SPR_MAX 255
|
||||
|
||||
/* Register SPCMD */
|
||||
@@ -77,6 +76,8 @@
|
||||
|
||||
#define RSPI_RESET_NUM 2
|
||||
|
||||
#define RSPI_MAX_SPEED_HZ 50000000
|
||||
|
||||
struct rzv2h_rspi_best_clock {
|
||||
struct clk *clk;
|
||||
unsigned long clk_rate;
|
||||
@@ -87,9 +88,9 @@ struct rzv2h_rspi_best_clock {
|
||||
};
|
||||
|
||||
struct rzv2h_rspi_info {
|
||||
void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
|
||||
void (*find_tclk_rate)(struct clk *clk, u32 hz,
|
||||
struct rzv2h_rspi_best_clock *best_clk);
|
||||
void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high,
|
||||
void (*find_pclk_rate)(struct clk *clk, u32 hz,
|
||||
struct rzv2h_rspi_best_clock *best_clk);
|
||||
const char *tclk_name;
|
||||
unsigned int fifo_size;
|
||||
@@ -412,7 +413,6 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
|
||||
}
|
||||
|
||||
static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
|
||||
u8 spr_min, u8 spr_max,
|
||||
struct rzv2h_rspi_best_clock *best)
|
||||
{
|
||||
long clk_rate, clk_min_rate, clk_max_rate;
|
||||
@@ -463,7 +463,7 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
|
||||
* minimum SPR that is in the valid range.
|
||||
*/
|
||||
min_rate_spr = DIV_ROUND_CLOSEST(clk_min_rate, rate_div) - 1;
|
||||
if (min_rate_spr > spr_max)
|
||||
if (min_rate_spr > RSPI_SPBR_SPR_MAX)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -473,14 +473,14 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
|
||||
* maximum SPR that is in the valid range.
|
||||
*/
|
||||
max_rate_spr = DIV_ROUND_CLOSEST(clk_max_rate, rate_div) - 1;
|
||||
if (max_rate_spr < spr_min)
|
||||
if (max_rate_spr < RSPI_SPBR_SPR_MIN)
|
||||
break;
|
||||
|
||||
if (min_rate_spr < spr_min)
|
||||
min_rate_spr = spr_min;
|
||||
if (min_rate_spr < RSPI_SPBR_SPR_MIN)
|
||||
min_rate_spr = RSPI_SPBR_SPR_MIN;
|
||||
|
||||
if (max_rate_spr > spr_max)
|
||||
max_rate_spr = spr_max;
|
||||
if (max_rate_spr > RSPI_SPBR_SPR_MAX)
|
||||
max_rate_spr = RSPI_SPBR_SPR_MAX;
|
||||
|
||||
for (spr = min_rate_spr; spr <= max_rate_spr; spr++) {
|
||||
clk_rate = (spr + 1) * rate_div;
|
||||
@@ -511,7 +511,6 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
|
||||
}
|
||||
|
||||
static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
|
||||
u8 spr_min, u8 spr_max,
|
||||
struct rzv2h_rspi_best_clock *best)
|
||||
{
|
||||
unsigned long clk_rate;
|
||||
@@ -533,7 +532,18 @@ static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
|
||||
for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
|
||||
spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1)));
|
||||
spr--;
|
||||
if (spr >= spr_min && spr <= spr_max)
|
||||
/*
|
||||
* Skip SPR=0 and BRDV=0 as it is not a valid combination:
|
||||
* - On RZ/G3E, RZ/G3L, RZ/V2H(P) and RZ/V2N, RSPI_n_TCLK is
|
||||
* fixed at 200MHz and SPR=0 and BRDV=0 results in the maximum
|
||||
* bit rate of 100Mbps which is prohibited.
|
||||
* - On RZ/T2H and RZ/N2H, when PCLK (125MHz) is used as
|
||||
* the clock source, SPR=0 and BRDV=0 is explicitly listed
|
||||
* as unsupported in the hardware manual (Table 36.7).
|
||||
*/
|
||||
if (!spr && !brdv)
|
||||
continue;
|
||||
if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
|
||||
goto clock_found;
|
||||
}
|
||||
|
||||
@@ -563,16 +573,10 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
|
||||
};
|
||||
int ret;
|
||||
|
||||
rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
|
||||
RSPI_SPBR_SPR_MAX, &best_clock);
|
||||
rspi->info->find_tclk_rate(rspi->tclk, hz, &best_clock);
|
||||
|
||||
/*
|
||||
* T2H and N2H can also use PCLK as a source, which is 125MHz, but not
|
||||
* when both SPR and BRDV are 0.
|
||||
*/
|
||||
if (best_clock.error && rspi->info->find_pclk_rate)
|
||||
rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN,
|
||||
RSPI_SPBR_SPR_MAX, &best_clock);
|
||||
rspi->info->find_pclk_rate(rspi->pclk, hz, &best_clock);
|
||||
|
||||
if (!best_clock.clk_rate)
|
||||
return -EINVAL;
|
||||
@@ -771,13 +775,7 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
|
||||
RSPI_SPBR_SPR_MAX,
|
||||
RSPI_SPCMD_BRDV_MAX);
|
||||
|
||||
tclk_rate = clk_round_rate(rspi->tclk, ULONG_MAX);
|
||||
if (tclk_rate < 0)
|
||||
return tclk_rate;
|
||||
|
||||
controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
|
||||
RSPI_SPBR_SPR_MIN,
|
||||
RSPI_SPCMD_BRDV_MIN);
|
||||
controller->max_speed_hz = RSPI_MAX_SPEED_HZ;
|
||||
|
||||
controller->dma_tx = devm_dma_request_chan(dev, "tx");
|
||||
if (IS_ERR(controller->dma_tx)) {
|
||||
@@ -811,6 +809,13 @@ static const struct rzv2h_rspi_info rzv2h_info = {
|
||||
.num_clks = 3,
|
||||
};
|
||||
|
||||
static const struct rzv2h_rspi_info rzg3l_info = {
|
||||
.find_tclk_rate = rzv2h_rspi_find_rate_fixed,
|
||||
.tclk_name = "tclk",
|
||||
.fifo_size = 16,
|
||||
.num_clks = 2,
|
||||
};
|
||||
|
||||
static const struct rzv2h_rspi_info rzt2h_info = {
|
||||
.find_tclk_rate = rzv2h_rspi_find_rate_variable,
|
||||
.find_pclk_rate = rzv2h_rspi_find_rate_fixed,
|
||||
@@ -820,6 +825,7 @@ static const struct rzv2h_rspi_info rzt2h_info = {
|
||||
};
|
||||
|
||||
static const struct of_device_id rzv2h_rspi_match[] = {
|
||||
{ .compatible = "renesas,r9a08g046-rspi", &rzg3l_info },
|
||||
{ .compatible = "renesas,r9a09g057-rspi", &rzv2h_info },
|
||||
{ .compatible = "renesas,r9a09g077-rspi", &rzt2h_info },
|
||||
{ /* sentinel */ }
|
||||
|
||||
@@ -1369,7 +1369,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
|
||||
S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
|
||||
sdd->regs + S3C64XX_SPI_INT_EN);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "cannot register SPI host: %d\n", ret);
|
||||
goto err_pm_put;
|
||||
@@ -1399,12 +1399,9 @@ static void s3c64xx_spi_remove(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
|
||||
spi_unregister_controller(host);
|
||||
|
||||
if (!is_polling(sdd)) {
|
||||
dma_release_channel(sdd->rx_dma.ch);
|
||||
dma_release_channel(sdd->tx_dma.ch);
|
||||
}
|
||||
writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
|
||||
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
@@ -257,9 +257,9 @@ static int hspi_probe(struct platform_device *pdev)
|
||||
ctlr->transfer_one_message = hspi_transfer_one_message;
|
||||
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
|
||||
dev_err(&pdev->dev, "failed to register controller\n");
|
||||
goto error2;
|
||||
}
|
||||
|
||||
@@ -279,9 +279,15 @@ 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[] = {
|
||||
|
||||
@@ -1289,9 +1289,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "DMA not available, using PIO\n");
|
||||
|
||||
ret = devm_spi_register_controller(dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "devm_spi_register_controller error.\n");
|
||||
dev_err(dev, "failed to register controller\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
@@ -1309,8 +1309,14 @@ 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[] = {
|
||||
|
||||
@@ -312,7 +312,8 @@ static int sifive_spi_probe(struct platform_device *pdev)
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
spi->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
/* 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);
|
||||
@@ -342,13 +343,6 @@ static int sifive_spi_probe(struct platform_device *pdev)
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
/* Spin up the bus clock before hitting registers */
|
||||
ret = clk_prepare_enable(spi->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to enable bus clock\n");
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
/* probe the number of CS lines */
|
||||
spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
|
||||
sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU);
|
||||
@@ -357,14 +351,14 @@ static int sifive_spi_probe(struct platform_device *pdev)
|
||||
if (!cs_bits) {
|
||||
dev_err(&pdev->dev, "Could not auto probe CS lines\n");
|
||||
ret = -EINVAL;
|
||||
goto disable_clk;
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
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 disable_clk;
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
/* Define our host */
|
||||
@@ -392,22 +386,20 @@ 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 disable_clk;
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
|
||||
irq, host->num_chipselect);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "spi_register_host failed\n");
|
||||
goto disable_clk;
|
||||
goto put_host;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(spi->clk);
|
||||
put_host:
|
||||
spi_controller_put(host);
|
||||
|
||||
@@ -419,9 +411,14 @@ 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);
|
||||
clk_disable_unprepare(spi->clk);
|
||||
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
static int sifive_spi_suspend(struct device *dev)
|
||||
|
||||
@@ -453,7 +453,7 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
clk_disable_unprepare(mdata->spi_clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
@@ -473,7 +473,15 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
|
||||
|
||||
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
|
||||
|
||||
@@ -625,7 +625,7 @@ static int f_ospi_probe(struct platform_device *pdev)
|
||||
of_property_read_u32(dev->of_node, "num-cs", &num_cs);
|
||||
if (num_cs > OSPI_NUM_CS) {
|
||||
dev_err(dev, "num-cs too large: %d\n", num_cs);
|
||||
return -ENOMEM;
|
||||
return -EINVAL;
|
||||
}
|
||||
ctlr->num_chipselect = num_cs;
|
||||
|
||||
|
||||
@@ -977,7 +977,7 @@ static int sprd_spi_probe(struct platform_device *pdev)
|
||||
goto err_rpm_put;
|
||||
}
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, sctlr);
|
||||
ret = spi_register_controller(sctlr);
|
||||
if (ret)
|
||||
goto err_rpm_put;
|
||||
|
||||
@@ -1008,7 +1008,9 @@ static void sprd_spi_remove(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
dev_err(ss->dev, "failed to resume SPI controller\n");
|
||||
|
||||
spi_controller_suspend(sctlr);
|
||||
spi_controller_get(sctlr);
|
||||
|
||||
spi_unregister_controller(sctlr);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (ss->dma.enable)
|
||||
@@ -1017,6 +1019,8 @@ 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)
|
||||
|
||||
@@ -349,7 +349,7 @@ static int spi_st_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, host);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register host\n");
|
||||
goto rpm_disable;
|
||||
@@ -371,10 +371,16 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -469,11 +469,6 @@ static int stm32_ospi_send(struct spi_device *spi, const struct spi_mem_op *op)
|
||||
int timeout, err = 0, err_poll_status = 0;
|
||||
u8 cs = spi->chip_select[ffs(spi->cs_index_mask) - 1];
|
||||
|
||||
dev_dbg(ospi->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
|
||||
op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
|
||||
op->dummy.buswidth, op->data.buswidth,
|
||||
op->addr.val, op->data.nbytes);
|
||||
|
||||
cr = readl_relaxed(ospi->regs_base + OSPI_CR);
|
||||
cr &= ~CR_CSSEL;
|
||||
cr |= FIELD_PREP(CR_CSSEL, cs);
|
||||
|
||||
@@ -1659,7 +1659,7 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
|
||||
ret = stm32_spi_prepare_rx_dma_mdma_chaining(spi, xfer, &rx_dma_conf,
|
||||
&rx_dma_desc, &rx_mdma_desc);
|
||||
if (ret) { /* RX DMA MDMA chaining not possible, fallback to DMA only */
|
||||
rx_dma_conf.peripheral_config = 0;
|
||||
rx_dma_conf.peripheral_config = NULL;
|
||||
rx_dma_desc = NULL;
|
||||
}
|
||||
}
|
||||
@@ -2360,25 +2360,20 @@ static int stm32_spi_probe(struct platform_device *pdev)
|
||||
int ret;
|
||||
|
||||
cfg = of_device_get_match_data(&pdev->dev);
|
||||
if (!cfg) {
|
||||
dev_err(&pdev->dev, "Failed to get match data for platform\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!cfg)
|
||||
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||
"Failed to get match data for platform\n");
|
||||
|
||||
device_mode = of_property_read_bool(np, "spi-slave");
|
||||
if (!cfg->has_device_mode && device_mode) {
|
||||
dev_err(&pdev->dev, "spi-slave not supported\n");
|
||||
return -EPERM;
|
||||
}
|
||||
if (!cfg->has_device_mode && device_mode)
|
||||
return dev_err_probe(&pdev->dev, -EPERM, "spi-slave not supported\n");
|
||||
|
||||
if (device_mode)
|
||||
ctrl = devm_spi_alloc_target(&pdev->dev, sizeof(struct stm32_spi));
|
||||
else
|
||||
ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(struct stm32_spi));
|
||||
if (!ctrl) {
|
||||
dev_err(&pdev->dev, "spi controller allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!ctrl)
|
||||
return dev_err_probe(&pdev->dev, -ENOMEM, "spi controller allocation failed\n");
|
||||
platform_set_drvdata(pdev, ctrl);
|
||||
|
||||
spi = spi_controller_get_devdata(ctrl);
|
||||
@@ -2409,32 +2404,18 @@ static int stm32_spi_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
spi->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(spi->clk)) {
|
||||
ret = PTR_ERR(spi->clk);
|
||||
dev_err(&pdev->dev, "clk get failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
|
||||
if (IS_ERR(spi->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(spi->clk), "clk enabled failed\n");
|
||||
|
||||
ret = clk_prepare_enable(spi->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "clk enable failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
spi->clk_rate = clk_get_rate(spi->clk);
|
||||
if (!spi->clk_rate) {
|
||||
dev_err(&pdev->dev, "clk rate = 0\n");
|
||||
ret = -EINVAL;
|
||||
goto err_clk_disable;
|
||||
}
|
||||
if (!spi->clk_rate)
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "clk rate = 0\n");
|
||||
|
||||
rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
|
||||
if (rst) {
|
||||
if (IS_ERR(rst)) {
|
||||
ret = dev_err_probe(&pdev->dev, PTR_ERR(rst),
|
||||
"failed to get reset\n");
|
||||
goto err_clk_disable;
|
||||
}
|
||||
if (IS_ERR(rst))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(rst), "failed to get reset\n");
|
||||
|
||||
reset_control_assert(rst);
|
||||
udelay(2);
|
||||
@@ -2461,11 +2442,8 @@ static int stm32_spi_probe(struct platform_device *pdev)
|
||||
dev_dbg(spi->dev, "one message max size %d\n", spi->t_size_max);
|
||||
|
||||
ret = spi->cfg->config(spi);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "controller configuration failed: %d\n",
|
||||
ret);
|
||||
goto err_clk_disable;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "controller configuration failed: %d\n", ret);
|
||||
|
||||
ctrl->auto_runtime_pm = true;
|
||||
ctrl->bus_num = pdev->id;
|
||||
@@ -2490,8 +2468,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
|
||||
dev_info(&pdev->dev, "tx dma disabled\n");
|
||||
spi->dma_tx = NULL;
|
||||
} else {
|
||||
dev_err_probe(&pdev->dev, ret, "failed to request tx dma channel\n");
|
||||
goto err_clk_disable;
|
||||
return dev_err_probe(&pdev->dev, ret, "failed to request tx dma channel\n");
|
||||
}
|
||||
} else {
|
||||
ctrl->dma_tx = spi->dma_tx;
|
||||
@@ -2505,7 +2482,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
|
||||
spi->dma_rx = NULL;
|
||||
} else {
|
||||
dev_err_probe(&pdev->dev, ret, "failed to request rx dma channel\n");
|
||||
goto err_dma_release;
|
||||
goto err_dma_tx_release;
|
||||
}
|
||||
} else {
|
||||
ctrl->dma_rx = spi->dma_rx;
|
||||
@@ -2574,13 +2551,11 @@ static int stm32_spi_probe(struct platform_device *pdev)
|
||||
if (spi->sram_pool)
|
||||
gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf,
|
||||
spi->sram_rx_buf_size);
|
||||
err_dma_release:
|
||||
if (spi->dma_tx)
|
||||
dma_release_channel(spi->dma_tx);
|
||||
if (spi->dma_rx)
|
||||
dma_release_channel(spi->dma_rx);
|
||||
err_clk_disable:
|
||||
clk_disable_unprepare(spi->clk);
|
||||
err_dma_tx_release:
|
||||
if (spi->dma_tx)
|
||||
dma_release_channel(spi->dma_tx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2610,9 +2585,6 @@ static void stm32_spi_remove(struct platform_device *pdev)
|
||||
gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf,
|
||||
spi->sram_rx_buf_size);
|
||||
|
||||
clk_disable_unprepare(spi->clk);
|
||||
|
||||
|
||||
pinctrl_pm_select_sleep_state(&pdev->dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot register SPI host\n");
|
||||
goto err_pm_disable;
|
||||
@@ -522,7 +522,15 @@ static int sun4i_spi_probe(struct platform_device *pdev)
|
||||
|
||||
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[] = {
|
||||
|
||||
@@ -742,7 +742,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot register SPI host\n");
|
||||
goto err_pm_disable;
|
||||
@@ -768,12 +768,18 @@ 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);
|
||||
|
||||
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 sun6i_spi_cfg sun6i_a31_spi_cfg = {
|
||||
|
||||
@@ -389,11 +389,6 @@ static int sp7021_spi_target_transfer_one(struct spi_controller *ctlr, struct sp
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sp7021_spi_disable_unprepare(void *data)
|
||||
{
|
||||
clk_disable_unprepare(data);
|
||||
}
|
||||
|
||||
static void sp7021_spi_reset_control_assert(void *data)
|
||||
{
|
||||
reset_control_assert(data);
|
||||
@@ -460,7 +455,7 @@ static int sp7021_spi_controller_probe(struct platform_device *pdev)
|
||||
if (pspim->s_irq < 0)
|
||||
return pspim->s_irq;
|
||||
|
||||
pspim->spi_clk = devm_clk_get(dev, NULL);
|
||||
pspim->spi_clk = devm_clk_get_enabled(dev, NULL);
|
||||
if (IS_ERR(pspim->spi_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(pspim->spi_clk), "clk get fail\n");
|
||||
|
||||
@@ -468,14 +463,6 @@ static int sp7021_spi_controller_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(pspim->rstc))
|
||||
return dev_err_probe(dev, PTR_ERR(pspim->rstc), "rst get fail\n");
|
||||
|
||||
ret = clk_prepare_enable(pspim->spi_clk);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to enable clk\n");
|
||||
|
||||
ret = devm_add_action_or_reset(dev, sp7021_spi_disable_unprepare, pspim->spi_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(pspim->rstc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to deassert reset\n");
|
||||
|
||||
@@ -716,7 +716,7 @@ static int synquacer_spi_probe(struct platform_device *pdev)
|
||||
pm_runtime_set_active(sspi->dev);
|
||||
pm_runtime_enable(sspi->dev);
|
||||
|
||||
ret = devm_spi_register_controller(sspi->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto disable_pm;
|
||||
|
||||
@@ -737,9 +737,15 @@ 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)
|
||||
|
||||
@@ -1415,7 +1415,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
|
||||
goto exit_pm_disable;
|
||||
}
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "can not register to host err %d\n", ret);
|
||||
goto exit_free_irq;
|
||||
@@ -1441,6 +1441,10 @@ 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);
|
||||
|
||||
if (tspi->tx_dma_chan)
|
||||
@@ -1452,6 +1456,8 @@ 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
|
||||
|
||||
@@ -505,7 +505,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
|
||||
tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "can not register to host err %d\n", ret);
|
||||
goto exit_pm_disable;
|
||||
@@ -528,11 +528,17 @@ 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);
|
||||
|
||||
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
|
||||
|
||||
@@ -1007,7 +1007,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
|
||||
|
||||
cdata = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
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;
|
||||
@@ -1034,37 +1034,34 @@ static int tegra_slink_probe(struct platform_device *pdev)
|
||||
host->max_speed_hz = 25000000; /* 25MHz */
|
||||
|
||||
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;
|
||||
|
||||
/* disabled clock may cause interrupt storm upon request */
|
||||
tspi->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(tspi->clk)) {
|
||||
ret = PTR_ERR(tspi->clk);
|
||||
dev_err(&pdev->dev, "Can not get clock %d\n", ret);
|
||||
goto exit_free_host;
|
||||
return dev_err_probe(&pdev->dev, ret, "Can not get clock\n");
|
||||
}
|
||||
|
||||
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 dev_err_probe(&pdev->dev, ret, "can not get reset\n");
|
||||
}
|
||||
|
||||
ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
|
||||
if (ret)
|
||||
goto exit_free_host;
|
||||
return ret;
|
||||
|
||||
tspi->max_buf_size = SLINK_FIFO_DEPTH << 2;
|
||||
tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
|
||||
|
||||
ret = tegra_slink_init_dma_param(tspi, true);
|
||||
if (ret < 0)
|
||||
goto exit_free_host;
|
||||
return ret;
|
||||
ret = tegra_slink_init_dma_param(tspi, false);
|
||||
if (ret < 0)
|
||||
goto exit_rx_dma_free;
|
||||
@@ -1125,14 +1122,13 @@ static int tegra_slink_probe(struct platform_device *pdev)
|
||||
tegra_slink_deinit_dma_param(tspi, false);
|
||||
exit_rx_dma_free:
|
||||
tegra_slink_deinit_dma_param(tspi, true);
|
||||
exit_free_host:
|
||||
spi_controller_put(host);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tegra_slink_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *host = spi_controller_get(platform_get_drvdata(pdev));
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct tegra_slink_data *tspi = spi_controller_get_devdata(host);
|
||||
|
||||
spi_unregister_controller(host);
|
||||
@@ -1146,8 +1142,6 @@ static void tegra_slink_remove(struct platform_device *pdev)
|
||||
|
||||
if (tspi->rx_dma_chan)
|
||||
tegra_slink_deinit_dma_param(tspi, true);
|
||||
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -1000,7 +1000,7 @@ static int tegra_qspi_setup(struct spi_device *spi)
|
||||
|
||||
spin_unlock_irqrestore(&tqspi->lock, flags);
|
||||
|
||||
pm_runtime_put(tqspi->dev);
|
||||
pm_runtime_put_autosuspend(tqspi->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1223,7 +1223,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
|
||||
(&tqspi->xfer_completion,
|
||||
QSPI_DMA_TIMEOUT);
|
||||
|
||||
if (WARN_ON_ONCE(ret == 0)) {
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Check if hardware completed the transfer
|
||||
* even though interrupt was lost or delayed.
|
||||
@@ -1232,6 +1232,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
|
||||
ret = tegra_qspi_handle_timeout(tqspi);
|
||||
if (ret < 0) {
|
||||
/* Real timeout - clean up and fail */
|
||||
WARN_ON_ONCE(1);
|
||||
dev_err(tqspi->dev, "transfer timeout\n");
|
||||
|
||||
/* Abort transfer by resetting pio/dma bit */
|
||||
@@ -1340,7 +1341,7 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
|
||||
|
||||
ret = wait_for_completion_timeout(&tqspi->xfer_completion,
|
||||
QSPI_DMA_TIMEOUT);
|
||||
if (WARN_ON(ret == 0)) {
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Check if hardware completed the transfer even though
|
||||
* interrupt was lost or delayed. If so, process the
|
||||
@@ -1349,6 +1350,7 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
|
||||
ret = tegra_qspi_handle_timeout(tqspi);
|
||||
if (ret < 0) {
|
||||
/* Real timeout - clean up and fail */
|
||||
WARN_ON(1);
|
||||
dev_err(tqspi->dev, "transfer timeout\n");
|
||||
|
||||
if (tqspi->is_curr_dma_xfer)
|
||||
@@ -1765,6 +1767,14 @@ static int tegra_qspi_probe(struct platform_device *pdev)
|
||||
init_completion(&tqspi->rx_dma_complete);
|
||||
init_completion(&tqspi->xfer_completion);
|
||||
|
||||
/*
|
||||
* Set autosuspend delay to 500ms. Testing shows this value eliminates
|
||||
* suspend/resume overhead during burst operations while allowing quick
|
||||
* suspension during idle. For longer operations, the overhead is negligible.
|
||||
*/
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||
if (ret < 0) {
|
||||
@@ -1781,7 +1791,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
|
||||
tqspi->spi_cs_timing2 = tegra_qspi_readl(tqspi, QSPI_CS_TIMING2);
|
||||
tqspi->def_command2_reg = tegra_qspi_readl(tqspi, QSPI_COMMAND2);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
ret = request_threaded_irq(tqspi->irq, NULL,
|
||||
tegra_qspi_isr_thread, IRQF_ONESHOT,
|
||||
@@ -1802,6 +1812,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
|
||||
exit_free_irq:
|
||||
free_irq(qspi_irq, tqspi);
|
||||
exit_pm_disable:
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_force_suspend(&pdev->dev);
|
||||
tegra_qspi_deinit_dma(tqspi);
|
||||
return ret;
|
||||
@@ -1814,6 +1825,7 @@ static void tegra_qspi_remove(struct platform_device *pdev)
|
||||
|
||||
spi_unregister_controller(host);
|
||||
free_irq(tqspi->irq, tqspi);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_force_suspend(&pdev->dev);
|
||||
tegra_qspi_deinit_dma(tqspi);
|
||||
}
|
||||
@@ -1839,7 +1851,7 @@ static int __maybe_unused tegra_qspi_resume(struct device *dev)
|
||||
|
||||
tegra_qspi_writel(tqspi, tqspi->command1_reg, QSPI_COMMAND1);
|
||||
tegra_qspi_writel(tqspi, tqspi->def_command2_reg, QSPI_COMMAND2);
|
||||
pm_runtime_put(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return spi_controller_resume(host);
|
||||
}
|
||||
|
||||
@@ -888,7 +888,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
|
||||
qspi->mmap_enabled = false;
|
||||
qspi->current_cs = -1;
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
@@ -903,19 +903,17 @@ static int ti_qspi_probe(struct platform_device *pdev)
|
||||
static void ti_qspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ti_qspi *qspi = platform_get_drvdata(pdev);
|
||||
int rc;
|
||||
|
||||
rc = spi_controller_suspend(qspi->host);
|
||||
if (rc) {
|
||||
dev_alert(&pdev->dev, "spi_controller_suspend() failed (%pe)\n",
|
||||
ERR_PTR(rc));
|
||||
return;
|
||||
}
|
||||
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 = {
|
||||
|
||||
@@ -666,28 +666,24 @@ static int uniphier_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
priv->base_dma_addr = res->start;
|
||||
|
||||
priv->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
goto out_host_put;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
goto out_disable_clk;
|
||||
goto out_host_put;
|
||||
}
|
||||
|
||||
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_disable_clk;
|
||||
goto out_host_put;
|
||||
}
|
||||
|
||||
init_completion(&priv->xfer_done);
|
||||
@@ -716,7 +712,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
|
||||
if (IS_ERR_OR_NULL(host->dma_tx)) {
|
||||
if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto out_disable_clk;
|
||||
goto out_host_put;
|
||||
}
|
||||
host->dma_tx = NULL;
|
||||
dma_tx_burst = INT_MAX;
|
||||
@@ -750,7 +746,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
|
||||
|
||||
host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, host);
|
||||
ret = spi_register_controller(host);
|
||||
if (ret)
|
||||
goto out_release_dma;
|
||||
|
||||
@@ -766,9 +762,6 @@ static int uniphier_spi_probe(struct platform_device *pdev)
|
||||
host->dma_tx = NULL;
|
||||
}
|
||||
|
||||
out_disable_clk:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
out_host_put:
|
||||
spi_controller_put(host);
|
||||
return ret;
|
||||
@@ -777,14 +770,17 @@ static int uniphier_spi_probe(struct platform_device *pdev)
|
||||
static void uniphier_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
|
||||
|
||||
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);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
spi_controller_put(host);
|
||||
}
|
||||
|
||||
static const struct of_device_id uniphier_spi_match[] = {
|
||||
|
||||
@@ -643,7 +643,7 @@ static int zynq_qspi_probe(struct platform_device *pdev)
|
||||
|
||||
xqspi = spi_controller_get_devdata(ctlr);
|
||||
xqspi->dev = dev;
|
||||
platform_set_drvdata(pdev, xqspi);
|
||||
platform_set_drvdata(pdev, ctlr);
|
||||
xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(xqspi->regs)) {
|
||||
ret = PTR_ERR(xqspi->regs);
|
||||
@@ -702,9 +702,9 @@ static int zynq_qspi_probe(struct platform_device *pdev)
|
||||
/* QSPI controller initializations */
|
||||
zynq_qspi_init_hw(xqspi, ctlr->num_chipselect);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
|
||||
dev_err(&pdev->dev, "failed to register controller\n");
|
||||
goto remove_ctlr;
|
||||
}
|
||||
|
||||
@@ -728,9 +728,16 @@ static int zynq_qspi_probe(struct platform_device *pdev)
|
||||
*/
|
||||
static void zynq_qspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct zynq_qspi *xqspi = platform_get_drvdata(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[] = {
|
||||
|
||||
@@ -1324,7 +1324,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
|
||||
ctlr->dev.of_node = np;
|
||||
ctlr->auto_runtime_pm = true;
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "spi_register_controller failed\n");
|
||||
goto clk_dis_all;
|
||||
@@ -1362,6 +1362,8 @@ static void zynqmp_qspi_remove(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
spi_unregister_controller(xqspi->ctlr);
|
||||
|
||||
zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
@@ -89,25 +89,22 @@ static ssize_t driver_override_show(struct device *dev,
|
||||
}
|
||||
static DEVICE_ATTR_RW(driver_override);
|
||||
|
||||
static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev)
|
||||
static struct spi_statistics __percpu *spi_alloc_pcpu_stats(void)
|
||||
{
|
||||
struct spi_statistics __percpu *pcpu_stats;
|
||||
int cpu;
|
||||
|
||||
if (dev)
|
||||
pcpu_stats = devm_alloc_percpu(dev, struct spi_statistics);
|
||||
else
|
||||
pcpu_stats = alloc_percpu_gfp(struct spi_statistics, GFP_KERNEL);
|
||||
pcpu_stats = alloc_percpu_gfp(struct spi_statistics, GFP_KERNEL);
|
||||
if (!pcpu_stats)
|
||||
return NULL;
|
||||
|
||||
if (pcpu_stats) {
|
||||
int cpu;
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct spi_statistics *stat;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct spi_statistics *stat;
|
||||
|
||||
stat = per_cpu_ptr(pcpu_stats, cpu);
|
||||
u64_stats_init(&stat->syncp);
|
||||
}
|
||||
stat = per_cpu_ptr(pcpu_stats, cpu);
|
||||
u64_stats_init(&stat->syncp);
|
||||
}
|
||||
|
||||
return pcpu_stats;
|
||||
}
|
||||
|
||||
@@ -569,7 +566,7 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spi->pcpu_statistics = spi_alloc_pcpu_stats(NULL);
|
||||
spi->pcpu_statistics = spi_alloc_pcpu_stats();
|
||||
if (!spi->pcpu_statistics) {
|
||||
kfree(spi);
|
||||
spi_controller_put(ctlr);
|
||||
@@ -636,12 +633,26 @@ static inline int spi_dev_check_cs(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct spi_dev_check_info {
|
||||
struct spi_device *new_spi;
|
||||
struct spi_device *parent; /* set for ancillary devices */
|
||||
};
|
||||
|
||||
static int spi_dev_check(struct device *dev, void *data)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
struct spi_device *new_spi = data;
|
||||
struct spi_dev_check_info *info = data;
|
||||
struct spi_device *new_spi = info->new_spi;
|
||||
int status, idx;
|
||||
|
||||
/*
|
||||
* When registering an ancillary device, skip checking against the
|
||||
* parent device since the ancillary is intentionally using one of
|
||||
* the parent's chip selects.
|
||||
*/
|
||||
if (info->parent && spi == info->parent)
|
||||
return 0;
|
||||
|
||||
if (spi->controller == new_spi->controller) {
|
||||
for (idx = 0; idx < spi->num_chipselect; idx++) {
|
||||
status = spi_dev_check_cs(dev, spi, idx, new_spi, 0);
|
||||
@@ -658,10 +669,11 @@ static void spi_cleanup(struct spi_device *spi)
|
||||
spi->controller->cleanup(spi);
|
||||
}
|
||||
|
||||
static int __spi_add_device(struct spi_device *spi)
|
||||
static int __spi_add_device(struct spi_device *spi, struct spi_device *parent)
|
||||
{
|
||||
struct spi_controller *ctlr = spi->controller;
|
||||
struct device *dev = ctlr->dev.parent;
|
||||
struct spi_dev_check_info check_info;
|
||||
int status, idx;
|
||||
u8 cs;
|
||||
|
||||
@@ -705,7 +717,9 @@ static int __spi_add_device(struct spi_device *spi)
|
||||
* chipselect **BEFORE** we call setup(), else we'll trash
|
||||
* its configuration.
|
||||
*/
|
||||
status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
|
||||
check_info.new_spi = spi;
|
||||
check_info.parent = parent;
|
||||
status = bus_for_each_dev(&spi_bus_type, NULL, &check_info, spi_dev_check);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
@@ -767,7 +781,7 @@ int spi_add_device(struct spi_device *spi)
|
||||
spi_dev_set_name(spi);
|
||||
|
||||
mutex_lock(&ctlr->add_lock);
|
||||
status = __spi_add_device(spi);
|
||||
status = __spi_add_device(spi, NULL);
|
||||
mutex_unlock(&ctlr->add_lock);
|
||||
return status;
|
||||
}
|
||||
@@ -2710,8 +2724,8 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi,
|
||||
|
||||
WARN_ON(!mutex_is_locked(&ctlr->add_lock));
|
||||
|
||||
/* Register the new device */
|
||||
rc = __spi_add_device(ancillary);
|
||||
/* Register the new device, passing the parent to skip CS conflict check */
|
||||
rc = __spi_add_device(ancillary, spi);
|
||||
if (rc) {
|
||||
dev_err(&spi->dev, "failed to register ancillary device\n");
|
||||
goto err_out;
|
||||
@@ -2725,6 +2739,46 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_new_ancillary_device);
|
||||
|
||||
static void devm_spi_unregister_device(void *spi)
|
||||
{
|
||||
spi_unregister_device(spi);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_spi_new_ancillary_device() - Register managed ancillary SPI device
|
||||
* @spi: Pointer to the main SPI device registering the ancillary device
|
||||
* @chip_select: Chip Select of the ancillary device
|
||||
*
|
||||
* Register an ancillary SPI device; for example some chips have a chip-select
|
||||
* for normal device usage and another one for setup/firmware upload.
|
||||
*
|
||||
* This is the managed version of spi_new_ancillary_device(). The ancillary
|
||||
* device will be unregistered automatically when the parent SPI device is
|
||||
* unregistered.
|
||||
*
|
||||
* This may only be called from main SPI device's probe routine.
|
||||
*
|
||||
* Return: Pointer to new ancillary device on success; ERR_PTR on failure
|
||||
*/
|
||||
struct spi_device *devm_spi_new_ancillary_device(struct spi_device *spi,
|
||||
u8 chip_select)
|
||||
{
|
||||
struct spi_device *ancillary;
|
||||
int ret;
|
||||
|
||||
ancillary = spi_new_ancillary_device(spi, chip_select);
|
||||
if (IS_ERR(ancillary))
|
||||
return ancillary;
|
||||
|
||||
ret = devm_add_action_or_reset(&spi->dev, devm_spi_unregister_device,
|
||||
ancillary);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return ancillary;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_spi_new_ancillary_device);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
struct acpi_spi_lookup {
|
||||
struct spi_controller *ctlr;
|
||||
@@ -3189,7 +3243,7 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
|
||||
if (!ctlr)
|
||||
return NULL;
|
||||
|
||||
ctlr->pcpu_statistics = spi_alloc_pcpu_stats(NULL);
|
||||
ctlr->pcpu_statistics = spi_alloc_pcpu_stats();
|
||||
if (!ctlr->pcpu_statistics) {
|
||||
kfree(ctlr);
|
||||
return NULL;
|
||||
@@ -3386,8 +3440,8 @@ static int spi_controller_id_alloc(struct spi_controller *ctlr, int start, int e
|
||||
* device identification, boards need configuration tables telling which
|
||||
* chip is at which address.
|
||||
*
|
||||
* This must be called from context that can sleep. It returns zero on
|
||||
* success, else a negative error code (dropping the controller's refcount).
|
||||
* This must be called from context that can sleep.
|
||||
*
|
||||
* After a successful return, the caller is responsible for calling
|
||||
* spi_unregister_controller().
|
||||
*
|
||||
@@ -3521,7 +3575,8 @@ 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.
|
||||
* automatically be unregistered (and freed unless it has been allocated using
|
||||
* devm_spi_alloc_host/target()).
|
||||
*
|
||||
* Return: zero on success, else a negative error code.
|
||||
*/
|
||||
@@ -3566,7 +3621,8 @@ static int __unregister(struct device *dev, void *null)
|
||||
*
|
||||
* This must be called from context that can sleep.
|
||||
*
|
||||
* Note that this function also drops a reference to the controller.
|
||||
* 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)
|
||||
{
|
||||
@@ -4232,12 +4288,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
|
||||
* SPI transfer length should be multiple of SPI word size
|
||||
* where SPI word size should be power-of-two multiple.
|
||||
*/
|
||||
if (xfer->bits_per_word <= 8)
|
||||
w_size = 1;
|
||||
else if (xfer->bits_per_word <= 16)
|
||||
w_size = 2;
|
||||
else
|
||||
w_size = 4;
|
||||
w_size = spi_bpw_to_bytes(xfer->bits_per_word);
|
||||
|
||||
/* No partial transfers accepted */
|
||||
if (xfer->len % w_size)
|
||||
|
||||
@@ -28,6 +28,14 @@
|
||||
.dtr = true, \
|
||||
}
|
||||
|
||||
#define SPI_MEM_DTR_OP_PACKED_CMD(__opcode, __addr, __buswidth) \
|
||||
{ \
|
||||
.nbytes = 2, \
|
||||
.opcode = __opcode << 8 | __addr, \
|
||||
.buswidth = __buswidth, \
|
||||
.dtr = true, \
|
||||
}
|
||||
|
||||
#define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth) \
|
||||
{ \
|
||||
.nbytes = __nbytes, \
|
||||
@@ -130,11 +138,13 @@ enum spi_mem_data_dir {
|
||||
|
||||
/**
|
||||
* struct spi_mem_op - describes a SPI memory operation
|
||||
* @cmd: the complete command
|
||||
* @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is
|
||||
* sent MSB-first.
|
||||
* @cmd.buswidth: number of IO lines used to transmit the command
|
||||
* @cmd.opcode: operation opcode
|
||||
* @cmd.dtr: whether the command opcode should be sent in DTR mode or not
|
||||
* @addr: the address attributes
|
||||
* @addr.nbytes: number of address bytes to send. Can be zero if the operation
|
||||
* does not need to send an address
|
||||
* @addr.buswidth: number of IO lines used to transmit the address cycles
|
||||
@@ -143,10 +153,12 @@ enum spi_mem_data_dir {
|
||||
* Note that only @addr.nbytes are taken into account in this
|
||||
* address value, so users should make sure the value fits in the
|
||||
* assigned number of bytes.
|
||||
* @dummy: data for dummy operation
|
||||
* @dummy.nbytes: number of dummy bytes to send after an opcode or address. Can
|
||||
* be zero if the operation does not require dummy bytes
|
||||
* @dummy.buswidth: number of IO lanes used to transmit the dummy bytes
|
||||
* @dummy.dtr: whether the dummy bytes should be sent in DTR mode or not
|
||||
* @data: the data attributes
|
||||
* @data.buswidth: number of IO lanes used to send/receive the data
|
||||
* @data.dtr: whether the data should be sent in DTR mode or not
|
||||
* @data.ecc: whether error correction is required or not
|
||||
@@ -273,7 +285,7 @@ struct spi_mem {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct spi_mem_set_drvdata() - attach driver private data to a SPI mem
|
||||
* spi_mem_set_drvdata() - attach driver private data to a SPI mem
|
||||
* device
|
||||
* @mem: memory device
|
||||
* @data: data to attach to the memory device
|
||||
@@ -284,7 +296,7 @@ static inline void spi_mem_set_drvdata(struct spi_mem *mem, void *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* struct spi_mem_get_drvdata() - get driver private data attached to a SPI mem
|
||||
* spi_mem_get_drvdata() - get driver private data attached to a SPI mem
|
||||
* device
|
||||
* @mem: memory device
|
||||
*
|
||||
|
||||
@@ -382,6 +382,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
|
||||
}
|
||||
|
||||
extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select);
|
||||
extern struct spi_device *devm_spi_new_ancillary_device(struct spi_device *spi, u8 chip_select);
|
||||
|
||||
/* Use a define to avoid include chaining to get THIS_MODULE */
|
||||
#define spi_register_driver(driver) \
|
||||
|
||||
Reference in New Issue
Block a user