summaryrefslogtreecommitdiff
path: root/target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2016-01-30 13:19:53 +0000
committerFelix Fietkau <nbd@openwrt.org>2016-01-30 13:19:53 +0000
commit2530640f07cd2b3b14fe9ec03fa63a586452cc5f (patch)
treeda4d0e63a6771cbd044d3ba8d8dc97bd0615920f /target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch
parente5b5cce442f6fdaccf86064657518a5d0404f78e (diff)
downloadmtk-20170518-2530640f07cd2b3b14fe9ec03fa63a586452cc5f.zip
mtk-20170518-2530640f07cd2b3b14fe9ec03fa63a586452cc5f.tar.gz
mtk-20170518-2530640f07cd2b3b14fe9ec03fa63a586452cc5f.tar.bz2
ar71xx: add support for linux 4.4
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 48563
Diffstat (limited to 'target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch')
-rw-r--r--target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch199
1 files changed, 199 insertions, 0 deletions
diff --git a/target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch b/target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch
new file mode 100644
index 0000000..e0863a4
--- /dev/null
+++ b/target/linux/ar71xx/patches-4.4/206-spi-ath79-make-chipselect-logic-more-flexible.patch
@@ -0,0 +1,199 @@
+From 7008284716403237f6bc7d7590b3ed073555bd56 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Wed, 11 Jan 2012 22:25:11 +0100
+Subject: [PATCH 34/34] spi/ath79: make chipselect logic more flexible
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ arch/mips/ath79/mach-pb44.c | 6 ++
+ .../include/asm/mach-ath79/ath79_spi_platform.h | 8 ++-
+ drivers/spi/spi-ath79.c | 67 +++++++++++++-------
+ 8 files changed, 88 insertions(+), 23 deletions(-)
+
+--- a/arch/mips/ath79/mach-pb44.c
++++ b/arch/mips/ath79/mach-pb44.c
+@@ -87,12 +87,18 @@ static struct gpio_keys_button pb44_gpio
+ }
+ };
+
++static struct ath79_spi_controller_data pb44_spi0_data = {
++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
++ .cs_line = 0,
++};
++
+ static struct spi_board_info pb44_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
++ .controller_data = &pb44_spi0_data,
+ },
+ };
+
+--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
++++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
+@@ -16,8 +16,14 @@ struct ath79_spi_platform_data {
+ unsigned num_chipselect;
+ };
+
++enum ath79_spi_cs_type {
++ ATH79_SPI_CS_TYPE_INTERNAL,
++ ATH79_SPI_CS_TYPE_GPIO,
++};
++
+ struct ath79_spi_controller_data {
+- unsigned gpio;
++ enum ath79_spi_cs_type cs_type;
++ unsigned cs_line;
+ };
+
+ #endif /* _ATH79_SPI_PLATFORM_H */
+--- a/drivers/spi/spi-ath79.c
++++ b/drivers/spi/spi-ath79.c
+@@ -33,6 +33,8 @@
+ #define ATH79_SPI_RRW_DELAY_FACTOR 12000
+ #define MHZ (1000 * 1000)
+
++#define ATH79_SPI_CS_LINE_MAX 2
++
+ struct ath79_spi {
+ struct spi_bitbang bitbang;
+ u32 ioc_base;
+@@ -67,6 +69,7 @@ static void ath79_spi_chipselect(struct
+ {
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+ int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
++ struct ath79_spi_controller_data *cdata = spi->controller_data;
+
+ if (is_active) {
+ /* set initial clock polarity */
+@@ -78,20 +81,24 @@ static void ath79_spi_chipselect(struct
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+- if (spi->chip_select) {
+- struct ath79_spi_controller_data *cdata = spi->controller_data;
+-
+- /* SPI is normally active-low */
+- gpio_set_value(cdata->gpio, cs_high);
+- } else {
++ switch (cdata->cs_type) {
++ case ATH79_SPI_CS_TYPE_INTERNAL:
+ if (cs_high)
+- sp->ioc_base |= AR71XX_SPI_IOC_CS0;
++ sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line);
+ else
+- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
++ sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line);
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+- }
++ break;
+
++ case ATH79_SPI_CS_TYPE_GPIO:
++ /* SPI is normally active-low */
++ if (gpio_cansleep(cdata->cs_line))
++ gpio_set_value_cansleep(cdata->cs_line, cs_high);
++ else
++ gpio_set_value(cdata->cs_line, cs_high);
++ break;
++ }
+ }
+
+ static void ath79_spi_enable(struct ath79_spi *sp)
+@@ -119,14 +126,15 @@ static int ath79_spi_setup_cs(struct spi
+ {
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+ struct ath79_spi_controller_data *cdata = spi->controller_data;
++ unsigned long flags;
+ int status;
+
+- if (spi->chip_select && (!cdata || !gpio_is_valid(cdata->gpio)))
++ if (!cdata)
+ return -EINVAL;
+
+ status = 0;
+- if (spi->chip_select) {
+- unsigned long flags;
++ switch (cdata->cs_type) {
++ case ATH79_SPI_CS_TYPE_GPIO:
+
+ flags = GPIOF_DIR_OUT;
+ if (spi->mode & SPI_CS_HIGH)
+@@ -134,15 +142,21 @@ static int ath79_spi_setup_cs(struct spi
+ else
+ flags |= GPIOF_INIT_HIGH;
+
+- status = gpio_request_one(cdata->gpio, flags,
++ status = gpio_request_one(cdata->cs_line, flags,
+ dev_name(&spi->dev));
+- } else {
++ break;
++ case ATH79_SPI_CS_TYPE_INTERNAL:
++ if (cdata->cs_line > ATH79_SPI_CS_LINE_MAX)
++ status = -EINVAL;
++ break;
++
+ if (spi->mode & SPI_CS_HIGH)
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+ else
+ sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
++ break;
+ }
+
+ return status;
+@@ -150,9 +164,19 @@ static int ath79_spi_setup_cs(struct spi
+
+ static void ath79_spi_cleanup_cs(struct spi_device *spi)
+ {
+- if (spi->chip_select) {
+- struct ath79_spi_controller_data *cdata = spi->controller_data;
+- gpio_free(cdata->gpio);
++ struct ath79_spi_controller_data *cdata;
++
++ cdata = spi->controller_data;
++ if (!cdata)
++ return;
++
++ switch (cdata->cs_type) {
++ case ATH79_SPI_CS_TYPE_INTERNAL:
++ /* nothing to do */
++ break;
++ case ATH79_SPI_CS_TYPE_GPIO:
++ gpio_free(cdata->cs_line);
++ break;
+ }
+ }
+
+@@ -217,6 +241,10 @@ static int ath79_spi_probe(struct platfo
+ unsigned long rate;
+ int ret;
+
++ pdata = pdev->dev.platform_data;
++ if (!pdata)
++ return -EINVAL;
++
+ master = spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "failed to allocate spi master\n");
+@@ -226,15 +254,11 @@ static int ath79_spi_probe(struct platfo
+ sp = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, sp);
+
+- pdata = dev_get_platdata(&pdev->dev);
+-
+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+ master->setup = ath79_spi_setup;
+ master->cleanup = ath79_spi_cleanup;
+- if (pdata) {
+- master->bus_num = pdata->bus_num;
+- master->num_chipselect = pdata->num_chipselect;
+- }
++ master->bus_num = pdata->bus_num;
++ master->num_chipselect = pdata->num_chipselect;
+
+ sp->bitbang.master = master;
+ sp->bitbang.chipselect = ath79_spi_chipselect;