aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorJonas Gorski2017-02-21 11:58:22 +0100
committerMark Brown2017-02-21 15:04:14 -0800
commitc29f08890ae337e398becf5ba586114553e99771 (patch)
tree7584194f189a7f680e2e227c2d922c7505bd02bf /drivers/spi
parent0135c03df914f0481c61f097c78d37cece84f330 (diff)
spi/bcm63xx: allow for probing through devicetree
Add required binding support to probe through device tree. Use the compatible instead of the resource size for identifiying the block type, and allow reducing the number of cs lines through OF. Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-bcm63xx.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index caa733ec405c..325131370941 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -26,6 +26,7 @@
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
+#include <linux/of.h>
/* BCM 6338/6348 SPI core */
#define SPI_6348_RSET_SIZE 64
@@ -484,21 +485,48 @@ static const struct platform_device_id bcm63xx_spi_dev_match[] = {
},
};
+static const struct of_device_id bcm63xx_spi_of_match[] = {
+ { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets },
+ { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets },
+ { },
+};
+
static int bcm63xx_spi_probe(struct platform_device *pdev)
{
struct resource *r;
const unsigned long *bcm63xx_spireg;
struct device *dev = &pdev->dev;
- int irq;
+ int irq, bus_num;
struct spi_master *master;
struct clk *clk;
struct bcm63xx_spi *bs;
int ret;
+ u32 num_cs = BCM63XX_SPI_MAX_CS;
- if (!pdev->id_entry->driver_data)
- return -EINVAL;
+ if (dev->of_node) {
+ const struct of_device_id *match;
- bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data;
+ match = of_match_node(bcm63xx_spi_of_match, dev->of_node);
+ if (!match)
+ return -EINVAL;
+ bcm63xx_spireg = match->data;
+
+ of_property_read_u32(dev->of_node, "num-cs", &num_cs);
+ if (num_cs > BCM63XX_SPI_MAX_CS) {
+ dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n",
+ num_cs);
+ num_cs = BCM63XX_SPI_MAX_CS;
+ }
+
+ bus_num = -1;
+ } else if (pdev->id_entry->driver_data) {
+ const struct platform_device_id *match = pdev->id_entry;
+
+ bcm63xx_spireg = (const unsigned long *)match->driver_data;
+ bus_num = BCM63XX_SPI_BUS_NUM;
+ } else {
+ return -EINVAL;
+ }
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -543,8 +571,9 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
goto out_err;
}
- master->bus_num = BCM63XX_SPI_BUS_NUM;
- master->num_chipselect = BCM63XX_SPI_MAX_CS;
+ master->dev.of_node = dev->of_node;
+ master->bus_num = bus_num;
+ master->num_chipselect = num_cs;
master->transfer_one_message = bcm63xx_spi_transfer_one;
master->mode_bits = MODEBITS;
master->bits_per_word_mask = SPI_BPW_MASK(8);
@@ -633,6 +662,7 @@ static struct platform_driver bcm63xx_spi_driver = {
.driver = {
.name = "bcm63xx-spi",
.pm = &bcm63xx_spi_pm_ops,
+ .of_match_table = bcm63xx_spi_of_match,
},
.id_table = bcm63xx_spi_dev_match,
.probe = bcm63xx_spi_probe,