Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dee13f12 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'omapdrm-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next

omapdrm patches for 3.14

* tag 'omapdrm-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux:
  drm/omap: Enable DT support for DMM
  drm/omap: fix: change dev_unload order
  drm/omap: fix: disable encoder before destroying it
  drm/omap: fix: disconnect devices when omapdrm module is removed
  drm/omap: fix: Defer probe if an omapdss device requests for it at connect
  drm/omap: fix (un)registering irqs inside an irq handler

Conflicts:
	drivers/gpu/drm/omapdrm/omap_drv.c
parents 5a0abe30 3d232346
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -411,7 +411,7 @@ static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
	struct drm_crtc *crtc = &omap_crtc->base;
	DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
	/* avoid getting in a flood, unregister the irq until next vblank */
	omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
	__omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
}

static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -421,13 +421,13 @@ static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
	struct drm_crtc *crtc = &omap_crtc->base;

	if (!omap_crtc->error_irq.registered)
		omap_irq_register(crtc->dev, &omap_crtc->error_irq);
		__omap_irq_register(crtc->dev, &omap_crtc->error_irq);

	if (!dispc_mgr_go_busy(omap_crtc->channel)) {
		struct omap_drm_private *priv =
				crtc->dev->dev_private;
		DBG("%s: apply done", omap_crtc->name);
		omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq);
		__omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq);
		queue_work(priv->wq, &omap_crtc->apply_work);
	}
}
@@ -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)
+9 −0
Original line number Diff line number Diff line
@@ -969,12 +969,21 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
};
#endif

#if defined(CONFIG_OF)
static const struct of_device_id dmm_of_match[] = {
	{ .compatible = "ti,omap4-dmm", },
	{ .compatible = "ti,omap5-dmm", },
	{},
};
#endif

struct platform_driver omap_dmm_driver = {
	.probe = omap_dmm_probe,
	.remove = omap_dmm_remove,
	.driver = {
		.owner = THIS_MODULE,
		.name = DMM_DRIVER_NAME,
		.of_match_table = of_match_ptr(dmm_of_match),
#ifdef CONFIG_PM
		.pm = &omap_dmm_pm_ops,
#endif
+58 −26
Original line number Diff line number Diff line
@@ -86,6 +86,47 @@ static bool channel_used(struct drm_device *dev, enum omap_channel channel)

	return false;
}
static void omap_disconnect_dssdevs(void)
{
	struct omap_dss_device *dssdev = NULL;

	for_each_dss_dev(dssdev)
		dssdev->driver->disconnect(dssdev);
}

static int omap_connect_dssdevs(void)
{
	int r;
	struct omap_dss_device *dssdev = NULL;
	bool no_displays = true;

	for_each_dss_dev(dssdev) {
		r = dssdev->driver->connect(dssdev);
		if (r == -EPROBE_DEFER) {
			omap_dss_put_device(dssdev);
			goto cleanup;
		} else if (r) {
			dev_warn(dssdev->dev, "could not connect display: %s\n",
				dssdev->name);
		} else {
			no_displays = false;
		}
	}

	if (no_displays)
		return -EPROBE_DEFER;

	return 0;

cleanup:
	/*
	 * if we are deferring probe, we disconnect the devices we previously
	 * connected
	 */
	omap_disconnect_dssdevs();

	return r;
}

static int omap_modeset_init(struct drm_device *dev)
{
@@ -95,9 +136,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 +157,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);

@@ -497,16 +517,16 @@ static int dev_unload(struct drm_device *dev)
	DBG("unload: dev=%p", dev);

	drm_kms_helper_poll_fini(dev);
	drm_vblank_cleanup(dev);
	omap_drm_irq_uninstall(dev);

	omap_fbdev_free(dev);
	omap_modeset_free(dev);
	omap_gem_deinit(dev);

	flush_workqueue(priv->wq);
	destroy_workqueue(priv->wq);

	drm_vblank_cleanup(dev);
	omap_drm_irq_uninstall(dev);

	kfree(dev->dev_private);
	dev->dev_private = NULL;

@@ -655,9 +675,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);
}
@@ -666,8 +696,10 @@ static int pdev_remove(struct platform_device *device)
{
	DBG("");

	drm_put_dev(platform_get_drvdata(device));
	omap_disconnect_dssdevs();
	omap_crtc_pre_uninit();

	drm_put_dev(platform_get_drvdata(device));
	return 0;
}

+3 −0
Original line number Diff line number Diff line
@@ -145,6 +145,8 @@ irqreturn_t omap_irq_handler(int irq, void *arg);
void omap_irq_preinstall(struct drm_device *dev);
int omap_irq_postinstall(struct drm_device *dev);
void omap_irq_uninstall(struct drm_device *dev);
void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
int omap_drm_irq_uninstall(struct drm_device *dev);
@@ -158,6 +160,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);

+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@ struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder)
static void omap_encoder_destroy(struct drm_encoder *encoder)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);

	omap_encoder_set_enabled(encoder, false);

	drm_encoder_cleanup(encoder);
	kfree(omap_encoder);
}
Loading