@@ -25,7 +25,7 @@
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
--- /dev/null
+++ b/drivers/spi/spi-mt7621.c
-@@ -0,0 +1,537 @@
+@@ -0,0 +1,532 @@
+/*
+ * spi-mt7621.c -- MediaTek MT7621 SPI controller driver
+ *
@@ -147,13 +147,9 @@
+struct mt7621_spi {
+ struct spi_master *master;
+ void __iomem *base;
-+ unsigned int sys_freq;
+ unsigned int speed;
+ u16 wait_loops;
+ struct clk *clk;
-+ spinlock_t lock;
-+
-+ struct mt7621_spi_ops *ops;
+};
+
+static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi)
@@ -205,15 +201,9 @@
+
+ dev_dbg(&spi->dev, "speed:%u\n", speed);
+
-+ rate = DIV_ROUND_UP(rs->sys_freq, speed);
++ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed);
+ dev_dbg(&spi->dev, "rate-1:%u\n", rate);
+
-+ if (rate > 4097)
-+ return -EINVAL;
-+
-+ if (rate < 2)
-+ rate = 2;
-+
+ reg = mt7621_spi_read(rs, MT7621_SPI_MASTER);
+ reg &= ~(0xfff << 16);
+ reg |= (rate - 2) << 16;
@@ -446,15 +436,12 @@
+
+static int mt7621_spi_setup(struct spi_device *spi)
+{
-+ struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
++ struct spi_master *master = spi->master;
+
-+ if ((spi->max_speed_hz == 0) ||
-+ (spi->max_speed_hz > (rs->sys_freq / 2)))
-+ spi->max_speed_hz = (rs->sys_freq / 2);
-+
-+ if (spi->max_speed_hz < (rs->sys_freq / 4097)) {
-+ dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n",
-+ spi->max_speed_hz);
++ if ((spi->max_speed_hz > master->max_speed_hz) ||
++ (spi->max_speed_hz < master->min_speed_hz)) {
++ dev_err(&spi->dev, "invalide requested speed %d Hz\n",
++ spi->max_speed_hz);
+ return -EINVAL;
+ }
+
@@ -472,17 +459,14 @@
+ const struct of_device_id *match;
+ struct spi_master *master;
+ struct mt7621_spi *rs;
-+ unsigned long flags;
+ void __iomem *base;
+ struct resource *r;
-+ int status = 0;
+ struct clk *clk;
-+ struct mt7621_spi_ops *ops;
++ int ret;
+
+ match = of_match_device(mt7621_spi_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
-+ ops = (struct mt7621_spi_ops *)match->data;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, r);
@@ -491,45 +475,57 @@
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
-+ dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n",
-+ status);
++ dev_err(&pdev->dev, "unable to get SYS clock\n");
+ return PTR_ERR(clk);
+ }
+
-+ status = clk_prepare_enable(clk);
-+ if (status)
-+ return status;
++ ret = clk_prepare_enable(clk);
++ if (ret)
++ goto err_clk;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
+ if (master == NULL) {
-+ dev_info(&pdev->dev, "master allocation failed\n");
-+ return -ENOMEM;
++ dev_err(&pdev->dev, "master allocation failed\n");
++ ret = -ENOMEM;
++ goto err_clk;
+ }
+
++ master->dev.of_node = pdev->dev.of_node;
+ master->mode_bits = MT7621_SPI_MODE_BITS;
-+
++ master->bits_per_word_mask = SPI_BPW_MASK(8);
++ master->min_speed_hz = clk_get_rate(clk) / 4097;
++ master->max_speed_hz = clk_get_rate(clk) / 2;
++ master->flags = SPI_MASTER_HALF_DUPLEX;
+ master->setup = mt7621_spi_setup;
+ master->transfer_one_message = mt7621_spi_transfer_one_message;
-+ master->bits_per_word_mask = SPI_BPW_MASK(8);
-+ master->dev.of_node = pdev->dev.of_node;
+ master->num_chipselect = 2;
+
+ dev_set_drvdata(&pdev->dev, master);
+
+ rs = spi_master_get_devdata(master);
++ rs->master = master;
+ rs->base = base;
+ rs->clk = clk;
-+ rs->master = master;
-+ rs->sys_freq = clk_get_rate(rs->clk);
-+ rs->ops = ops;
-+ dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq);
-+ spin_lock_irqsave(&rs->lock, flags);
+
+ device_reset(&pdev->dev);
+
+ mt7621_spi_reset(rs, 0);
+
-+ return spi_register_master(master);
++ ret = devm_spi_register_master(&pdev->dev, master);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "devm_spi_register_master error.\n");
++ goto err_master;
++ }
++
++ return ret;
++
++err_master:
++ spi_master_put(master);
++ kfree(master);
++err_clk:
++ clk_disable_unprepare(clk);
++
++ return ret;
+}
+
+static int mt7621_spi_remove(struct platform_device *pdev)
@@ -540,8 +536,7 @@
+ master = dev_get_drvdata(&pdev->dev);
+ rs = spi_master_get_devdata(master);
+
-+ clk_disable(rs->clk);
-+ spi_unregister_master(master);
++ clk_disable_unprepare(rs->clk);
+
+ return 0;
+}
* fill struct according to the member order * add error clean up * set min/max spi speed. so we don't need to check again Signed-off-by: Michael Lee <igvtee@gmail.com> --- ...0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch | 79 ++++++++++------------ 1 file changed, 37 insertions(+), 42 deletions(-)