diff options
Diffstat (limited to 'drivers/soc/amlogic/meson-canvas.c')
| -rw-r--r-- | drivers/soc/amlogic/meson-canvas.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c index fce33ca76bb6..79681afea8c6 100644 --- a/drivers/soc/amlogic/meson-canvas.c +++ b/drivers/soc/amlogic/meson-canvas.c @@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <linux/mfd/syscon.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/soc/amlogic/meson-canvas.h> #include <linux/of_address.h> @@ -35,6 +36,7 @@ struct meson_canvas { void __iomem *reg_base; spinlock_t lock; /* canvas device lock */ u8 used[NUM_CANVAS]; + bool supports_endianness; }; static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val) @@ -51,16 +53,28 @@ struct meson_canvas *meson_canvas_get(struct device *dev) { struct device_node *canvas_node; struct platform_device *canvas_pdev; + struct meson_canvas *canvas; canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0); if (!canvas_node) return ERR_PTR(-ENODEV); canvas_pdev = of_find_device_by_node(canvas_node); + of_node_put(canvas_node); if (!canvas_pdev) return ERR_PTR(-EPROBE_DEFER); - return dev_get_drvdata(&canvas_pdev->dev); + /* + * If priv is NULL, it's probably because the canvas hasn't + * properly initialized. Bail out with -EINVAL because, in the + * current state, this driver probe cannot return -EPROBE_DEFER + */ + canvas = dev_get_drvdata(&canvas_pdev->dev); + put_device(&canvas_pdev->dev); + if (!canvas) + return ERR_PTR(-EINVAL); + + return canvas; } EXPORT_SYMBOL_GPL(meson_canvas_get); @@ -72,6 +86,12 @@ int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index, { unsigned long flags; + if (endian && !canvas->supports_endianness) { + dev_err(canvas->dev, + "Endianness is not supported on this SoC\n"); + return -EINVAL; + } + spin_lock_irqsave(&canvas->lock, flags); if (!canvas->used[canvas_index]) { dev_err(canvas->dev, @@ -145,7 +165,6 @@ EXPORT_SYMBOL_GPL(meson_canvas_free); static int meson_canvas_probe(struct platform_device *pdev) { - struct resource *res; struct meson_canvas *canvas; struct device *dev = &pdev->dev; @@ -153,11 +172,12 @@ static int meson_canvas_probe(struct platform_device *pdev) if (!canvas) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - canvas->reg_base = devm_ioremap_resource(dev, res); + canvas->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(canvas->reg_base)) return PTR_ERR(canvas->reg_base); + canvas->supports_endianness = of_device_get_match_data(dev); + canvas->dev = dev; spin_lock_init(&canvas->lock); dev_set_drvdata(dev, canvas); @@ -166,7 +186,10 @@ static int meson_canvas_probe(struct platform_device *pdev) } static const struct of_device_id canvas_dt_match[] = { - { .compatible = "amlogic,canvas" }, + { .compatible = "amlogic,meson8-canvas", .data = (void *)false, }, + { .compatible = "amlogic,meson8b-canvas", .data = (void *)false, }, + { .compatible = "amlogic,meson8m2-canvas", .data = (void *)false, }, + { .compatible = "amlogic,canvas", .data = (void *)true, }, {} }; MODULE_DEVICE_TABLE(of, canvas_dt_match); |
