97c596ae2781f0eae6933cdd65cbbf8dcce0e916
[openwrt/staging/thess.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 @@ -484,21 +485,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 @@ -543,8 +571,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 @@ -633,6 +662,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,