Files
openwrt/target/linux/starfive/patches-6.12/0020-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch
T
Shiji Yang 0eaee44870 kernel: bump 6.12 to 6.12.90
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.90

All patches are automatically refreshed.

Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/23444
(cherry picked from commit 979bad2629)
Link: https://github.com/openwrt/openwrt/pull/23538
[Updated and added starfive patches for spi-pl022]
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2026-05-27 12:37:48 +02:00

224 lines
6.3 KiB
Diff

From 714c99f993097e5c16822e73ba0a7945b86a20ea Mon Sep 17 00:00:00 2001
From: "xingyu.wu" <xingyu.wu@starfivetech.com>
Date: Tue, 28 Jun 2022 22:48:15 +0800
Subject: [PATCH 20/55] spi-pl022:starfive:Add platform bus register to adapt
overlay
Add platform bus register to adapt dtbo overlay.
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/spi/spi-pl022.c | 143 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 137 insertions(+), 6 deletions(-)
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -34,6 +34,7 @@
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/reset.h>
+#include <linux/platform_device.h>
/*
* This macro is used to define some register default values.
@@ -1841,7 +1842,10 @@ pl022_platform_data_dt_get(struct device
return NULL;
}
- pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ if (strncmp(dev->bus->name, "platform", strlen("platform")))
+ pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ else
+ pd = kzalloc(sizeof(struct pl022_ssp_controller), GFP_KERNEL);
if (!pd)
return NULL;
@@ -1861,6 +1865,14 @@ static int pl022_probe(struct amba_devic
struct spi_controller *host;
struct pl022 *pl022 = NULL; /*Data for this driver */
int status = 0;
+ int platform_flag = 0;
+
+ if (strncmp(dev->bus->name, "platform", strlen("platform")))
+ platform_flag = 0;
+ else
+ platform_flag = 1;
+ dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
+ dev->bus->name, platform_flag);
dev_info(&adev->dev,
"ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
@@ -1916,7 +1928,11 @@ static int pl022_probe(struct amba_devic
goto err_no_ioregion;
pl022->phybase = adev->res.start;
- pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ if (platform_flag)
+ pl022->virtbase = ioremap(adev->res.start,
+ resource_size(&adev->res));
+ else
+ pl022->virtbase = devm_ioremap(dev, adev->res.start,
resource_size(&adev->res));
if (pl022->virtbase == NULL) {
status = -ENOMEM;
@@ -1925,14 +1941,28 @@ static int pl022_probe(struct amba_devic
dev_info(&adev->dev, "mapped registers from %pa to %p\n",
&adev->res.start, pl022->virtbase);
- pl022->clk = devm_clk_get_enabled(&adev->dev, NULL);
+ if (platform_flag)
+ pl022->clk = clk_get(&adev->dev, NULL);
+ else
+ pl022->clk = devm_clk_get_enabled(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
status = PTR_ERR(pl022->clk);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
goto err_no_clk;
}
- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (platform_flag) {
+ status = clk_prepare_enable(pl022->clk);
+ if (status) {
+ dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
+ goto err_no_clk_en;
+ }
+ }
+
+ if (platform_flag)
+ pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
+ else
+ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
if (IS_ERR(pl022->rst)) {
status = PTR_ERR(pl022->rst);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
@@ -1950,7 +1980,11 @@ static int pl022_probe(struct amba_devic
SSP_CR1(pl022->virtbase));
load_ssp_default_config(pl022);
- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ if (platform_flag)
+ status = request_irq(adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ else
+ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
0, "pl022", pl022);
if (status < 0) {
dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
@@ -2000,13 +2034,24 @@ static int pl022_probe(struct amba_devic
if (platform_info->enable_dma)
pl022_dma_remove(pl022);
err_no_irq:
+ if (platform_flag)
+ free_irq(adev->irq[0], pl022);
+ reset_control_assert(pl022->rst);
err_no_rst_de:
+ if (platform_flag)
+ reset_control_put(pl022->rst);
err_no_rst:
+ if (platform_flag)
+ clk_put(pl022->clk);
err_no_clk:
+ if (platform_flag)
+ iounmap(pl022->virtbase);
err_no_ioremap:
amba_release_regions(adev);
err_no_ioregion:
spi_controller_put(host);
+ if (platform_flag)
+ kfree(platform_info);
return status;
}
@@ -2211,6 +2256,89 @@ static void __exit pl022_exit(void)
}
module_exit(pl022_exit);
+/*
+ * Register PL022 in platform bus to accommodate overlay use.
+ * Because overlay only trigger response from the platform bus
+ * not amba bus.
+ */
+static int starfive_of_pl022_probe(struct platform_device *pdev)
+{
+ int ret;
+ const struct amba_id id = {
+ .id = 0x00041022,
+ .mask = 0x000fffff,
+ .data = &vendor_arm
+ };
+ struct amba_device *pcdev;
+ struct device *dev = &pdev->dev;
+
+ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
+ if (!pcdev)
+ return -ENOMEM;
+
+ pcdev->dev = pdev->dev;
+ pcdev->periphid = id.id;
+ pcdev->res = *(pdev->resource);
+
+ pcdev->irq[0] = platform_get_irq(pdev, 0);
+ if (pcdev->irq[0] < 0) {
+ dev_err(dev, "failed to get irq\n");
+ ret = -EINVAL;
+ }
+
+ ret = pl022_probe(pcdev, &id);
+
+ return ret;
+}
+
+static void starfive_of_pl022_remove(struct platform_device *pdev)
+{
+ u32 size;
+ int irq;
+ struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
+
+ if (!pl022)
+ return;
+
+ pm_runtime_get_noresume(&pdev->dev);
+
+ load_ssp_default_config(pl022);
+ if (pl022->host_info->enable_dma)
+ pl022_dma_remove(pl022);
+
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq, pl022);
+ reset_control_assert(pl022->rst);
+ reset_control_put(pl022->rst);
+ clk_disable_unprepare(pl022->clk);
+ clk_put(pl022->clk);
+ iounmap(pl022->virtbase);
+ kfree(pl022->host_info);
+
+ size = resource_size(pdev->resource);
+ release_mem_region(pdev->resource->start, size);
+}
+
+static const struct of_device_id starfive_of_pl022_match[] = {
+ { .compatible = "starfive,jh7110-spi-pl022" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, starfive_of_pl022_match);
+
+static struct platform_driver starfive_of_pl022_driver = {
+ .driver = {
+ .name = "starfive-spi-pl022",
+ .of_match_table = starfive_of_pl022_match,
+ .pm = &pl022_dev_pm_ops,
+ },
+ .probe = starfive_of_pl022_probe,
+ .remove = starfive_of_pl022_remove,
+};
+
+module_platform_driver(starfive_of_pl022_driver);
+/* platform register end */
+
+MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("PL022 SSP Controller Driver");
MODULE_LICENSE("GPL");