ar71xx: Add kernel 4.9 support
[openwrt/openwrt.git] / target / linux / ar71xx / patches-4.9 / 104-spi-spi-ath79-support-multiple-internal-chip-select-.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Fri, 9 Dec 2016 20:09:16 +0100
3 Subject: [PATCH] spi: spi-ath79: support multiple internal chip select
4 lines
5
6 Several devices with multiple flash chips use the internal chip select
7 lines. Don't assume that chip select 1 and above are GPIO lines.
8
9 Signed-off-by: Felix Fietkau <nbd@nbd.name>
10 ---
11
12 --- a/drivers/spi/spi-ath79.c
13 +++ b/drivers/spi/spi-ath79.c
14 @@ -78,14 +78,16 @@ static void ath79_spi_chipselect(struct
15 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
16 }
17
18 - if (spi->chip_select) {
19 + if (gpio_is_valid(spi->cs_gpio)) {
20 /* SPI is normally active-low */
21 gpio_set_value(spi->cs_gpio, cs_high);
22 } else {
23 + u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
24 +
25 if (cs_high)
26 - sp->ioc_base |= AR71XX_SPI_IOC_CS0;
27 + sp->ioc_base |= cs_bit;
28 else
29 - sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
30 + sp->ioc_base &= ~cs_bit;
31
32 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
33 }
34 @@ -118,11 +120,8 @@ static int ath79_spi_setup_cs(struct spi
35 struct ath79_spi *sp = ath79_spidev_to_sp(spi);
36 int status;
37
38 - if (spi->chip_select && !gpio_is_valid(spi->cs_gpio))
39 - return -EINVAL;
40 -
41 status = 0;
42 - if (spi->chip_select) {
43 + if (gpio_is_valid(spi->cs_gpio)) {
44 unsigned long flags;
45
46 flags = GPIOF_DIR_OUT;
47 @@ -134,10 +133,12 @@ static int ath79_spi_setup_cs(struct spi
48 status = gpio_request_one(spi->cs_gpio, flags,
49 dev_name(&spi->dev));
50 } else {
51 + u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
52 +
53 if (spi->mode & SPI_CS_HIGH)
54 - sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
55 + sp->ioc_base &= ~cs_bit;
56 else
57 - sp->ioc_base |= AR71XX_SPI_IOC_CS0;
58 + sp->ioc_base |= cs_bit;
59
60 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
61 }
62 @@ -147,7 +148,7 @@ static int ath79_spi_setup_cs(struct spi
63
64 static void ath79_spi_cleanup_cs(struct spi_device *spi)
65 {
66 - if (spi->chip_select) {
67 + if (gpio_is_valid(spi->cs_gpio)) {
68 gpio_free(spi->cs_gpio);
69 }
70 }