diff options
Diffstat (limited to 'target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch')
-rw-r--r-- | target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch | 59 |
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; +} |