All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ajay kumar <ajaynumb@gmail.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: "dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"linux-samsung-soc@vger.kernel.org"
	<linux-samsung-soc@vger.kernel.org>,
	Ajay Kumar <ajaykumar.rs@samsung.com>,
	InKi Dae <inki.dae@samsung.com>,
	Kukjin Kim <kgene.kim@samsung.com>,
	Sean Paul <seanpaul@google.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Pannaga Bhushan Reddy Patel <bhushan.r@samsung.com>,
	Prashanth G <prashanth.g@samsung.com>
Subject: Re: [PATCH V8 03/14] drm/bridge: make bridge registration independent of drm flow
Date: Tue, 2 Dec 2014 11:31:35 +0530	[thread overview]
Message-ID: <CAEC9eQMhTv1hakk_y0a5AWhyvzPZgmicmRserfNubX99kzL19g@mail.gmail.com> (raw)
In-Reply-To: <1416045309-13359-4-git-send-email-ajaykumar.rs@samsung.com>

On Sat, Nov 15, 2014 at 3:24 PM, Ajay Kumar <ajaykumar.rs@samsung.com> wrote:
> Currently, third party bridge drivers(ptn3460) are dependent
> on the corresponding encoder driver init, since bridge driver
> needs a drm_device pointer to finish drm initializations.
> The encoder driver passes the drm_device pointer to the
> bridge driver. Because of this dependency, third party drivers
> like ptn3460 doesn't adhere to the driver model.
>
> In this patch, we reframe the bridge registration framework
> so that bridge initialization is split into 2 steps, and
> bridge registration happens independent of drm flow:
> --Step 1: gather all the bridge settings independent of drm and
>           add the bridge onto a global list of bridges.
> --Step 2: when the encoder driver is probed, call drm_bridge_attach
>           for the corresponding bridge so that the bridge receives
>           drm_device pointer and continues with connector and other
>           drm initializations.
>
> The old set of bridge helpers are removed, and a set of new helpers
> are added to accomplish the 2 step initialization.
>
> The bridge devices register themselves onto global list of bridges
> when they get probed by calling "drm_bridge_add".
>
> The parent encoder driver waits till the bridge is available
> in the lookup table(by calling "of_drm_find_bridge") and then
> continues with its initialization.
>
> The encoder driver should also call "drm_bridge_attach" to pass
> on the drm_device to the bridge object.
>
> drm_bridge_attach inturn calls "bridge->funcs->attach" so that
> bridge can continue with drm related initializations.
>
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>  drivers/gpu/drm/Makefile               |    2 +-
>  drivers/gpu/drm/bridge/ptn3460.c       |   27 +++++-----
>  drivers/gpu/drm/drm_bridge.c           |   91 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_crtc.c             |   65 -----------------------
>  drivers/gpu/drm/msm/hdmi/hdmi.c        |    7 +--
>  drivers/gpu/drm/msm/hdmi/hdmi.h        |    1 +
>  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |    7 ++-
>  drivers/gpu/drm/sti/sti_hda.c          |   10 +---
>  drivers/gpu/drm/sti/sti_hdmi.c         |   10 +---
>  include/drm/bridge/ptn3460.h           |    8 +++
>  include/drm/drm_crtc.h                 |   26 ++++-----
>  11 files changed, 136 insertions(+), 118 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_bridge.c
>
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 9292a76..00f97a5 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -14,7 +14,7 @@ drm-y       :=        drm_auth.o drm_bufs.o drm_cache.o \
>                 drm_info.o drm_debugfs.o drm_encoder_slave.o \
>                 drm_trace_points.o drm_global.o drm_prime.o \
>                 drm_rect.o drm_vma_manager.o drm_flip_work.o \
> -               drm_modeset_lock.o
> +               drm_modeset_lock.o drm_bridge.o
>
>  drm-$(CONFIG_COMPAT) += drm_ioc32.o
>  drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
> diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
> index a2ddc8d..4a818c1 100644
> --- a/drivers/gpu/drm/bridge/ptn3460.c
> +++ b/drivers/gpu/drm/bridge/ptn3460.c
> @@ -176,24 +176,11 @@ static void ptn3460_post_disable(struct drm_bridge *bridge)
>  {
>  }
>
> -static void ptn3460_bridge_destroy(struct drm_bridge *bridge)
> -{
> -       struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
> -
> -       drm_bridge_cleanup(bridge);
> -       if (gpio_is_valid(ptn_bridge->gpio_pd_n))
> -               gpio_free(ptn_bridge->gpio_pd_n);
> -       if (gpio_is_valid(ptn_bridge->gpio_rst_n))
> -               gpio_free(ptn_bridge->gpio_rst_n);
> -       /* Nothing else to free, we've got devm allocated memory */
> -}
> -
>  static struct drm_bridge_funcs ptn3460_bridge_funcs = {
>         .pre_enable = ptn3460_pre_enable,
>         .enable = ptn3460_enable,
>         .disable = ptn3460_disable,
>         .post_disable = ptn3460_post_disable,
> -       .destroy = ptn3460_bridge_destroy,
>  };
>
>  static int ptn3460_get_modes(struct drm_connector *connector)
> @@ -314,7 +301,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
>         }
>
>         ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
> -       ret = drm_bridge_init(dev, &ptn_bridge->bridge);
> +       ret = drm_bridge_attach(dev, &ptn_bridge->bridge);
>         if (ret) {
>                 DRM_ERROR("Failed to initialize bridge with drm\n");
>                 goto err;
> @@ -343,3 +330,15 @@ err:
>         return ret;
>  }
>  EXPORT_SYMBOL(ptn3460_init);
> +
> +void ptn3460_destroy(struct drm_bridge *bridge)
> +{
> +       struct ptn3460_bridge *ptn_bridge = bridge->driver_private;
> +
> +       if (gpio_is_valid(ptn_bridge->gpio_pd_n))
> +               gpio_free(ptn_bridge->gpio_pd_n);
> +       if (gpio_is_valid(ptn_bridge->gpio_rst_n))
> +               gpio_free(ptn_bridge->gpio_rst_n);
> +       /* Nothing else to free, we've got devm allocated memory */
> +}
> +EXPORT_SYMBOL(ptn3460_destroy);
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> new file mode 100644
> index 0000000..d1187e5
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -0,0 +1,91 @@
> +/*
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/module.h>
> +
> +#include <drm/drm_crtc.h>
> +
> +#include "drm/drmP.h"
> +
> +static DEFINE_MUTEX(bridge_lock);
> +static LIST_HEAD(bridge_list);
> +
> +int drm_bridge_add(struct drm_bridge *bridge)
> +{
> +       mutex_lock(&bridge_lock);
> +       list_add_tail(&bridge->list, &bridge_list);
> +       mutex_unlock(&bridge_lock);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_bridge_add);
> +
> +void drm_bridge_remove(struct drm_bridge *bridge)
> +{
> +       mutex_lock(&bridge_lock);
> +       list_del_init(&bridge->list);
> +       mutex_unlock(&bridge_lock);
> +}
> +EXPORT_SYMBOL(drm_bridge_remove);
> +
> +extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
> +{
> +       if (!dev || !bridge)
> +               return -EINVAL;
> +
> +       if (bridge->dev)
> +               return -EBUSY;
> +
> +       bridge->dev = dev;
> +
> +       if (bridge->funcs->attach)
> +               return bridge->funcs->attach(bridge);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_bridge_attach);
> +
> +#ifdef CONFIG_OF
> +struct drm_bridge *of_drm_find_bridge(struct device_node *np)
> +{
> +       struct drm_bridge *bridge;
> +
> +       mutex_lock(&bridge_lock);
> +
> +       list_for_each_entry(bridge, &bridge_list, list) {
> +               if (bridge->of_node == np) {
> +                       mutex_unlock(&bridge_lock);
> +                       return bridge;
> +               }
> +       }
> +
> +       mutex_unlock(&bridge_lock);
> +       return NULL;
> +}
> +EXPORT_SYMBOL(of_drm_find_bridge);
> +#endif
> +
> +MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
> +MODULE_DESCRIPTION("DRM bridge infrastructure");
> +MODULE_LICENSE("GPL and additional rights");
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 408c053..39d6100 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1008,56 +1008,6 @@ void drm_connector_unplug_all(struct drm_device *dev)
>  EXPORT_SYMBOL(drm_connector_unplug_all);
>
>  /**
> - * drm_bridge_init - initialize a drm transcoder/bridge
> - * @dev: drm device
> - * @bridge: transcoder/bridge to set up
> - *
> - * Initialises a preallocated bridge. Bridges should be
> - * subclassed as part of driver connector objects.
> - *
> - * Returns:
> - * Zero on success, error code on failure.
> - */
> -int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge)
> -{
> -       int ret;
> -
> -       drm_modeset_lock_all(dev);
> -
> -       ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
> -       if (ret)
> -               goto out;
> -
> -       bridge->dev = dev;
> -
> -       list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
> -       dev->mode_config.num_bridge++;
> -
> - out:
> -       drm_modeset_unlock_all(dev);
> -       return ret;
> -}
> -EXPORT_SYMBOL(drm_bridge_init);
> -
> -/**
> - * drm_bridge_cleanup - cleans up an initialised bridge
> - * @bridge: bridge to cleanup
> - *
> - * Cleans up the bridge but doesn't free the object.
> - */
> -void drm_bridge_cleanup(struct drm_bridge *bridge)
> -{
> -       struct drm_device *dev = bridge->dev;
> -
> -       drm_modeset_lock_all(dev);
> -       drm_mode_object_put(dev, &bridge->base);
> -       list_del(&bridge->head);
> -       dev->mode_config.num_bridge--;
> -       drm_modeset_unlock_all(dev);
> -}
> -EXPORT_SYMBOL(drm_bridge_cleanup);
> -
> -/**
>   * drm_encoder_init - Init a preallocated encoder
>   * @dev: drm device
>   * @encoder: the encoder to init
> @@ -1539,7 +1489,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
>         total_objects += dev->mode_config.num_crtc;
>         total_objects += dev->mode_config.num_connector;
>         total_objects += dev->mode_config.num_encoder;
> -       total_objects += dev->mode_config.num_bridge;
>
>         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
>         if (!group->id_list)
> @@ -1548,7 +1497,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
>         group->num_crtcs = 0;
>         group->num_connectors = 0;
>         group->num_encoders = 0;
> -       group->num_bridges = 0;
>         return 0;
>  }
>
> @@ -1568,7 +1516,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
>         struct drm_crtc *crtc;
>         struct drm_encoder *encoder;
>         struct drm_connector *connector;
> -       struct drm_bridge *bridge;
>         int ret;
>
>         if ((ret = drm_mode_group_init(dev, group)))
> @@ -1585,11 +1532,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
>                 group->id_list[group->num_crtcs + group->num_encoders +
>                                group->num_connectors++] = connector->base.id;
>
> -       list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
> -               group->id_list[group->num_crtcs + group->num_encoders +
> -                              group->num_connectors + group->num_bridges++] =
> -                                       bridge->base.id;
> -
>         return 0;
>  }
>  EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
> @@ -5088,7 +5030,6 @@ void drm_mode_config_init(struct drm_device *dev)
>         INIT_LIST_HEAD(&dev->mode_config.fb_list);
>         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
>         INIT_LIST_HEAD(&dev->mode_config.connector_list);
> -       INIT_LIST_HEAD(&dev->mode_config.bridge_list);
>         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
>         INIT_LIST_HEAD(&dev->mode_config.property_list);
>         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
> @@ -5128,7 +5069,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>         struct drm_connector *connector, *ot;
>         struct drm_crtc *crtc, *ct;
>         struct drm_encoder *encoder, *enct;
> -       struct drm_bridge *bridge, *brt;
>         struct drm_framebuffer *fb, *fbt;
>         struct drm_property *property, *pt;
>         struct drm_property_blob *blob, *bt;
> @@ -5139,11 +5079,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>                 encoder->funcs->destroy(encoder);
>         }
>
> -       list_for_each_entry_safe(bridge, brt,
> -                                &dev->mode_config.bridge_list, head) {
> -               bridge->funcs->destroy(bridge);
> -       }
> -
>         list_for_each_entry_safe(connector, ot,
>                                  &dev->mode_config.connector_list, head) {
>                 connector->funcs->destroy(connector);
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
> index 9d00dcb..e4f249b 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
> @@ -65,6 +65,9 @@ void hdmi_destroy(struct kref *kref)
>         if (hdmi->i2c)
>                 hdmi_i2c_destroy(hdmi->i2c);
>
> +       if (hdmi->bridge)
> +               hdmi_bridge_destroy(hdmi->bridge);
> +
>         platform_set_drvdata(hdmi->pdev, NULL);
>  }
>
> @@ -234,9 +237,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
>
>  fail:
>         if (hdmi) {
> -               /* bridge/connector are normally destroyed by drm: */
> -               if (hdmi->bridge)
> -                       hdmi->bridge->funcs->destroy(hdmi->bridge);
> +               /* bridge is normally destroyed by drm: */
>                 if (hdmi->connector)
>                         hdmi->connector->funcs->destroy(hdmi->connector);
>                 hdmi_destroy(&hdmi->refcount);
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
> index b981995..d2cf7f4 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.h
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
> @@ -163,6 +163,7 @@ void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
>   */
>
>  struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi);
> +void hdmi_bridge_destroy(struct drm_bridge *bridge);
>
>  /*
>   * hdmi connector:
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> index 0309539..26657a0 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> @@ -23,11 +23,11 @@ struct hdmi_bridge {
>  };
>  #define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
>
> -static void hdmi_bridge_destroy(struct drm_bridge *bridge)
> +void hdmi_bridge_destroy(struct drm_bridge *bridge)
>  {
>         struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
> +
>         hdmi_unreference(hdmi_bridge->hdmi);
> -       drm_bridge_cleanup(bridge);
>         kfree(hdmi_bridge);
>  }
>
> @@ -201,7 +201,6 @@ static const struct drm_bridge_funcs hdmi_bridge_funcs = {
>                 .disable = hdmi_bridge_disable,
>                 .post_disable = hdmi_bridge_post_disable,
>                 .mode_set = hdmi_bridge_mode_set,
> -               .destroy = hdmi_bridge_destroy,
>  };
>
>
> @@ -223,7 +222,7 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi)
>         bridge = &hdmi_bridge->base;
>         bridge->funcs = &hdmi_bridge_funcs;
>
> -       drm_bridge_init(hdmi->dev, bridge);
> +       drm_bridge_attach(hdmi->dev, bridge);
>
>         return bridge;
>
> diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
> index 6cf145d..a9bbb08 100644
> --- a/drivers/gpu/drm/sti/sti_hda.c
> +++ b/drivers/gpu/drm/sti/sti_hda.c
> @@ -508,19 +508,12 @@ static void sti_hda_bridge_nope(struct drm_bridge *bridge)
>         /* do nothing */
>  }
>
> -static void sti_hda_brigde_destroy(struct drm_bridge *bridge)
> -{
> -       drm_bridge_cleanup(bridge);
> -       kfree(bridge);
> -}
> -
>  static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
>         .pre_enable = sti_hda_pre_enable,
>         .enable = sti_hda_bridge_nope,
>         .disable = sti_hda_disable,
>         .post_disable = sti_hda_bridge_nope,
>         .mode_set = sti_hda_set_mode,
> -       .destroy = sti_hda_brigde_destroy,
>  };
>
>  static int sti_hda_connector_get_modes(struct drm_connector *connector)
> @@ -665,7 +658,7 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
>
>         bridge->driver_private = hda;
>         bridge->funcs = &sti_hda_bridge_funcs;
> -       drm_bridge_init(drm_dev, bridge);
> +       drm_bridge_attach(drm_dev, bridge);
>
>         encoder->bridge = bridge;
>         connector->encoder = encoder;
> @@ -694,7 +687,6 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
>  err_sysfs:
>         drm_connector_unregister(drm_connector);
>  err_connector:
> -       drm_bridge_cleanup(bridge);
>         drm_connector_cleanup(drm_connector);
>         return -EINVAL;
>  }
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 285f723..bf4cdb8 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -463,19 +463,12 @@ static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
>         /* do nothing */
>  }
>
> -static void sti_hdmi_brigde_destroy(struct drm_bridge *bridge)
> -{
> -       drm_bridge_cleanup(bridge);
> -       kfree(bridge);
> -}
> -
>  static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
>         .pre_enable = sti_hdmi_pre_enable,
>         .enable = sti_hdmi_bridge_nope,
>         .disable = sti_hdmi_disable,
>         .post_disable = sti_hdmi_bridge_nope,
>         .mode_set = sti_hdmi_set_mode,
> -       .destroy = sti_hdmi_brigde_destroy,
>  };
>
>  static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
> @@ -629,7 +622,7 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
>
>         bridge->driver_private = hdmi;
>         bridge->funcs = &sti_hdmi_bridge_funcs;
> -       drm_bridge_init(drm_dev, bridge);
> +       drm_bridge_attach(drm_dev, bridge);
>
>         encoder->bridge = bridge;
>         connector->encoder = encoder;
> @@ -661,7 +654,6 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
>  err_sysfs:
>         drm_connector_unregister(drm_connector);
>  err_connector:
> -       drm_bridge_cleanup(bridge);
>         drm_connector_cleanup(drm_connector);
>         return -EINVAL;
>  }
> diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h
> index ff62344..b11f8e1 100644
> --- a/include/drm/bridge/ptn3460.h
> +++ b/include/drm/bridge/ptn3460.h
> @@ -15,6 +15,7 @@
>  #define _DRM_BRIDGE_PTN3460_H_
>
>  struct drm_device;
> +struct drm_bridge;
>  struct drm_encoder;
>  struct i2c_client;
>  struct device_node;
> @@ -23,6 +24,9 @@ struct device_node;
>
>  int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
>                 struct i2c_client *client, struct device_node *node);
> +
> +void ptn3460_destroy(struct drm_bridge *bridge);
> +
>  #else
>
>  static inline int ptn3460_init(struct drm_device *dev,
> @@ -32,6 +36,10 @@ static inline int ptn3460_init(struct drm_device *dev,
>         return 0;
>  }
>
> +static inline void ptn3460_destroy(struct drm_bridge *bridge)
> +{
> +}
> +
>  #endif
>
>  #endif
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 5a3bce17..da2beaf 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -633,15 +633,16 @@ struct drm_plane {
>
>  /**
>   * drm_bridge_funcs - drm_bridge control functions
> + * @attach: Called during drm_bridge_attach
>   * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge
>   * @disable: Called right before encoder prepare, disables the bridge
>   * @post_disable: Called right after encoder prepare, for lockstepped disable
>   * @mode_set: Set this mode to the bridge
>   * @pre_enable: Called right before encoder commit, for lockstepped commit
>   * @enable: Called right after encoder commit, enables the bridge
> - * @destroy: make object go away
>   */
>  struct drm_bridge_funcs {
> +       int (*attach)(struct drm_bridge *bridge);
>         bool (*mode_fixup)(struct drm_bridge *bridge,
>                            const struct drm_display_mode *mode,
>                            struct drm_display_mode *adjusted_mode);
> @@ -652,22 +653,24 @@ struct drm_bridge_funcs {
>                          struct drm_display_mode *adjusted_mode);
>         void (*pre_enable)(struct drm_bridge *bridge);
>         void (*enable)(struct drm_bridge *bridge);
> -       void (*destroy)(struct drm_bridge *bridge);
>  };
>
>  /**
>   * drm_bridge - central DRM bridge control structure
>   * @dev: DRM device this bridge belongs to
> - * @head: list management
> + * @of_node: device node pointer to the bridge
> + * @list: to keep track of all added bridges
>   * @base: base mode object
>   * @funcs: control functions
>   * @driver_private: pointer to the bridge driver's internal context
>   */
>  struct drm_bridge {
>         struct drm_device *dev;
> -       struct list_head head;
> -
> -       struct drm_mode_object base;
> +       struct drm_encoder *encoder;
> +#ifdef CONFIG_OF
> +       struct device_node *of_node;
> +#endif
> +       struct list_head list;
>
>         const struct drm_bridge_funcs *funcs;
>         void *driver_private;
> @@ -733,7 +736,6 @@ struct drm_mode_group {
>         uint32_t num_crtcs;
>         uint32_t num_encoders;
>         uint32_t num_connectors;
> -       uint32_t num_bridges;
>
>         /* list of object IDs for this group */
>         uint32_t *id_list;
> @@ -748,8 +750,6 @@ struct drm_mode_group {
>   * @fb_list: list of framebuffers available
>   * @num_connector: number of connectors on this device
>   * @connector_list: list of connector objects
> - * @num_bridge: number of bridges on this device
> - * @bridge_list: list of bridge objects
>   * @num_encoder: number of encoders on this device
>   * @encoder_list: list of encoder objects
>   * @num_crtc: number of CRTCs on this device
> @@ -789,8 +789,6 @@ struct drm_mode_config {
>
>         int num_connector;
>         struct list_head connector_list;
> -       int num_bridge;
> -       struct list_head bridge_list;
>         int num_encoder;
>         struct list_head encoder_list;
>
> @@ -912,8 +910,10 @@ extern unsigned int drm_connector_index(struct drm_connector *connector);
>  /* helper to unplug all connectors from sysfs for device */
>  extern void drm_connector_unplug_all(struct drm_device *dev);
>
> -extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge);
> -extern void drm_bridge_cleanup(struct drm_bridge *bridge);
> +extern int drm_bridge_add(struct drm_bridge *bridge);
> +extern void drm_bridge_remove(struct drm_bridge *bridge);
> +extern struct drm_bridge *of_drm_find_bridge(struct device_node *np);
> +extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
>
>  extern int drm_encoder_init(struct drm_device *dev,
>                             struct drm_encoder *encoder,
> --
> 1.7.9.5
>

WARNING: multiple messages have this Message-ID (diff)
From: ajaynumb@gmail.com (Ajay kumar)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V8 03/14] drm/bridge: make bridge registration independent of drm flow
Date: Tue, 2 Dec 2014 11:31:35 +0530	[thread overview]
Message-ID: <CAEC9eQMhTv1hakk_y0a5AWhyvzPZgmicmRserfNubX99kzL19g@mail.gmail.com> (raw)
In-Reply-To: <1416045309-13359-4-git-send-email-ajaykumar.rs@samsung.com>

On Sat, Nov 15, 2014 at 3:24 PM, Ajay Kumar <ajaykumar.rs@samsung.com> wrote:
> Currently, third party bridge drivers(ptn3460) are dependent
> on the corresponding encoder driver init, since bridge driver
> needs a drm_device pointer to finish drm initializations.
> The encoder driver passes the drm_device pointer to the
> bridge driver. Because of this dependency, third party drivers
> like ptn3460 doesn't adhere to the driver model.
>
> In this patch, we reframe the bridge registration framework
> so that bridge initialization is split into 2 steps, and
> bridge registration happens independent of drm flow:
> --Step 1: gather all the bridge settings independent of drm and
>           add the bridge onto a global list of bridges.
> --Step 2: when the encoder driver is probed, call drm_bridge_attach
>           for the corresponding bridge so that the bridge receives
>           drm_device pointer and continues with connector and other
>           drm initializations.
>
> The old set of bridge helpers are removed, and a set of new helpers
> are added to accomplish the 2 step initialization.
>
> The bridge devices register themselves onto global list of bridges
> when they get probed by calling "drm_bridge_add".
>
> The parent encoder driver waits till the bridge is available
> in the lookup table(by calling "of_drm_find_bridge") and then
> continues with its initialization.
>
> The encoder driver should also call "drm_bridge_attach" to pass
> on the drm_device to the bridge object.
>
> drm_bridge_attach inturn calls "bridge->funcs->attach" so that
> bridge can continue with drm related initializations.
>
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>  drivers/gpu/drm/Makefile               |    2 +-
>  drivers/gpu/drm/bridge/ptn3460.c       |   27 +++++-----
>  drivers/gpu/drm/drm_bridge.c           |   91 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_crtc.c             |   65 -----------------------
>  drivers/gpu/drm/msm/hdmi/hdmi.c        |    7 +--
>  drivers/gpu/drm/msm/hdmi/hdmi.h        |    1 +
>  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |    7 ++-
>  drivers/gpu/drm/sti/sti_hda.c          |   10 +---
>  drivers/gpu/drm/sti/sti_hdmi.c         |   10 +---
>  include/drm/bridge/ptn3460.h           |    8 +++
>  include/drm/drm_crtc.h                 |   26 ++++-----
>  11 files changed, 136 insertions(+), 118 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_bridge.c
>
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 9292a76..00f97a5 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -14,7 +14,7 @@ drm-y       :=        drm_auth.o drm_bufs.o drm_cache.o \
>                 drm_info.o drm_debugfs.o drm_encoder_slave.o \
>                 drm_trace_points.o drm_global.o drm_prime.o \
>                 drm_rect.o drm_vma_manager.o drm_flip_work.o \
> -               drm_modeset_lock.o
> +               drm_modeset_lock.o drm_bridge.o
>
>  drm-$(CONFIG_COMPAT) += drm_ioc32.o
>  drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
> diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
> index a2ddc8d..4a818c1 100644
> --- a/drivers/gpu/drm/bridge/ptn3460.c
> +++ b/drivers/gpu/drm/bridge/ptn3460.c
> @@ -176,24 +176,11 @@ static void ptn3460_post_disable(struct drm_bridge *bridge)
>  {
>  }
>
> -static void ptn3460_bridge_destroy(struct drm_bridge *bridge)
> -{
> -       struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
> -
> -       drm_bridge_cleanup(bridge);
> -       if (gpio_is_valid(ptn_bridge->gpio_pd_n))
> -               gpio_free(ptn_bridge->gpio_pd_n);
> -       if (gpio_is_valid(ptn_bridge->gpio_rst_n))
> -               gpio_free(ptn_bridge->gpio_rst_n);
> -       /* Nothing else to free, we've got devm allocated memory */
> -}
> -
>  static struct drm_bridge_funcs ptn3460_bridge_funcs = {
>         .pre_enable = ptn3460_pre_enable,
>         .enable = ptn3460_enable,
>         .disable = ptn3460_disable,
>         .post_disable = ptn3460_post_disable,
> -       .destroy = ptn3460_bridge_destroy,
>  };
>
>  static int ptn3460_get_modes(struct drm_connector *connector)
> @@ -314,7 +301,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
>         }
>
>         ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
> -       ret = drm_bridge_init(dev, &ptn_bridge->bridge);
> +       ret = drm_bridge_attach(dev, &ptn_bridge->bridge);
>         if (ret) {
>                 DRM_ERROR("Failed to initialize bridge with drm\n");
>                 goto err;
> @@ -343,3 +330,15 @@ err:
>         return ret;
>  }
>  EXPORT_SYMBOL(ptn3460_init);
> +
> +void ptn3460_destroy(struct drm_bridge *bridge)
> +{
> +       struct ptn3460_bridge *ptn_bridge = bridge->driver_private;
> +
> +       if (gpio_is_valid(ptn_bridge->gpio_pd_n))
> +               gpio_free(ptn_bridge->gpio_pd_n);
> +       if (gpio_is_valid(ptn_bridge->gpio_rst_n))
> +               gpio_free(ptn_bridge->gpio_rst_n);
> +       /* Nothing else to free, we've got devm allocated memory */
> +}
> +EXPORT_SYMBOL(ptn3460_destroy);
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> new file mode 100644
> index 0000000..d1187e5
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -0,0 +1,91 @@
> +/*
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/module.h>
> +
> +#include <drm/drm_crtc.h>
> +
> +#include "drm/drmP.h"
> +
> +static DEFINE_MUTEX(bridge_lock);
> +static LIST_HEAD(bridge_list);
> +
> +int drm_bridge_add(struct drm_bridge *bridge)
> +{
> +       mutex_lock(&bridge_lock);
> +       list_add_tail(&bridge->list, &bridge_list);
> +       mutex_unlock(&bridge_lock);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_bridge_add);
> +
> +void drm_bridge_remove(struct drm_bridge *bridge)
> +{
> +       mutex_lock(&bridge_lock);
> +       list_del_init(&bridge->list);
> +       mutex_unlock(&bridge_lock);
> +}
> +EXPORT_SYMBOL(drm_bridge_remove);
> +
> +extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
> +{
> +       if (!dev || !bridge)
> +               return -EINVAL;
> +
> +       if (bridge->dev)
> +               return -EBUSY;
> +
> +       bridge->dev = dev;
> +
> +       if (bridge->funcs->attach)
> +               return bridge->funcs->attach(bridge);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_bridge_attach);
> +
> +#ifdef CONFIG_OF
> +struct drm_bridge *of_drm_find_bridge(struct device_node *np)
> +{
> +       struct drm_bridge *bridge;
> +
> +       mutex_lock(&bridge_lock);
> +
> +       list_for_each_entry(bridge, &bridge_list, list) {
> +               if (bridge->of_node == np) {
> +                       mutex_unlock(&bridge_lock);
> +                       return bridge;
> +               }
> +       }
> +
> +       mutex_unlock(&bridge_lock);
> +       return NULL;
> +}
> +EXPORT_SYMBOL(of_drm_find_bridge);
> +#endif
> +
> +MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
> +MODULE_DESCRIPTION("DRM bridge infrastructure");
> +MODULE_LICENSE("GPL and additional rights");
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 408c053..39d6100 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1008,56 +1008,6 @@ void drm_connector_unplug_all(struct drm_device *dev)
>  EXPORT_SYMBOL(drm_connector_unplug_all);
>
>  /**
> - * drm_bridge_init - initialize a drm transcoder/bridge
> - * @dev: drm device
> - * @bridge: transcoder/bridge to set up
> - *
> - * Initialises a preallocated bridge. Bridges should be
> - * subclassed as part of driver connector objects.
> - *
> - * Returns:
> - * Zero on success, error code on failure.
> - */
> -int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge)
> -{
> -       int ret;
> -
> -       drm_modeset_lock_all(dev);
> -
> -       ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
> -       if (ret)
> -               goto out;
> -
> -       bridge->dev = dev;
> -
> -       list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
> -       dev->mode_config.num_bridge++;
> -
> - out:
> -       drm_modeset_unlock_all(dev);
> -       return ret;
> -}
> -EXPORT_SYMBOL(drm_bridge_init);
> -
> -/**
> - * drm_bridge_cleanup - cleans up an initialised bridge
> - * @bridge: bridge to cleanup
> - *
> - * Cleans up the bridge but doesn't free the object.
> - */
> -void drm_bridge_cleanup(struct drm_bridge *bridge)
> -{
> -       struct drm_device *dev = bridge->dev;
> -
> -       drm_modeset_lock_all(dev);
> -       drm_mode_object_put(dev, &bridge->base);
> -       list_del(&bridge->head);
> -       dev->mode_config.num_bridge--;
> -       drm_modeset_unlock_all(dev);
> -}
> -EXPORT_SYMBOL(drm_bridge_cleanup);
> -
> -/**
>   * drm_encoder_init - Init a preallocated encoder
>   * @dev: drm device
>   * @encoder: the encoder to init
> @@ -1539,7 +1489,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
>         total_objects += dev->mode_config.num_crtc;
>         total_objects += dev->mode_config.num_connector;
>         total_objects += dev->mode_config.num_encoder;
> -       total_objects += dev->mode_config.num_bridge;
>
>         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
>         if (!group->id_list)
> @@ -1548,7 +1497,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
>         group->num_crtcs = 0;
>         group->num_connectors = 0;
>         group->num_encoders = 0;
> -       group->num_bridges = 0;
>         return 0;
>  }
>
> @@ -1568,7 +1516,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
>         struct drm_crtc *crtc;
>         struct drm_encoder *encoder;
>         struct drm_connector *connector;
> -       struct drm_bridge *bridge;
>         int ret;
>
>         if ((ret = drm_mode_group_init(dev, group)))
> @@ -1585,11 +1532,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
>                 group->id_list[group->num_crtcs + group->num_encoders +
>                                group->num_connectors++] = connector->base.id;
>
> -       list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
> -               group->id_list[group->num_crtcs + group->num_encoders +
> -                              group->num_connectors + group->num_bridges++] =
> -                                       bridge->base.id;
> -
>         return 0;
>  }
>  EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
> @@ -5088,7 +5030,6 @@ void drm_mode_config_init(struct drm_device *dev)
>         INIT_LIST_HEAD(&dev->mode_config.fb_list);
>         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
>         INIT_LIST_HEAD(&dev->mode_config.connector_list);
> -       INIT_LIST_HEAD(&dev->mode_config.bridge_list);
>         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
>         INIT_LIST_HEAD(&dev->mode_config.property_list);
>         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
> @@ -5128,7 +5069,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>         struct drm_connector *connector, *ot;
>         struct drm_crtc *crtc, *ct;
>         struct drm_encoder *encoder, *enct;
> -       struct drm_bridge *bridge, *brt;
>         struct drm_framebuffer *fb, *fbt;
>         struct drm_property *property, *pt;
>         struct drm_property_blob *blob, *bt;
> @@ -5139,11 +5079,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>                 encoder->funcs->destroy(encoder);
>         }
>
> -       list_for_each_entry_safe(bridge, brt,
> -                                &dev->mode_config.bridge_list, head) {
> -               bridge->funcs->destroy(bridge);
> -       }
> -
>         list_for_each_entry_safe(connector, ot,
>                                  &dev->mode_config.connector_list, head) {
>                 connector->funcs->destroy(connector);
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
> index 9d00dcb..e4f249b 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
> @@ -65,6 +65,9 @@ void hdmi_destroy(struct kref *kref)
>         if (hdmi->i2c)
>                 hdmi_i2c_destroy(hdmi->i2c);
>
> +       if (hdmi->bridge)
> +               hdmi_bridge_destroy(hdmi->bridge);
> +
>         platform_set_drvdata(hdmi->pdev, NULL);
>  }
>
> @@ -234,9 +237,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
>
>  fail:
>         if (hdmi) {
> -               /* bridge/connector are normally destroyed by drm: */
> -               if (hdmi->bridge)
> -                       hdmi->bridge->funcs->destroy(hdmi->bridge);
> +               /* bridge is normally destroyed by drm: */
>                 if (hdmi->connector)
>                         hdmi->connector->funcs->destroy(hdmi->connector);
>                 hdmi_destroy(&hdmi->refcount);
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
> index b981995..d2cf7f4 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.h
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
> @@ -163,6 +163,7 @@ void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
>   */
>
>  struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi);
> +void hdmi_bridge_destroy(struct drm_bridge *bridge);
>
>  /*
>   * hdmi connector:
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> index 0309539..26657a0 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> @@ -23,11 +23,11 @@ struct hdmi_bridge {
>  };
>  #define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
>
> -static void hdmi_bridge_destroy(struct drm_bridge *bridge)
> +void hdmi_bridge_destroy(struct drm_bridge *bridge)
>  {
>         struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
> +
>         hdmi_unreference(hdmi_bridge->hdmi);
> -       drm_bridge_cleanup(bridge);
>         kfree(hdmi_bridge);
>  }
>
> @@ -201,7 +201,6 @@ static const struct drm_bridge_funcs hdmi_bridge_funcs = {
>                 .disable = hdmi_bridge_disable,
>                 .post_disable = hdmi_bridge_post_disable,
>                 .mode_set = hdmi_bridge_mode_set,
> -               .destroy = hdmi_bridge_destroy,
>  };
>
>
> @@ -223,7 +222,7 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi)
>         bridge = &hdmi_bridge->base;
>         bridge->funcs = &hdmi_bridge_funcs;
>
> -       drm_bridge_init(hdmi->dev, bridge);
> +       drm_bridge_attach(hdmi->dev, bridge);
>
>         return bridge;
>
> diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
> index 6cf145d..a9bbb08 100644
> --- a/drivers/gpu/drm/sti/sti_hda.c
> +++ b/drivers/gpu/drm/sti/sti_hda.c
> @@ -508,19 +508,12 @@ static void sti_hda_bridge_nope(struct drm_bridge *bridge)
>         /* do nothing */
>  }
>
> -static void sti_hda_brigde_destroy(struct drm_bridge *bridge)
> -{
> -       drm_bridge_cleanup(bridge);
> -       kfree(bridge);
> -}
> -
>  static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
>         .pre_enable = sti_hda_pre_enable,
>         .enable = sti_hda_bridge_nope,
>         .disable = sti_hda_disable,
>         .post_disable = sti_hda_bridge_nope,
>         .mode_set = sti_hda_set_mode,
> -       .destroy = sti_hda_brigde_destroy,
>  };
>
>  static int sti_hda_connector_get_modes(struct drm_connector *connector)
> @@ -665,7 +658,7 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
>
>         bridge->driver_private = hda;
>         bridge->funcs = &sti_hda_bridge_funcs;
> -       drm_bridge_init(drm_dev, bridge);
> +       drm_bridge_attach(drm_dev, bridge);
>
>         encoder->bridge = bridge;
>         connector->encoder = encoder;
> @@ -694,7 +687,6 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
>  err_sysfs:
>         drm_connector_unregister(drm_connector);
>  err_connector:
> -       drm_bridge_cleanup(bridge);
>         drm_connector_cleanup(drm_connector);
>         return -EINVAL;
>  }
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 285f723..bf4cdb8 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -463,19 +463,12 @@ static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
>         /* do nothing */
>  }
>
> -static void sti_hdmi_brigde_destroy(struct drm_bridge *bridge)
> -{
> -       drm_bridge_cleanup(bridge);
> -       kfree(bridge);
> -}
> -
>  static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
>         .pre_enable = sti_hdmi_pre_enable,
>         .enable = sti_hdmi_bridge_nope,
>         .disable = sti_hdmi_disable,
>         .post_disable = sti_hdmi_bridge_nope,
>         .mode_set = sti_hdmi_set_mode,
> -       .destroy = sti_hdmi_brigde_destroy,
>  };
>
>  static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
> @@ -629,7 +622,7 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
>
>         bridge->driver_private = hdmi;
>         bridge->funcs = &sti_hdmi_bridge_funcs;
> -       drm_bridge_init(drm_dev, bridge);
> +       drm_bridge_attach(drm_dev, bridge);
>
>         encoder->bridge = bridge;
>         connector->encoder = encoder;
> @@ -661,7 +654,6 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
>  err_sysfs:
>         drm_connector_unregister(drm_connector);
>  err_connector:
> -       drm_bridge_cleanup(bridge);
>         drm_connector_cleanup(drm_connector);
>         return -EINVAL;
>  }
> diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h
> index ff62344..b11f8e1 100644
> --- a/include/drm/bridge/ptn3460.h
> +++ b/include/drm/bridge/ptn3460.h
> @@ -15,6 +15,7 @@
>  #define _DRM_BRIDGE_PTN3460_H_
>
>  struct drm_device;
> +struct drm_bridge;
>  struct drm_encoder;
>  struct i2c_client;
>  struct device_node;
> @@ -23,6 +24,9 @@ struct device_node;
>
>  int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
>                 struct i2c_client *client, struct device_node *node);
> +
> +void ptn3460_destroy(struct drm_bridge *bridge);
> +
>  #else
>
>  static inline int ptn3460_init(struct drm_device *dev,
> @@ -32,6 +36,10 @@ static inline int ptn3460_init(struct drm_device *dev,
>         return 0;
>  }
>
> +static inline void ptn3460_destroy(struct drm_bridge *bridge)
> +{
> +}
> +
>  #endif
>
>  #endif
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 5a3bce17..da2beaf 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -633,15 +633,16 @@ struct drm_plane {
>
>  /**
>   * drm_bridge_funcs - drm_bridge control functions
> + * @attach: Called during drm_bridge_attach
>   * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge
>   * @disable: Called right before encoder prepare, disables the bridge
>   * @post_disable: Called right after encoder prepare, for lockstepped disable
>   * @mode_set: Set this mode to the bridge
>   * @pre_enable: Called right before encoder commit, for lockstepped commit
>   * @enable: Called right after encoder commit, enables the bridge
> - * @destroy: make object go away
>   */
>  struct drm_bridge_funcs {
> +       int (*attach)(struct drm_bridge *bridge);
>         bool (*mode_fixup)(struct drm_bridge *bridge,
>                            const struct drm_display_mode *mode,
>                            struct drm_display_mode *adjusted_mode);
> @@ -652,22 +653,24 @@ struct drm_bridge_funcs {
>                          struct drm_display_mode *adjusted_mode);
>         void (*pre_enable)(struct drm_bridge *bridge);
>         void (*enable)(struct drm_bridge *bridge);
> -       void (*destroy)(struct drm_bridge *bridge);
>  };
>
>  /**
>   * drm_bridge - central DRM bridge control structure
>   * @dev: DRM device this bridge belongs to
> - * @head: list management
> + * @of_node: device node pointer to the bridge
> + * @list: to keep track of all added bridges
>   * @base: base mode object
>   * @funcs: control functions
>   * @driver_private: pointer to the bridge driver's internal context
>   */
>  struct drm_bridge {
>         struct drm_device *dev;
> -       struct list_head head;
> -
> -       struct drm_mode_object base;
> +       struct drm_encoder *encoder;
> +#ifdef CONFIG_OF
> +       struct device_node *of_node;
> +#endif
> +       struct list_head list;
>
>         const struct drm_bridge_funcs *funcs;
>         void *driver_private;
> @@ -733,7 +736,6 @@ struct drm_mode_group {
>         uint32_t num_crtcs;
>         uint32_t num_encoders;
>         uint32_t num_connectors;
> -       uint32_t num_bridges;
>
>         /* list of object IDs for this group */
>         uint32_t *id_list;
> @@ -748,8 +750,6 @@ struct drm_mode_group {
>   * @fb_list: list of framebuffers available
>   * @num_connector: number of connectors on this device
>   * @connector_list: list of connector objects
> - * @num_bridge: number of bridges on this device
> - * @bridge_list: list of bridge objects
>   * @num_encoder: number of encoders on this device
>   * @encoder_list: list of encoder objects
>   * @num_crtc: number of CRTCs on this device
> @@ -789,8 +789,6 @@ struct drm_mode_config {
>
>         int num_connector;
>         struct list_head connector_list;
> -       int num_bridge;
> -       struct list_head bridge_list;
>         int num_encoder;
>         struct list_head encoder_list;
>
> @@ -912,8 +910,10 @@ extern unsigned int drm_connector_index(struct drm_connector *connector);
>  /* helper to unplug all connectors from sysfs for device */
>  extern void drm_connector_unplug_all(struct drm_device *dev);
>
> -extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge);
> -extern void drm_bridge_cleanup(struct drm_bridge *bridge);
> +extern int drm_bridge_add(struct drm_bridge *bridge);
> +extern void drm_bridge_remove(struct drm_bridge *bridge);
> +extern struct drm_bridge *of_drm_find_bridge(struct device_node *np);
> +extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
>
>  extern int drm_encoder_init(struct drm_device *dev,
>                             struct drm_encoder *encoder,
> --
> 1.7.9.5
>

  reply	other threads:[~2014-12-02  6:01 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-15  9:54 [PATCH V8 00/14] drm/exynos: few patches to enhance bridge chip support Ajay Kumar
2014-11-15  9:54 ` Ajay Kumar
2014-11-15  9:54 ` [PATCH V8 01/14] drm/bridge: ptn3460: Few trivial cleanups Ajay Kumar
2014-11-15  9:54   ` Ajay Kumar
2014-11-15  9:54 ` [PATCH V8 02/14] drm/bridge: do not pass drm_bridge_funcs to drm_bridge_init Ajay Kumar
2014-11-15  9:54   ` Ajay Kumar
2014-11-15  9:54 ` [PATCH V8 03/14] drm/bridge: make bridge registration independent of drm flow Ajay Kumar
2014-11-15  9:54   ` Ajay Kumar
2014-12-02  6:01   ` Ajay kumar [this message]
2014-12-02  6:01     ` Ajay kumar
2014-12-08 10:24     ` Ajay kumar
2014-12-08 10:24       ` Ajay kumar
2014-11-15  9:54 ` [PATCH V8 04/14] drm/bridge: ptn3460: Convert to i2c driver model Ajay Kumar
2014-11-15  9:54   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 05/14] drm/exynos: dp: support drm_bridge Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 06/14] drm/bridge: ptn3460: support drm_panel Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 07/14] drm/bridge: ptn3460: probe connector at the end of bridge attach Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 08/14] drm/bridge: ptn3460: use gpiod interface Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 09/14] Documentation: drm: bridge: move to video/bridge Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 10/14] Documentation: devicetree: Add vendor prefix for parade Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 11/14] Documentation: bridge: Add documentation for ps8622 DT properties Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 12/14] drm/bridge: Add i2c based driver for ps8622/ps8625 bridge Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 13/14] ARM: dts: snow: represent the connection between bridge and panel using videoport and endpoints Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-15  9:55 ` [PATCH V8 14/14] ARM: dts: peach-pit: " Ajay Kumar
2014-11-15  9:55   ` Ajay Kumar
2014-11-18  6:20 ` [PATCH V8 00/14] drm/exynos: few patches to enhance bridge chip support Ajay kumar
2014-11-18  6:20   ` Ajay kumar
2014-11-19  9:35   ` Javier Martinez Canillas
2014-11-19  9:35     ` Javier Martinez Canillas
2014-11-19  9:38     ` Ajay kumar
2014-11-19  9:38       ` Ajay kumar
2014-11-19  9:51       ` Javier Martinez Canillas
2014-11-19  9:51         ` Javier Martinez Canillas
2014-11-19 10:55     ` Paolo Pisati
2014-11-19 10:55       ` Paolo Pisati
2014-11-19 11:20       ` Javier Martinez Canillas
2014-11-19 11:20         ` Javier Martinez Canillas
2014-11-19 16:22         ` Paolo Pisati
2014-11-19 16:22           ` Paolo Pisati
2014-11-19 16:28           ` Javier Martinez Canillas
2014-11-19 16:28             ` Javier Martinez Canillas
2014-11-19 16:44             ` Andreas Färber
2014-11-19 16:44               ` Andreas Färber
2014-11-19 19:19       ` Kevin Hilman
2014-11-19 19:19         ` Kevin Hilman
2014-12-12  9:51   ` Javier Martinez Canillas
2014-12-12  9:51     ` Javier Martinez Canillas
2014-12-15 14:30     ` Tomi Valkeinen
2014-12-15 14:30       ` Tomi Valkeinen
2014-12-15 23:37     ` Laurent Pinchart
2014-12-15 23:37       ` Laurent Pinchart
2014-12-17  9:31       ` Javier Martinez Canillas
2014-12-17  9:31         ` Javier Martinez Canillas
2014-12-17 11:29         ` Laurent Pinchart
2014-12-17 11:29           ` Laurent Pinchart
2015-01-02 13:10         ` Daniel Stone
2015-01-02 13:14           ` Ajay kumar
2015-01-02 13:14             ` Ajay kumar
2015-01-02 13:19             ` Daniel Stone
2015-01-03  6:47             ` Inki Dae
2015-01-03  6:47               ` Inki Dae
2015-01-05 13:50           ` Thierry Reding
2015-01-05 13:50             ` Thierry Reding
     [not found]             ` <20150105135015.GA12010-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
2015-01-19 10:27               ` Javier Martinez Canillas
2015-01-19 10:27                 ` Javier Martinez Canillas
2015-01-19 16:30                 ` Thierry Reding
2015-01-19 16:30                   ` Thierry Reding
2015-01-19 17:01                   ` Gustavo Padovan
2015-01-19 17:01                     ` Gustavo Padovan
2015-01-19 17:43                     ` Sjoerd Simons
2015-01-19 17:43                       ` Sjoerd Simons
     [not found]                   ` <20150119163043.GB7751-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
2015-01-19 17:05                     ` Javier Martinez Canillas
2015-01-19 17:05                       ` Javier Martinez Canillas
2015-01-20 10:56                       ` Ajay kumar
2015-01-20 10:56                         ` Ajay kumar
2015-01-20 23:37                       ` Laurent Pinchart
2015-01-20 23:37                         ` Laurent Pinchart

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAEC9eQMhTv1hakk_y0a5AWhyvzPZgmicmRserfNubX99kzL19g@mail.gmail.com \
    --to=ajaynumb@gmail.com \
    --cc=ajaykumar.rs@samsung.com \
    --cc=bhushan.r@samsung.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=daniel@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=inki.dae@samsung.com \
    --cc=kgene.kim@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=prashanth.g@samsung.com \
    --cc=seanpaul@google.com \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.