[PATCH] drm: omap: fix: Defer probe if an omapdss device requests for it at connect
Archit Taneja
archit at ti.com
Wed Sep 18 04:15:05 PDT 2013
On Wednesday 18 September 2013 04:38 PM, Archit Taneja wrote:
> Some omapdss panels are connected to outputs/encoders(HDMI/DSI/DPI) that require
> regulators. The output's connect op tries to get a regulator which may not exist
> yet because it might get registered later in the kernel boot.
>
> omapdrm currently ignores those panels which return a non zero value when
> connected. A better approach would be for omapdrm to request for probe
> deferral if a panel's connect op returns -EPROBE_DEFER.
>
> The connecting of panels is moved very early in the the drm device's probe
> before anything else is initialized. When we enter omap_modeset_init(), we have
> a set of panels that have been connected. We now proceed with registering only
> those panels which are already connected.
>
> Checking whether the panel has a driver or whether it has get_timing/read_edid
> ops in omap_modeset_init() are redundant with the new display model. These can
> be removed since a dssdev device will always have a driver associated with it,
> and all dssdev drivers have a get_timings op.
>
> This fixes boot with omapdrm on an omap4 panda ES board. The regulators used by
> HDMI aren't initialized because I2c isn't initialized, I2C isn't initialized
> as it's pins are not configured because pinctrl is yet to probe.
Copying dri-devel list.
>
> Signed-off-by: Archit Taneja <archit at ti.com>
> ---
> drivers/gpu/drm/omapdrm/omap_crtc.c | 5 ++++
> drivers/gpu/drm/omapdrm/omap_drv.c | 51 +++++++++++++++++++++----------------
> drivers/gpu/drm/omapdrm/omap_drv.h | 1 +
> 3 files changed, 35 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
> index 0fd2eb1..9c01311 100644
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -623,6 +623,11 @@ void omap_crtc_pre_init(void)
> dss_install_mgr_ops(&mgr_ops);
> }
>
> +void omap_crtc_pre_uninit(void)
> +{
> + dss_uninstall_mgr_ops();
> +}
> +
> /* initialize crtc */
> struct drm_crtc *omap_crtc_init(struct drm_device *dev,
> struct drm_plane *plane, enum omap_channel channel, int id)
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index 2603d90..cbe5d8e 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -87,6 +87,24 @@ static bool channel_used(struct drm_device *dev, enum omap_channel channel)
> return false;
> }
>
> +static int omap_connect_dssdevs(void)
> +{
> + int r;
> + struct omap_dss_device *dssdev = NULL;
> +
> + for_each_dss_dev(dssdev) {
> + r = dssdev->driver->connect(dssdev);
> + if (r == -EPROBE_DEFER) {
> + return r;
> + } else if (r) {
> + dev_warn(dssdev->dev, "could not connect display: %s\n",
> + dssdev->name);
> + }
> + }
> +
> + return 0;
> +}
> +
> static int omap_modeset_init(struct drm_device *dev)
> {
> struct omap_drm_private *priv = dev->dev_private;
> @@ -95,9 +113,6 @@ static int omap_modeset_init(struct drm_device *dev)
> int num_mgrs = dss_feat_get_num_mgrs();
> int num_crtcs;
> int i, id = 0;
> - int r;
> -
> - omap_crtc_pre_init();
>
> drm_mode_config_init(dev);
>
> @@ -119,26 +134,8 @@ static int omap_modeset_init(struct drm_device *dev)
> enum omap_channel channel;
> struct omap_overlay_manager *mgr;
>
> - if (!dssdev->driver) {
> - dev_warn(dev->dev, "%s has no driver.. skipping it\n",
> - dssdev->name);
> + if (!omapdss_device_is_connected(dssdev))
> continue;
> - }
> -
> - if (!(dssdev->driver->get_timings ||
> - dssdev->driver->read_edid)) {
> - dev_warn(dev->dev, "%s driver does not support "
> - "get_timings or read_edid.. skipping it!\n",
> - dssdev->name);
> - continue;
> - }
> -
> - r = dssdev->driver->connect(dssdev);
> - if (r) {
> - dev_err(dev->dev, "could not connect display: %s\n",
> - dssdev->name);
> - continue;
> - }
>
> encoder = omap_encoder_init(dev, dssdev);
>
> @@ -656,9 +653,19 @@ static void pdev_shutdown(struct platform_device *device)
>
> static int pdev_probe(struct platform_device *device)
> {
> + int r;
> +
> if (omapdss_is_initialized() == false)
> return -EPROBE_DEFER;
>
> + omap_crtc_pre_init();
> +
> + r = omap_connect_dssdevs();
> + if (r) {
> + omap_crtc_pre_uninit();
> + return r;
> + }
> +
> DBG("%s", device->name);
> return drm_platform_init(&omap_drm_driver, device);
> }
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
> index 30b95b7..cb86cb3 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.h
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.h
> @@ -158,6 +158,7 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
> int omap_crtc_apply(struct drm_crtc *crtc,
> struct omap_drm_apply *apply);
> void omap_crtc_pre_init(void);
> +void omap_crtc_pre_uninit(void);
> struct drm_crtc *omap_crtc_init(struct drm_device *dev,
> struct drm_plane *plane, enum omap_channel channel, int id);
>
>
More information about the dri-devel
mailing list