51054625ee8294b7a7494891cc0d0074e6b76c7b
[oweals/openwrt.git] /
1 From 3353228a04a004ec67073871f40cf58dc4e209aa Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jonas.gorski@gmail.com>
3 Date: Mon, 7 Sep 2015 21:01:38 +0200
4 Subject: [PATCH 4/8] spi/bcm63xx: add support for probing through devicetree
5
6 Add required binding support to probe through device tree.
7
8 Use the compatible instead of the resource size for identifiying the
9 block type, and allow reducing the number of cs lines through OF.
10
11 Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
12 ---
13  drivers/spi/spi-bcm63xx.c | 42 ++++++++++++++++++++++++++++++++++++------
14  1 file changed, 36 insertions(+), 6 deletions(-)
15
16 --- a/drivers/spi/spi-bcm63xx.c
17 +++ b/drivers/spi/spi-bcm63xx.c
18 @@ -26,6 +26,7 @@
19  #include <linux/completion.h>
20  #include <linux/err.h>
21  #include <linux/pm_runtime.h>
22 +#include <linux/of.h>
23  
24  /* BCM 6338/6348 SPI core */
25  #define SPI_6348_RSET_SIZE             64
26 @@ -485,21 +486,48 @@ static const struct platform_device_id b
27         },
28  };
29  
30 +static const struct of_device_id bcm63xx_spi_of_match[] = {
31 +       { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets },
32 +       { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets },
33 +       { },
34 +};
35 +
36  static int bcm63xx_spi_probe(struct platform_device *pdev)
37  {
38         struct resource *r;
39         const unsigned long *bcm63xx_spireg;
40         struct device *dev = &pdev->dev;
41 -       int irq;
42 +       int irq, bus_num;
43         struct spi_master *master;
44         struct clk *clk;
45         struct bcm63xx_spi *bs;
46         int ret;
47 +       u32 num_cs = BCM63XX_SPI_MAX_CS;
48  
49 -       if (!pdev->id_entry->driver_data)
50 -               return -EINVAL;
51 +       if (dev->of_node) {
52 +               const struct of_device_id *match;
53  
54 -       bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data;
55 +               match = of_match_node(bcm63xx_spi_of_match, dev->of_node);
56 +               if (!match)
57 +                       return -EINVAL;
58 +               bcm63xx_spireg = match->data;
59 +
60 +               of_property_read_u32(dev->of_node, "num-cs", &num_cs);
61 +               if (num_cs > BCM63XX_SPI_MAX_CS) {
62 +                       dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n",
63 +                                num_cs);
64 +                       num_cs = BCM63XX_SPI_MAX_CS;
65 +               }
66 +
67 +               bus_num = -1;
68 +       } else if (pdev->id_entry->driver_data) {
69 +               const struct platform_device_id *match = pdev->id_entry;
70 +
71 +               bcm63xx_spireg = (const unsigned long *)match->driver_data;
72 +               bus_num = BCM63XX_SPI_BUS_NUM;
73 +       } else {
74 +               return -EINVAL;
75 +       }
76  
77         irq = platform_get_irq(pdev, 0);
78         if (irq < 0) {
79 @@ -544,8 +572,9 @@ static int bcm63xx_spi_probe(struct plat
80                 goto out_err;
81         }
82  
83 -       master->bus_num = BCM63XX_SPI_BUS_NUM;
84 -       master->num_chipselect = BCM63XX_SPI_MAX_CS;
85 +       master->dev.of_node = dev->of_node;
86 +       master->bus_num = bus_num;
87 +       master->num_chipselect = num_cs;
88         master->transfer_one_message = bcm63xx_spi_transfer_one;
89         master->mode_bits = MODEBITS;
90         master->bits_per_word_mask = SPI_BPW_MASK(8);
91 @@ -634,6 +663,7 @@ static struct platform_driver bcm63xx_sp
92         .driver = {
93                 .name   = "bcm63xx-spi",
94                 .pm     = &bcm63xx_spi_pm_ops,
95 +               .of_match_table = bcm63xx_spi_of_match,
96         },
97         .id_table       = bcm63xx_spi_dev_match,
98         .probe          = bcm63xx_spi_probe,