Re: [PATCH v6 2/2] spi: loongson: add bus driver for the loongson spi controller

From: zhuyinbo
Date: Mon Apr 03 2023 - 03:45:06 EST




在 2023/4/2 下午7:44, Christophe JAILLET 写道:
Le 01/04/2023 à 11:56, Yinbo Zhu a écrit :
This bus driver supports the Loongson spi hardware controller in the
Loongson platforms and supports to use DTS and PCI framework to
register spi device resources.

Signed-off-by: Yinbo Zhu <zhuyinbo-cXZgJK919ebM1kAEIRd3EQ@xxxxxxxxxxxxxxxx>
---

[...]

+int loongson_spi_init_master(struct device *dev, struct resource *res)
+{
+    struct spi_master *master;
+    struct loongson_spi *spi;
+    struct clk *clk;
+    int ret;
+
+    master = spi_alloc_master(dev, sizeof(struct loongson_spi));

devm_spi_alloc_master()?
(to simplify code and be consistent with devm_ function below)
okay, I got it, I will use it.

+    if (master == NULL) {
+        dev_dbg(dev, "master allocation failed\n");
+        return -ENOMEM;
+    }
+
+    master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+    master->setup = loongson_spi_setup;
+    master->prepare_message = loongson_spi_prepare_message;
+    master->transfer_one = loongson_spi_transfer_one;
+    master->unprepare_message = loongson_spi_unprepare_message;
+    master->set_cs = loongson_spi_set_cs;
+    master->num_chipselect = 4;
+    master->dev.of_node = of_node_get(dev->of_node);
+    dev_set_drvdata(dev, master);
+
+    spi = spi_master_get_devdata(master);
+
+    spi->master = master;
+
+    spi->base = devm_ioremap(dev, res->start, resource_size(res));
+    if (spi->base == NULL) {
+        dev_err(dev, "cannot map io\n");
+        ret = -ENXIO;
+        goto free_master;
+    }
+
+    clk = devm_clk_get(dev, NULL);
+    if (!IS_ERR(clk))
+        spi->clk_rate = clk_get_rate(clk);
+
+    loongson_spi_reginit(spi);
+
+    spi->mode = 0;
+    if (of_get_property(dev->of_node, "spi-nocs", NULL))
+        spi->mode |= SPI_NO_CS;
+
+    ret = spi_register_master(master);
+    if (ret < 0)
+        goto free_master;
+
+    return ret;
+
+free_master:
+    kfree(master);
+    spi_master_put(master);
+
+    return ret;
+}
+EXPORT_SYMBOL_GPL(loongson_spi_init_master);

[...]

diff --git a/drivers/spi/spi-loongson-pci.c b/drivers/spi/spi-loongson-pci.c
new file mode 100644
index 000000000000..b811de769ecb
--- /dev/null
+++ b/drivers/spi/spi-loongson-pci.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+// PCI interface driver for Loongson SPI Support
+// Copyright (C) 2023 Loongson Technology Corporation Limited
+
+#include <linux/pci.h>
+
+#include "spi-loongson.h"
+
+static int loongson_spi_pci_register(struct pci_dev *pdev,
+            const struct pci_device_id *ent)
+{
+    int ret;
+    unsigned char v8;
+    struct resource res[2];
+    struct device *dev = &pdev->dev;
+
+    ret = pci_enable_device(pdev);
+    if (ret < 0) {
+        dev_err(dev, "cannot enable pci device\n");
+        goto err_out;
+    }
+
+    ret = pci_request_region(pdev, 0, "loongson-spi io");
+    if (ret < 0) {
+        dev_err(dev, "cannot request region 0.\n");
+        goto err_out;
+    }
+
+    res[0].start = pci_resource_start(pdev, 0);
+    res[0].end = pci_resource_end(pdev, 0);
+    ret = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &v8);
+
+    if (ret == PCIBIOS_SUCCESSFUL) {
+        res[1].start = v8;
+        res[1].end = v8;
+    }
+
+    ret = loongson_spi_init_master(dev, res);
+    if (ret)
+        dev_err(dev, "failed to initialize master\n");
+
+err_out:
+    return ret;
+}
+
+static void loongson_spi_pci_unregister(struct pci_dev *pdev)
+{
+    pci_release_region(pdev, 0);

pci_disable_device()?
okay, I will add pci_disable_device() here.

Thanks.

+}

CJ