Fresh pull from upstream
[librecmc/librecmc.git] / target / linux / ar71xx / patches-4.4 / 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  }