From 587680c1c52d73bc7d5dbba2dcfadacb7a3f6b0e Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 2 Oct 2016 08:01:22 +0200 Subject: drm: Release resources with a safer function We should use 'ida_simple_remove()' instead of 'ida_remove()' when freeing resources allocated with 'ida_simple_get()'. This as been spotted with the following coccinelle script which tries to detect missing 'ida_simple_remove()' call in error handling paths. /////////////// @@ expression x; identifier l; @@ * x = ida_simple_get(...); ... if (...) { ... } ... if (...) { ... goto l; } ... * l: ... when != ida_simple_remove(...); Signed-off-by: Christophe JAILLET Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1475388082-12656-1-git-send-email-christophe.jaillet@wanadoo.fr --- drivers/gpu/drm/drm_connector.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 26bb78c76481..2e7430283043 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -250,10 +250,10 @@ int drm_connector_init(struct drm_device *dev, connector->debugfs_entry = NULL; out_put_type_id: if (ret) - ida_remove(connector_ida, connector->connector_type_id); + ida_simple_remove(connector_ida, connector->connector_type_id); out_put_id: if (ret) - ida_remove(&config->connector_ida, connector->index); + ida_simple_remove(&config->connector_ida, connector->index); out_put: if (ret) drm_mode_object_unregister(dev, &connector->base); -- cgit v1.2.3 From 7d83a155f0c4bf86bd6dfced1768c0a34add8f1b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 2 Oct 2016 19:01:24 +0200 Subject: drm: simple_kms_helper: Add prepare_fb and cleanup_fb hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add .prepare_fb and .cleanup_fb plane hooks into the drm_simple_kms. These can be used by drivers to call ie. the drm_fb_cma_setup_fence() helper. Signed-off-by: Marek Vasut Cc: Noralf Trønnes Cc: Daniel Vetter Cc: David Airlie Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161002170124.6099-1-marex@denx.de --- drivers/gpu/drm/drm_simple_kms_helper.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 7b6d26e64977..7bae08c2bf0a 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -125,7 +125,33 @@ static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane, pipe->funcs->update(pipe, pstate); } +static int drm_simple_kms_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct drm_simple_display_pipe *pipe; + + pipe = container_of(plane, struct drm_simple_display_pipe, plane); + if (!pipe->funcs || !pipe->funcs->prepare_fb) + return 0; + + return pipe->funcs->prepare_fb(pipe, state); +} + +static void drm_simple_kms_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct drm_simple_display_pipe *pipe; + + pipe = container_of(plane, struct drm_simple_display_pipe, plane); + if (!pipe->funcs || !pipe->funcs->cleanup_fb) + return; + + pipe->funcs->cleanup_fb(pipe, state); +} + static const struct drm_plane_helper_funcs drm_simple_kms_plane_helper_funcs = { + .prepare_fb = drm_simple_kms_plane_prepare_fb, + .cleanup_fb = drm_simple_kms_plane_cleanup_fb, .atomic_check = drm_simple_kms_plane_atomic_check, .atomic_update = drm_simple_kms_plane_atomic_update, }; -- cgit v1.2.3 From bf3b123e3d946dc110020814106ad84a36898d3a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Oct 2016 00:23:31 +0200 Subject: drm/bridge: Call drm_connector_cleanup directly Remove the unnecessary wrapper functions around drm_connector_cleanup(). Signed-off-by: Marek Vasut Cc: Daniel Vetter Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161004222331.7200-1-marex@denx.de --- drivers/gpu/drm/bridge/analogix-anx78xx.c | 7 +------ drivers/gpu/drm/bridge/nxp-ptn3460.c | 7 +------ drivers/gpu/drm/bridge/parade-ps8622.c | 7 +------ 3 files changed, 3 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index f9f03bcba0af..a2a82366a771 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -1001,16 +1001,11 @@ static enum drm_connector_status anx78xx_detect(struct drm_connector *connector, return connector_status_connected; } -static void anx78xx_connector_destroy(struct drm_connector *connector) -{ - drm_connector_cleanup(connector); -} - static const struct drm_connector_funcs anx78xx_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = anx78xx_detect, - .destroy = anx78xx_connector_destroy, + .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c index 93f3dacf9e27..f1a99938e924 100644 --- a/drivers/gpu/drm/bridge/nxp-ptn3460.c +++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c @@ -245,16 +245,11 @@ static enum drm_connector_status ptn3460_detect(struct drm_connector *connector, return connector_status_connected; } -static void ptn3460_connector_destroy(struct drm_connector *connector) -{ - drm_connector_cleanup(connector); -} - static const struct drm_connector_funcs ptn3460_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = ptn3460_detect, - .destroy = ptn3460_connector_destroy, + .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c index f1b39a2645cc..6f7c2f9860d2 100644 --- a/drivers/gpu/drm/bridge/parade-ps8622.c +++ b/drivers/gpu/drm/bridge/parade-ps8622.c @@ -483,16 +483,11 @@ static enum drm_connector_status ps8622_detect(struct drm_connector *connector, return connector_status_connected; } -static void ps8622_connector_destroy(struct drm_connector *connector) -{ - drm_connector_cleanup(connector); -} - static const struct drm_connector_funcs ps8622_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = ps8622_detect, - .destroy = ps8622_connector_destroy, + .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -- cgit v1.2.3 From 56a76c0123d6cb034975901c80fce2627338ef9e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 5 Oct 2016 13:21:43 +0100 Subject: drm/prime: Pass the right module owner through to dma_buf_export() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dma_buf_export() adds a reference to the owning module to the dmabuf (to prevent the driver from being unloaded whilst a third party still refers to the dmabuf). However, drm_gem_prime_export() was passing its own THIS_MODULE (i.e. drm.ko) rather than the driver. Extract the right owner from the device->fops instead. v2: Use C99 initializers to zero out unset elements of dma_buf_export_info v3: Extract the right module from dev->fops. Testcase: igt/vgem_basic/unload Reported-by: Petri Latvala Signed-off-by: Chris Wilson Cc: Petri Latvala Cc: Christian König Cc: stable@vger.kernel.org Tested-by: Petri Latvala Reviewed-by: Petri Latvala Reviewed-by: Christian König Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161005122145.1507-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_prime.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 57201d68cf61..80907b34d857 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -397,14 +397,17 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { * using the PRIME helpers. */ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, - struct drm_gem_object *obj, int flags) + struct drm_gem_object *obj, + int flags) { - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - - exp_info.ops = &drm_gem_prime_dmabuf_ops; - exp_info.size = obj->size; - exp_info.flags = flags; - exp_info.priv = obj; + struct dma_buf_export_info exp_info = { + .exp_name = KBUILD_MODNAME, /* white lie for debug */ + .owner = dev->driver->fops->owner, + .ops = &drm_gem_prime_dmabuf_ops, + .size = obj->size, + .flags = flags, + .priv = obj, + }; if (dev->driver->gem_prime_res_obj) exp_info.resv = dev->driver->gem_prime_res_obj(obj); -- cgit v1.2.3 From a4fce9cb782ad340ee5576a38e934e5e75832dc6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 5 Oct 2016 13:21:44 +0100 Subject: drm/prime: Take a ref on the drm_dev when exporting a dma_buf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dma_buf may live a long time, longer than the last direct user of the driver. We already hold a reference to the owner module (that prevents the object code from disappearing), but there is no reference to the drm_dev - so the pointers to the driver backend themselves may vanish. v2: Resist temptation to fix the bug in armada_gem.c not setting the correct flags on the exported dma-buf (it should pass the flags through and not be arbitrarily setting O_RDWR). Use a common wrapper for exporting the dmabuf and acquiring the reference to the drm_device. Testcase: igt/vgem_basic/unload Suggested-by: Daniel Vetter Signed-off-by: Chris Wilson Cc: Petri Latvala Cc: Daniel Vetter Cc: stable@vger.kernel.org Tested-by: Petri Latvala Reviewed-by: Christian König Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161005122145.1507-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/armada/armada_gem.c | 2 +- drivers/gpu/drm/drm_prime.c | 30 +++++++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 +- drivers/gpu/drm/tegra/gem.c | 2 +- drivers/gpu/drm/udl/udl_dmabuf.c | 2 +- 5 files changed, 33 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index cb8f0347b934..a5e428d27d2f 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -547,7 +547,7 @@ armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, exp_info.flags = O_RDWR; exp_info.priv = obj; - return dma_buf_export(&exp_info); + return drm_gem_dmabuf_export(dev, &exp_info); } struct drm_gem_object * diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 80907b34d857..875df8d719fb 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -283,19 +283,47 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, /* nothing to be done here */ } +/** + * drm_gem_dmabuf_export - dma_buf export implementation for GEM + * @dma_buf: buffer to be exported + * + * This wraps dma_buf_export() for use by generic GEM drivers that are using + * drm_gem_dmabuf_release(). In addition to calling dma_buf_export(), we take + * a reference to the drm_device which is released by drm_gem_dmabuf_release(). + * + * Returns the new dmabuf. + */ +struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, + struct dma_buf_export_info *exp_info) +{ + struct dma_buf *dma_buf; + + dma_buf = dma_buf_export(exp_info); + if (!IS_ERR(dma_buf)) + drm_dev_ref(dev); + + return dma_buf; +} +EXPORT_SYMBOL(drm_gem_dmabuf_export); + /** * drm_gem_dmabuf_release - dma_buf release implementation for GEM * @dma_buf: buffer to be released * * Generic release function for dma_bufs exported as PRIME buffers. GEM drivers * must use this in their dma_buf ops structure as the release callback. + * drm_gem_dmabuf_release() should be used in conjunction with + * drm_gem_dmabuf_export(). */ void drm_gem_dmabuf_release(struct dma_buf *dma_buf) { struct drm_gem_object *obj = dma_buf->priv; + struct drm_device *dev = obj->dev; /* drop the reference on the export fd holds */ drm_gem_object_unreference_unlocked(obj); + + drm_dev_unref(dev); } EXPORT_SYMBOL(drm_gem_dmabuf_release); @@ -412,7 +440,7 @@ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, if (dev->driver->gem_prime_res_obj) exp_info.resv = dev->driver->gem_prime_res_obj(obj); - return dma_buf_export(&exp_info); + return drm_gem_dmabuf_export(dev, &exp_info); } EXPORT_SYMBOL(drm_gem_prime_export); diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 10265bb35604..97c9d68b45df 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -283,7 +283,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, return ERR_PTR(ret); } - dma_buf = dma_buf_export(&exp_info); + dma_buf = drm_gem_dmabuf_export(dev, &exp_info); if (IS_ERR(dma_buf)) return dma_buf; diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index aa60d9909ea2..95e622e31931 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -613,7 +613,7 @@ struct dma_buf *tegra_gem_prime_export(struct drm_device *drm, exp_info.flags = flags; exp_info.priv = gem; - return dma_buf_export(&exp_info); + return drm_gem_dmabuf_export(drm, &exp_info); } struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm, diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c index e2243edd1ce3..ac90ffdb5912 100644 --- a/drivers/gpu/drm/udl/udl_dmabuf.c +++ b/drivers/gpu/drm/udl/udl_dmabuf.c @@ -209,7 +209,7 @@ struct dma_buf *udl_gem_prime_export(struct drm_device *dev, exp_info.flags = flags; exp_info.priv = obj; - return dma_buf_export(&exp_info); + return drm_gem_dmabuf_export(dev, &exp_info); } static int udl_prime_create(struct drm_device *dev, -- cgit v1.2.3 From 56fe8b6f499167e3f9e0aafc0909efe9fb673323 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 30 Sep 2016 16:37:06 +0200 Subject: drm/bridge: Add RGB to VGA bridge support Some boards have an entirely passive RGB to VGA bridge, based on DACs implemented by resistor ladders. Those might or might not have an i2c bus routed to the VGA connector in order to access the screen EDIDs. Add a bridge that doesn't do anything but expose the modes available on the screen, either based on the EDIDs if available, or based on the XGA standards. Acked-by: Rob Herring Reviewed-by: Sean Paul Tested-by: Laurent Pinchart Signed-off-by: Maxime Ripard Signed-off-by: Archit Taneja Link: http://patchwork.freedesktop.org/patch/msgid/20160930143709.1388-3-maxime.ripard@free-electrons.com --- drivers/gpu/drm/bridge/Kconfig | 7 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/dumb-vga-dac.c | 223 ++++++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 drivers/gpu/drm/bridge/dumb-vga-dac.c (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index b590e678052d..10e12e74fc9f 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -17,6 +17,13 @@ config DRM_ANALOGIX_ANX78XX the HDMI output of an application processor to MyDP or DisplayPort. +config DRM_DUMB_VGA_DAC + tristate "Dumb VGA DAC Bridge support" + depends on OF + select DRM_KMS_HELPER + help + Support for RGB to VGA DAC based bridges + config DRM_DW_HDMI tristate select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index efdb07e878f5..cdf3a3cf765d 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,7 @@ ccflags-y := -Iinclude/drm obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o +obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c new file mode 100644 index 000000000000..afec232185a7 --- /dev/null +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2015-2016 Free Electrons + * Copyright (C) 2015-2016 NextThing Co + * + * Maxime Ripard + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include + +#include +#include +#include +#include + +struct dumb_vga { + struct drm_bridge bridge; + struct drm_connector connector; + + struct i2c_adapter *ddc; +}; + +static inline struct dumb_vga * +drm_bridge_to_dumb_vga(struct drm_bridge *bridge) +{ + return container_of(bridge, struct dumb_vga, bridge); +} + +static inline struct dumb_vga * +drm_connector_to_dumb_vga(struct drm_connector *connector) +{ + return container_of(connector, struct dumb_vga, connector); +} + +static int dumb_vga_get_modes(struct drm_connector *connector) +{ + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); + struct edid *edid; + int ret; + + if (IS_ERR(vga->ddc)) + goto fallback; + + edid = drm_get_edid(connector, vga->ddc); + if (!edid) { + DRM_INFO("EDID readout failed, falling back to standard modes\n"); + goto fallback; + } + + drm_mode_connector_update_edid_property(connector, edid); + return drm_add_edid_modes(connector, edid); + +fallback: + /* + * In case we cannot retrieve the EDIDs (broken or missing i2c + * bus), fallback on the XGA standards + */ + ret = drm_add_modes_noedid(connector, 1920, 1200); + + /* And prefer a mode pretty much anyone can handle */ + drm_set_preferred_mode(connector, 1024, 768); + + return ret; +} + +static const struct drm_connector_helper_funcs dumb_vga_con_helper_funcs = { + .get_modes = dumb_vga_get_modes, +}; + +static enum drm_connector_status +dumb_vga_connector_detect(struct drm_connector *connector, bool force) +{ + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); + + /* + * Even if we have an I2C bus, we can't assume that the cable + * is disconnected if drm_probe_ddc fails. Some cables don't + * wire the DDC pins, or the I2C bus might not be working at + * all. + */ + if (!IS_ERR(vga->ddc) && drm_probe_ddc(vga->ddc)) + return connector_status_connected; + + return connector_status_unknown; +} + +static const struct drm_connector_funcs dumb_vga_con_funcs = { + .dpms = drm_atomic_helper_connector_dpms, + .detect = dumb_vga_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int dumb_vga_attach(struct drm_bridge *bridge) +{ + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge); + int ret; + + if (!bridge->encoder) { + DRM_ERROR("Missing encoder\n"); + return -ENODEV; + } + + drm_connector_helper_add(&vga->connector, + &dumb_vga_con_helper_funcs); + ret = drm_connector_init(bridge->dev, &vga->connector, + &dumb_vga_con_funcs, DRM_MODE_CONNECTOR_VGA); + if (ret) { + DRM_ERROR("Failed to initialize connector\n"); + return ret; + } + + drm_mode_connector_attach_encoder(&vga->connector, + bridge->encoder); + + return 0; +} + +static const struct drm_bridge_funcs dumb_vga_bridge_funcs = { + .attach = dumb_vga_attach, +}; + +static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev) +{ + struct device_node *end_node, *phandle, *remote; + struct i2c_adapter *ddc; + + end_node = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1); + if (!end_node) { + dev_err(dev, "Missing connector endpoint\n"); + return ERR_PTR(-ENODEV); + } + + remote = of_graph_get_remote_port_parent(end_node); + of_node_put(end_node); + if (!remote) { + dev_err(dev, "Enable to parse remote node\n"); + return ERR_PTR(-EINVAL); + } + + phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0); + of_node_put(remote); + if (!phandle) + return ERR_PTR(-ENODEV); + + ddc = of_get_i2c_adapter_by_node(phandle); + of_node_put(phandle); + if (!ddc) + return ERR_PTR(-EPROBE_DEFER); + + return ddc; +} + +static int dumb_vga_probe(struct platform_device *pdev) +{ + struct dumb_vga *vga; + int ret; + + vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL); + if (!vga) + return -ENOMEM; + platform_set_drvdata(pdev, vga); + + vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev); + if (IS_ERR(vga->ddc)) { + if (PTR_ERR(vga->ddc) == -ENODEV) { + dev_dbg(&pdev->dev, + "No i2c bus specified. Disabling EDID readout\n"); + } else { + dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n"); + return PTR_ERR(vga->ddc); + } + } + + vga->bridge.funcs = &dumb_vga_bridge_funcs; + vga->bridge.of_node = pdev->dev.of_node; + + ret = drm_bridge_add(&vga->bridge); + if (ret && !IS_ERR(vga->ddc)) + i2c_put_adapter(vga->ddc); + + return ret; +} + +static int dumb_vga_remove(struct platform_device *pdev) +{ + struct dumb_vga *vga = platform_get_drvdata(pdev); + + drm_bridge_remove(&vga->bridge); + + if (!IS_ERR(vga->ddc)) + i2c_put_adapter(vga->ddc); + + return 0; +} + +static const struct of_device_id dumb_vga_match[] = { + { .compatible = "dumb-vga-dac" }, + {}, +}; +MODULE_DEVICE_TABLE(of, dumb_vga_match); + +static struct platform_driver dumb_vga_driver = { + .probe = dumb_vga_probe, + .remove = dumb_vga_remove, + .driver = { + .name = "dumb-vga-dac", + .of_match_table = dumb_vga_match, + }, +}; +module_platform_driver(dumb_vga_driver); + +MODULE_AUTHOR("Maxime Ripard "); +MODULE_DESCRIPTION("Dumb VGA DAC bridge driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From fdd8326a016a70f0ec96f5bb3011a5183961df2e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Oct 2016 16:31:33 +0200 Subject: drm/bridge: Drop drm_connector_unregister and call drm_connector_cleanup directly Drop unneeded drm_connector_unregister() and remove the unnecessary wrapper functions around drm_connector_cleanup(). Signed-off-by: Marek Vasut Cc: Daniel Vetter Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161005143133.5549-1-marex@denx.de --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +-------- drivers/gpu/drm/bridge/dw-hdmi.c | 8 +------- drivers/gpu/drm/bridge/tc358767.c | 8 +------- 3 files changed, 3 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 001b075e171b..6e0447f329a2 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -999,18 +999,11 @@ analogix_dp_detect(struct drm_connector *connector, bool force) return status; } -static void analogix_dp_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); - -} - static const struct drm_connector_funcs analogix_dp_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = analogix_dp_detect, - .destroy = analogix_dp_connector_destroy, + .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 66ad8e6fb11e..ab7023e5dfde 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1477,12 +1477,6 @@ dw_hdmi_connector_mode_valid(struct drm_connector *connector, return mode_status; } -static void dw_hdmi_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} - static void dw_hdmi_connector_force(struct drm_connector *connector) { struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, @@ -1499,7 +1493,7 @@ static const struct drm_connector_funcs dw_hdmi_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = dw_hdmi_connector_detect, - .destroy = dw_hdmi_connector_destroy, + .destroy = drm_connector_cleanup, .force = dw_hdmi_connector_force, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index a09825d8c94a..44d476ea6d2e 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1165,17 +1165,11 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = { .best_encoder = tc_connector_best_encoder, }; -static void tc_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} - static const struct drm_connector_funcs tc_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = tc_connector_detect, - .destroy = tc_connector_destroy, + .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -- cgit v1.2.3 From 67c8f116f5d59df46c2be99674542b43195b21d7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 5 Oct 2016 18:40:56 +0100 Subject: drm: Fix up kerneldoc for new drm_gem_dmabuf_export() I hit send before completing a make htmldoc, and lo I forgot to fix up the cut'n'paste. Fixes: a4fce9cb782a ("drm/prime: Take a ref on the drm_dev when exporting...") Reported-by: kbuild test robot Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161005174056.29869-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_prime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 875df8d719fb..b22a94dd7b53 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -285,7 +285,8 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, /** * drm_gem_dmabuf_export - dma_buf export implementation for GEM - * @dma_buf: buffer to be exported + * @dev: parent device for the exported dmabuf + * @exp_info: the export information used by dma_buf_export() * * This wraps dma_buf_export() for use by generic GEM drivers that are using * drm_gem_dmabuf_release(). In addition to calling dma_buf_export(), we take -- cgit v1.2.3 From 9a47dba1f93148acb4e74f07716df7fad989c2e0 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 7 Oct 2016 09:27:41 +0200 Subject: drm: Release resources with a safer function We should use 'ida_simple_remove()' instead of 'ida_remove()' when freeing resources allocated with 'ida_simple_get()'. Signed-off-by: Christophe JAILLET Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1475825261-7735-1-git-send-email-christophe.jaillet@wanadoo.fr --- drivers/gpu/drm/drm_connector.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 2e7430283043..2db7fb510b6c 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -341,11 +341,11 @@ void drm_connector_cleanup(struct drm_connector *connector) list_for_each_entry_safe(mode, t, &connector->modes, head) drm_mode_remove(connector, mode); - ida_remove(&drm_connector_enum_list[connector->connector_type].ida, - connector->connector_type_id); + ida_simple_remove(&drm_connector_enum_list[connector->connector_type].ida, + connector->connector_type_id); - ida_remove(&dev->mode_config.connector_ida, - connector->index); + ida_simple_remove(&dev->mode_config.connector_ida, + connector->index); kfree(connector->display_info.bus_formats); drm_mode_object_unregister(dev, &connector->base); -- cgit v1.2.3