aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch59
1 files changed, 34 insertions, 25 deletions
diff --git a/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch
index 00fdeedb87..605bda92e1 100644
--- a/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch
+++ b/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch
@@ -41,7 +41,7 @@ Acked-by: John Crispin <blogic@openwrt.org>
spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
--- /dev/null
+++ b/drivers/spi/spi-rt2880.c
-@@ -0,0 +1,479 @@
+@@ -0,0 +1,488 @@
+/*
+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
+ *
@@ -166,6 +166,9 @@ Acked-by: John Crispin <blogic@openwrt.org>
+#define SPI1_POR BIT(1)
+#define SPI0_POR BIT(0)
+
++#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \
++ SPI_CS_HIGH)
++
+struct rt2880_spi {
+ struct spi_master *master;
+ void __iomem *base;
@@ -223,13 +226,6 @@ Acked-by: John Crispin <blogic@openwrt.org>
+ rate = roundup_pow_of_two(rate);
+ dev_dbg(&spi->dev, "rate-2:%u\n", rate);
+
-+ /* check if requested speed is too small */
-+ if (rate > 128)
-+ return -EINVAL;
-+
-+ if (rate < 2)
-+ rate = 2;
-+
+ /* Convert the rate to SPI clock divisor value. */
+ prescale = ilog2(rate / 2);
+ dev_dbg(&spi->dev, "prescale:%u\n", prescale);
@@ -430,11 +426,10 @@ Acked-by: John Crispin <blogic@openwrt.org>
+{
+ struct spi_master *master;
+ struct rt2880_spi *rs;
-+ unsigned long flags;
+ void __iomem *base;
+ struct resource *r;
-+ int status = 0;
+ struct clk *clk;
++ int ret;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, r);
@@ -443,36 +438,37 @@ Acked-by: John Crispin <blogic@openwrt.org>
+
+ 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_dbg(&pdev->dev, "master allocation failed\n");
-+ return -ENOMEM;
++ ret = -ENOMEM;
++ goto err_clk;
+ }
+
-+ /* we support only mode 0, and no options */
-+ master->mode_bits = 0;
-+
++ master->dev.of_node = pdev->dev.of_node;
++ master->mode_bits = RT2880_SPI_MODE_BITS;
++ master->bits_per_word_mask = SPI_BPW_MASK(8);
++ master->min_speed_hz = clk_get_rate(clk) / 128;
++ master->max_speed_hz = clk_get_rate(clk) / 2;
++ master->flags = SPI_MASTER_HALF_DUPLEX;
+ master->setup = rt2880_spi_setup;
+ master->transfer_one_message = rt2880_spi_transfer_one_message;
+ master->num_chipselect = RALINK_NUM_CHIPSELECTS;
-+ master->bits_per_word_mask = SPI_BPW_MASK(8);
-+ master->dev.of_node = pdev->dev.of_node;
+
+ 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);
+ dev_dbg(&pdev->dev, "sys_freq: %u\n", rs->sys_freq);
+
@@ -480,7 +476,21 @@ Acked-by: John Crispin <blogic@openwrt.org>
+
+ rt2880_spi_reset(rs);
+
-+ 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 rt2880_spi_remove(struct platform_device *pdev)
@@ -491,8 +501,7 @@ Acked-by: John Crispin <blogic@openwrt.org>
+ 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;
+}