From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/spi/spi-rockchip.c | 141 ++++++++++++++++++++++++-----------------------
1 files changed, 72 insertions(+), 69 deletions(-)
diff --git a/kernel/drivers/spi/spi-rockchip.c b/kernel/drivers/spi/spi-rockchip.c
index e55c5c6..d6cc6de 100644
--- a/kernel/drivers/spi/spi-rockchip.c
+++ b/kernel/drivers/spi/spi-rockchip.c
@@ -1,22 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
* Author: Addy Ke <addy.ke@rock-chips.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
*/
+#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
-#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
@@ -197,6 +188,7 @@
struct clk *spiclk;
struct clk *apb_pclk;
+ struct clk *sclk_in;
void __iomem *regs;
dma_addr_t dma_addr_rx;
@@ -227,8 +219,9 @@
struct pinctrl_state *high_speed_state;
bool slave_aborted;
- bool gpio_requested;
bool cs_inactive; /* spi slave tansmition stop when cs inactive */
+ bool cs_high_supported; /* native CS supports active-high polarity */
+
struct spi_transfer *xfer; /* Store xfer temporarily */
phys_addr_t base_addr_phy;
struct miscdevice miscdev;
@@ -296,12 +289,12 @@
/* Keep things powered as long as CS is asserted */
pm_runtime_get_sync(rs->dev);
- if (gpio_is_valid(spi->cs_gpio))
+ if (spi->cs_gpiod)
ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
else
ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
} else {
- if (gpio_is_valid(spi->cs_gpio))
+ if (spi->cs_gpiod)
ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
else
ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
@@ -362,7 +355,7 @@
static void rockchip_spi_pio_reader(struct rockchip_spi *rs)
{
u32 words = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
- u32 rx_left = rs->rx_left > words ? rs->rx_left - words : 0;
+ u32 rx_left = (rs->rx_left > words) ? rs->rx_left - words : 0;
/* the hardware doesn't allow us to change fifo threshold
* level while spi is enabled, so instead make sure to leave
@@ -528,7 +521,7 @@
.direction = DMA_MEM_TO_DEV,
.dst_addr = rs->dma_addr_tx,
.dst_addr_width = rs->n_bytes,
- .dst_maxburst = 8,
+ .dst_maxburst = rs->fifo_len / 4,
};
dmaengine_slave_config(ctlr->dma_tx, &txconf);
@@ -678,7 +671,9 @@
* ctlr->bits_per_word_mask, so this shouldn't
* happen
*/
- unreachable();
+ dev_err(rs->dev, "unknown bits per word: %d\n",
+ xfer->bits_per_word);
+ return -EINVAL;
}
if (xfer_mode == ROCKCHIP_SPI_DMA) {
@@ -886,10 +881,13 @@
static int rockchip_spi_setup(struct spi_device *spi)
{
-
- int ret = -EINVAL;
struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller);
u32 cr0;
+
+ if (!spi->cs_gpiod && (spi->mode & SPI_CS_HIGH) && !rs->cs_high_supported) {
+ dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n");
+ return -EINVAL;
+ }
pm_runtime_get_sync(rs->dev);
@@ -903,39 +901,7 @@
pm_runtime_put(rs->dev);
- if (spi->cs_gpio == -ENOENT)
- return 0;
-
- if (!rs->gpio_requested && gpio_is_valid(spi->cs_gpio)) {
- ret = gpio_request_one(spi->cs_gpio,
- (spi->mode & SPI_CS_HIGH) ?
- GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
- dev_name(&spi->dev));
- if (ret)
- dev_err(&spi->dev, "can't request chipselect gpio %d\n",
- spi->cs_gpio);
- else
- rs->gpio_requested = true;
- } else {
- if (gpio_is_valid(spi->cs_gpio)) {
- int mode = ((spi->mode & SPI_CS_HIGH) ? 0 : 1);
-
- ret = gpio_direction_output(spi->cs_gpio, mode);
- if (ret)
- dev_err(&spi->dev, "chipselect gpio %d setup failed (%d)\n",
- spi->cs_gpio, ret);
- }
- }
-
- return ret;
-}
-
-static void rockchip_spi_cleanup(struct spi_device *spi)
-{
- struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller);
-
- if (rs->gpio_requested)
- gpio_free(spi->cs_gpio);
+ return 0;
}
static int rockchip_spi_misc_open(struct inode *inode, struct file *filp)
@@ -999,7 +965,7 @@
struct spi_controller *ctlr;
struct resource *mem;
struct device_node *np = pdev->dev.of_node;
- u32 rsd_nsecs, csm;
+ u32 rsd_nsecs, num_cs, csm;
bool slave_mode;
struct pinctrl *pinctrl = NULL;
const struct rockchip_spi_quirks *quirks_cfg;
@@ -1030,17 +996,26 @@
}
rs->base_addr_phy = mem->start;
- rs->apb_pclk = devm_clk_get(&pdev->dev, "apb_pclk");
+ if (!has_acpi_companion(&pdev->dev))
+ rs->apb_pclk = devm_clk_get(&pdev->dev, "apb_pclk");
if (IS_ERR(rs->apb_pclk)) {
dev_err(&pdev->dev, "Failed to get apb_pclk\n");
ret = PTR_ERR(rs->apb_pclk);
goto err_put_ctlr;
}
- rs->spiclk = devm_clk_get(&pdev->dev, "spiclk");
+ if (!has_acpi_companion(&pdev->dev))
+ rs->spiclk = devm_clk_get(&pdev->dev, "spiclk");
if (IS_ERR(rs->spiclk)) {
dev_err(&pdev->dev, "Failed to get spi_pclk\n");
ret = PTR_ERR(rs->spiclk);
+ goto err_put_ctlr;
+ }
+
+ rs->sclk_in = devm_clk_get_optional(&pdev->dev, "sclk_in");
+ if (IS_ERR(rs->sclk_in)) {
+ dev_err(&pdev->dev, "Failed to get sclk_in\n");
+ ret = PTR_ERR(rs->sclk_in);
goto err_put_ctlr;
}
@@ -1056,23 +1031,35 @@
goto err_disable_apbclk;
}
+ ret = clk_prepare_enable(rs->sclk_in);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to enable sclk_in\n");
+ goto err_disable_spiclk;
+ }
+
spi_enable_chip(rs, false);
ret = platform_get_irq(pdev, 0);
if (ret < 0)
- goto err_disable_spiclk;
+ goto err_disable_sclk_in;
ret = devm_request_threaded_irq(&pdev->dev, ret, rockchip_spi_isr, NULL,
IRQF_ONESHOT, dev_name(&pdev->dev), ctlr);
if (ret)
- goto err_disable_spiclk;
+ goto err_disable_sclk_in;
rs->dev = &pdev->dev;
- rs->freq = clk_get_rate(rs->spiclk);
- rs->gpio_requested = false;
- if (!of_property_read_u32(pdev->dev.of_node, "rx-sample-delay-ns",
- &rsd_nsecs)) {
+ rs->freq = clk_get_rate(rs->spiclk);
+ if (!rs->freq) {
+ ret = device_property_read_u32(&pdev->dev, "clock-frequency", &rs->freq);
+ if (ret) {
+ dev_warn(rs->dev, "Failed to get clock or clock-frequency property\n");
+ goto err_disable_sclk_in;
+ }
+ }
+
+ if (!device_property_read_u32(&pdev->dev, "rx-sample-delay-ns", &rsd_nsecs)) {
/* rx sample delay is expressed in parent clock cycles (max 3) */
u32 rsd = DIV_ROUND_CLOSEST(rsd_nsecs * (rs->freq >> 8),
1000000000 >> 8);
@@ -1102,7 +1089,7 @@
if (!rs->fifo_len) {
dev_err(&pdev->dev, "Failed to get fifo length\n");
ret = -EINVAL;
- goto err_disable_spiclk;
+ goto err_disable_sclk_in;
}
quirks_cfg = device_get_match_data(&pdev->dev);
if (quirks_cfg)
@@ -1113,22 +1100,29 @@
ctlr->auto_runtime_pm = true;
ctlr->bus_num = pdev->id;
- ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_LSB_FIRST | SPI_CS_HIGH;
+ ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_LSB_FIRST;
if (slave_mode) {
ctlr->mode_bits |= SPI_NO_CS;
ctlr->slave_abort = rockchip_spi_slave_abort;
} else {
ctlr->flags = SPI_MASTER_GPIO_SS;
+ ctlr->max_native_cs = ROCKCHIP_SPI_MAX_CS_NUM;
+ /*
+ * rk spi0 has two native cs, spi1..5 one cs only
+ * if num-cs is missing in the dts, default to 1
+ */
+ if (device_property_read_u32(&pdev->dev, "num-cs", &num_cs))
+ num_cs = 1;
+ ctlr->num_chipselect = num_cs;
+ ctlr->use_gpio_descriptors = true;
}
- ctlr->num_chipselect = ROCKCHIP_SPI_MAX_CS_NUM;
ctlr->dev.of_node = pdev->dev.of_node;
ctlr->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8) | SPI_BPW_MASK(4);
ctlr->min_speed_hz = rs->freq / BAUDR_SCKDV_MAX;
ctlr->max_speed_hz = min(rs->freq / BAUDR_SCKDV_MIN, MAX_SCLK_OUT);
- ctlr->set_cs = rockchip_spi_set_cs;
ctlr->setup = rockchip_spi_setup;
- ctlr->cleanup = rockchip_spi_cleanup;
+ ctlr->set_cs = rockchip_spi_set_cs;
ctlr->transfer_one = rockchip_spi_transfer_one;
ctlr->max_transfer_size = rockchip_spi_max_transfer_size;
ctlr->handle_err = rockchip_spi_handle_err;
@@ -1169,8 +1163,9 @@
}
switch (rs->version) {
- case ROCKCHIP_SPI_VER2_TYPE1:
case ROCKCHIP_SPI_VER2_TYPE2:
+ rs->cs_high_supported = true;
+ ctlr->mode_bits |= SPI_CS_HIGH;
if (slave_mode)
rs->cs_inactive = true;
else
@@ -1178,7 +1173,9 @@
break;
default:
rs->cs_inactive = false;
+ break;
}
+
pinctrl = devm_pinctrl_get(&pdev->dev);
if (!IS_ERR(pinctrl)) {
rs->high_speed_state = pinctrl_lookup_state(pinctrl, "high_speed");
@@ -1222,6 +1219,8 @@
dma_release_channel(ctlr->dma_tx);
err_disable_pm_runtime:
pm_runtime_disable(&pdev->dev);
+err_disable_sclk_in:
+ clk_disable_unprepare(rs->sclk_in);
err_disable_spiclk:
clk_disable_unprepare(rs->spiclk);
err_disable_apbclk:
@@ -1242,6 +1241,7 @@
pm_runtime_get_sync(&pdev->dev);
+ clk_disable_unprepare(rs->sclk_in);
clk_disable_unprepare(rs->spiclk);
clk_disable_unprepare(rs->apb_pclk);
@@ -1344,15 +1344,18 @@
.compatible = "rockchip,px30-spi",
.data = &rockchip_spi_quirks_cfg,
},
- { .compatible = "rockchip,rv1108-spi", },
- { .compatible = "rockchip,rv1126-spi", },
{ .compatible = "rockchip,rk3036-spi", },
{ .compatible = "rockchip,rk3066-spi", },
{ .compatible = "rockchip,rk3188-spi", },
{ .compatible = "rockchip,rk3228-spi", },
{ .compatible = "rockchip,rk3288-spi", },
+ { .compatible = "rockchip,rk3308-spi", },
+ { .compatible = "rockchip,rk3328-spi", },
{ .compatible = "rockchip,rk3368-spi", },
{ .compatible = "rockchip,rk3399-spi", },
+ { .compatible = "rockchip,rv1106-spi", },
+ { .compatible = "rockchip,rv1108-spi", },
+ { .compatible = "rockchip,rv1126-spi", },
{ },
};
MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
--
Gitblit v1.6.2