diff options
-rw-r--r-- | Documentation/devicetree/bindings/spi/sh-msiof.txt | 12 | ||||
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 56 |
2 files changed, 67 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt new file mode 100644 index 0000000..e622210 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -0,0 +1,12 @@ +Renesas MSIOF spi controller + +Required properties: +- compatible : "renesas,sh-msiof" for SuperH or + "renesas,sh-mobile-msiof" for SH Mobile series +- reg : Offset and length of the register set for the device +- interrupts : interrupt line used by MSIOF + +Optional properties: +- num-cs : total number of chip-selects +- renesas,tx-fifo-size : Overrides the default tx fifo size given in words +- renesas,rx-fifo-size : Overrides the default rx fifo size given in words diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 96358d0..8b40d08 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -20,6 +20,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -592,6 +593,37 @@ static u32 sh_msiof_spi_txrx_word(struct spi_device *spi, unsigned nsecs, return 0; } +#ifdef CONFIG_OF +static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev) +{ + struct sh_msiof_spi_info *info; + struct device_node *np = dev->of_node; + u32 num_cs = 0; + + info = devm_kzalloc(dev, sizeof(struct sh_msiof_spi_info), GFP_KERNEL); + if (!info) { + dev_err(dev, "failed to allocate setup data\n"); + return NULL; + } + + /* Parse the MSIOF properties */ + of_property_read_u32(np, "num-cs", &num_cs); + of_property_read_u32(np, "renesas,tx-fifo-size", + &info->tx_fifo_override); + of_property_read_u32(np, "renesas,rx-fifo-size", + &info->rx_fifo_override); + + info->num_chipselect = num_cs; + + return info; +} +#else +static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev) +{ + return NULL; +} +#endif + static int sh_msiof_spi_probe(struct platform_device *pdev) { struct resource *r; @@ -610,7 +642,17 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) p = spi_master_get_devdata(master); platform_set_drvdata(pdev, p); - p->info = pdev->dev.platform_data; + if (pdev->dev.of_node) + p->info = sh_msiof_spi_parse_dt(&pdev->dev); + else + p->info = pdev->dev.platform_data; + + if (!p->info) { + dev_err(&pdev->dev, "failed to obtain device info\n"); + ret = -ENXIO; + goto err1; + } + init_completion(&p->done); p->clk = clk_get(&pdev->dev, NULL); @@ -715,6 +757,17 @@ static int sh_msiof_spi_runtime_nop(struct device *dev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id sh_msiof_match[] = { + { .compatible = "renesas,sh-msiof", }, + { .compatible = "renesas,sh-mobile-msiof", }, + {}, +}; +MODULE_DEVICE_TABLE(of, sh_msiof_match); +#else +#define sh_msiof_match NULL +#endif + static struct dev_pm_ops sh_msiof_spi_dev_pm_ops = { .runtime_suspend = sh_msiof_spi_runtime_nop, .runtime_resume = sh_msiof_spi_runtime_nop, @@ -727,6 +780,7 @@ static struct platform_driver sh_msiof_spi_drv = { .name = "spi_sh_msiof", .owner = THIS_MODULE, .pm = &sh_msiof_spi_dev_pm_ops, + .of_match_table = sh_msiof_match, }, }; module_platform_driver(sh_msiof_spi_drv); |