mirror of https://gitee.com/openkylin/linux.git
omapdrm patches for 3.14
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSzqPyAAoJEPo9qoy8lh715MoP/i/70QZKPT4LxObqu+sVwqwp YEksEOgPFJZoUeZSs/7d7jgN/52bM9LCrARakEJdN8q+VyNWymXyi84VYE+vZB/D fHdDX5fTWsB09ORN2f4hRRPVJLr7kunJcMtNb3E0KTZKbDh6XOjdQ/pN+y6C9Gvt TzLLW9uuqFeziG5UVwgFIUgA99Z8BQYe7EMqs0k44vygq5/SNRkh7dbfGTiXVCnr NaMM1sa1MD3LW1Ec42StQ3bZDDE553V+SKWW3Xv7/x7kPQZmIs+wP+MxRa1DZGd1 a2acZvcDlbcp9Ea6UkErHxJKnWyW2ttqqTwljNvB88pJDFQ1RhNEslYMJCwDGDTn BYE9lhYfYZp9X4rP4OOazB1OGafoWguz+CzRidxsV17RloTHTVIgCZVQCcVOMmPK pPYUgVNHSJvo7kIaN0K/BEOSDYPyN92SAvdVlZMhE3blc2Zdu6R5l5uZ6TKmSlLs wFqagyLelM0k4JlvVwkwkPTSh1tLUO2UAnFUeiW7sPJlBxg5kV5jOwsisK69v5db arUkXXHO002L3P79LxCHqUIoRZG8FA73qRR6q2fqH4Yusq8GA0pWuNs31Ni5+Jha jjdGV+GMEXeula6q5H/JBRUvBUuWqxrR592DDuWE/C1M4ZHym6S04lN2h3bg2XRb 4yK+RbzfyZh/D3pZg+98 =/Uwk -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
dee13f12f6
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -45,12 +45,11 @@ static void omap_irq_update(struct drm_device *dev)
|
|||
dispc_read_irqenable(); /* flush posted write */
|
||||
}
|
||||
|
||||
void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
|
||||
void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
|
||||
{
|
||||
struct omap_drm_private *priv = dev->dev_private;
|
||||
unsigned long flags;
|
||||
|
||||
dispc_runtime_get();
|
||||
spin_lock_irqsave(&list_lock, flags);
|
||||
|
||||
if (!WARN_ON(irq->registered)) {
|
||||
|
@ -60,14 +59,21 @@ void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
|
|||
}
|
||||
|
||||
spin_unlock_irqrestore(&list_lock, flags);
|
||||
}
|
||||
|
||||
void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
|
||||
{
|
||||
dispc_runtime_get();
|
||||
|
||||
__omap_irq_register(dev, irq);
|
||||
|
||||
dispc_runtime_put();
|
||||
}
|
||||
|
||||
void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
|
||||
void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
dispc_runtime_get();
|
||||
spin_lock_irqsave(&list_lock, flags);
|
||||
|
||||
if (!WARN_ON(!irq->registered)) {
|
||||
|
@ -77,6 +83,14 @@ void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
|
|||
}
|
||||
|
||||
spin_unlock_irqrestore(&list_lock, flags);
|
||||
}
|
||||
|
||||
void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq)
|
||||
{
|
||||
dispc_runtime_get();
|
||||
|
||||
__omap_irq_unregister(dev, irq);
|
||||
|
||||
dispc_runtime_put();
|
||||
}
|
||||
|
||||
|
|
|
@ -3691,7 +3691,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_irq_safe(&pdev->dev);
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
|
|
Loading…
Reference in New Issue