Add DT support while keeping legacy support. Signed-off-by: Álvaro Fernández Rojas <noltari@xxxxxxxxx> --- diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 16f6115..9792783 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -61,6 +61,9 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` #include <linux/platform_device.h> #include <linux/mod_devicetable.h> #include <linux/basic_mmio_gpio.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> static void bgpio_write8(void __iomem *reg, unsigned long data) { @@ -488,8 +491,58 @@ static void __iomem *bgpio_map(struct platform_device *pdev, return ret; } +#ifdef CONFIG_OF +static const struct of_device_id bgpio_dt_ids[] = { + { .compatible = "basic-mmio-gpio" }, +}; +MODULE_DEVICE_TABLE(of, bgpio_dt_ids); + +static int bgpio_probe_dt(struct platform_device *pdev) +{ + u32 tmp; + struct bgpio_pdata *pdata; + struct device_node *np; + + np = pdev->dev.of_node; + if (!np) + return 0; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->label = dev_name(&pdev->dev); + pdata->base = -1; + if (of_find_property(np, "byte-be", NULL)) { + pdata->flags |= BGPIOF_BIG_ENDIAN_BYTE_ORDER; + } + if (of_find_property(np, "bit-be", NULL)) { + pdata->flags |= BGPIOF_BIG_ENDIAN; + } + if (of_find_property(np, "regset-nr", NULL)) { + pdata->flags |= BGPIOF_UNREADABLE_REG_SET; + } + if (of_find_property(np, "regdir-nr", NULL)) { + pdata->flags |= BGPIOF_UNREADABLE_REG_DIR; + } + if (!of_property_read_u32(np, "num-gpios", &tmp)) { + pdata->ngpio = tmp; + } + + pdev->dev.platform_data = pdata; + + return 1; +} +#else +static inline int bgpio_probe_dt(struct platform_device *pdev) +{ + return 0; +} +#endif + static int bgpio_pdev_probe(struct platform_device *pdev) { + int status; struct device *dev = &pdev->dev; struct resource *r; void __iomem *dat; @@ -498,10 +551,24 @@ static int bgpio_pdev_probe(struct platform_device *pdev) void __iomem *dirout; void __iomem *dirin; unsigned long sz; - unsigned long flags = pdev->id_entry->driver_data; + unsigned long flags; int err; struct bgpio_chip *bgc; - struct bgpio_pdata *pdata = dev_get_platdata(dev); + struct bgpio_pdata *pdata; + bool use_of = 0; + + status = bgpio_probe_dt(pdev); + if (status < 0) + return status; + if (status > 0) + use_of = 1; + + pdata = dev_get_platdata(dev); + + if (!use_of) + flags = pdev->id_entry->driver_data; + else if (pdata) + flags = pdata->flags; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); if (!r) @@ -547,6 +614,9 @@ static int bgpio_pdev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bgc); + if (use_of) + of_gpiochip_add(&bgc->gc); + return gpiochip_add(&bgc->gc); } @@ -572,6 +642,7 @@ MODULE_DEVICE_TABLE(platform, bgpio_id_table); static struct platform_driver bgpio_driver = { .driver = { .name = "basic-mmio-gpio", + .of_match_table = bgpio_dt_ids, }, .id_table = bgpio_id_table, .probe = bgpio_pdev_probe, diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h index 0e97856..a35dffd 100644 --- a/include/linux/basic_mmio_gpio.h +++ b/include/linux/basic_mmio_gpio.h @@ -22,6 +22,7 @@ struct bgpio_pdata { const char *label; int base; int ngpio; + unsigned long flags; }; struct device; -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html