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;
|
struct drm_crtc *crtc = &omap_crtc->base;
|
||||||
DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
|
DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
|
||||||
/* avoid getting in a flood, unregister the irq until next vblank */
|
/* 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)
|
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;
|
struct drm_crtc *crtc = &omap_crtc->base;
|
||||||
|
|
||||||
if (!omap_crtc->error_irq.registered)
|
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)) {
|
if (!dispc_mgr_go_busy(omap_crtc->channel)) {
|
||||||
struct omap_drm_private *priv =
|
struct omap_drm_private *priv =
|
||||||
crtc->dev->dev_private;
|
crtc->dev->dev_private;
|
||||||
DBG("%s: apply done", omap_crtc->name);
|
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);
|
queue_work(priv->wq, &omap_crtc->apply_work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,6 +623,11 @@ void omap_crtc_pre_init(void)
|
||||||
dss_install_mgr_ops(&mgr_ops);
|
dss_install_mgr_ops(&mgr_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void omap_crtc_pre_uninit(void)
|
||||||
|
{
|
||||||
|
dss_uninstall_mgr_ops();
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize crtc */
|
/* initialize crtc */
|
||||||
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
||||||
struct drm_plane *plane, enum omap_channel channel, int id)
|
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
|
#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 = {
|
struct platform_driver omap_dmm_driver = {
|
||||||
.probe = omap_dmm_probe,
|
.probe = omap_dmm_probe,
|
||||||
.remove = omap_dmm_remove,
|
.remove = omap_dmm_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = DMM_DRIVER_NAME,
|
.name = DMM_DRIVER_NAME,
|
||||||
|
.of_match_table = of_match_ptr(dmm_of_match),
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.pm = &omap_dmm_pm_ops,
|
.pm = &omap_dmm_pm_ops,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -86,6 +86,47 @@ static bool channel_used(struct drm_device *dev, enum omap_channel channel)
|
||||||
|
|
||||||
return false;
|
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)
|
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_mgrs = dss_feat_get_num_mgrs();
|
||||||
int num_crtcs;
|
int num_crtcs;
|
||||||
int i, id = 0;
|
int i, id = 0;
|
||||||
int r;
|
|
||||||
|
|
||||||
omap_crtc_pre_init();
|
|
||||||
|
|
||||||
drm_mode_config_init(dev);
|
drm_mode_config_init(dev);
|
||||||
|
|
||||||
|
@ -119,26 +157,8 @@ static int omap_modeset_init(struct drm_device *dev)
|
||||||
enum omap_channel channel;
|
enum omap_channel channel;
|
||||||
struct omap_overlay_manager *mgr;
|
struct omap_overlay_manager *mgr;
|
||||||
|
|
||||||
if (!dssdev->driver) {
|
if (!omapdss_device_is_connected(dssdev))
|
||||||
dev_warn(dev->dev, "%s has no driver.. skipping it\n",
|
|
||||||
dssdev->name);
|
|
||||||
continue;
|
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);
|
encoder = omap_encoder_init(dev, dssdev);
|
||||||
|
|
||||||
|
@ -497,16 +517,16 @@ static int dev_unload(struct drm_device *dev)
|
||||||
DBG("unload: dev=%p", dev);
|
DBG("unload: dev=%p", dev);
|
||||||
|
|
||||||
drm_kms_helper_poll_fini(dev);
|
drm_kms_helper_poll_fini(dev);
|
||||||
drm_vblank_cleanup(dev);
|
|
||||||
omap_drm_irq_uninstall(dev);
|
|
||||||
|
|
||||||
omap_fbdev_free(dev);
|
omap_fbdev_free(dev);
|
||||||
omap_modeset_free(dev);
|
omap_modeset_free(dev);
|
||||||
omap_gem_deinit(dev);
|
omap_gem_deinit(dev);
|
||||||
|
|
||||||
flush_workqueue(priv->wq);
|
|
||||||
destroy_workqueue(priv->wq);
|
destroy_workqueue(priv->wq);
|
||||||
|
|
||||||
|
drm_vblank_cleanup(dev);
|
||||||
|
omap_drm_irq_uninstall(dev);
|
||||||
|
|
||||||
kfree(dev->dev_private);
|
kfree(dev->dev_private);
|
||||||
dev->dev_private = NULL;
|
dev->dev_private = NULL;
|
||||||
|
|
||||||
|
@ -655,9 +675,19 @@ static void pdev_shutdown(struct platform_device *device)
|
||||||
|
|
||||||
static int pdev_probe(struct platform_device *device)
|
static int pdev_probe(struct platform_device *device)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
if (omapdss_is_initialized() == false)
|
if (omapdss_is_initialized() == false)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
|
omap_crtc_pre_init();
|
||||||
|
|
||||||
|
r = omap_connect_dssdevs();
|
||||||
|
if (r) {
|
||||||
|
omap_crtc_pre_uninit();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
DBG("%s", device->name);
|
DBG("%s", device->name);
|
||||||
return drm_platform_init(&omap_drm_driver, device);
|
return drm_platform_init(&omap_drm_driver, device);
|
||||||
}
|
}
|
||||||
|
@ -666,8 +696,10 @@ static int pdev_remove(struct platform_device *device)
|
||||||
{
|
{
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
drm_put_dev(platform_get_drvdata(device));
|
omap_disconnect_dssdevs();
|
||||||
|
omap_crtc_pre_uninit();
|
||||||
|
|
||||||
|
drm_put_dev(platform_get_drvdata(device));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,8 @@ irqreturn_t omap_irq_handler(int irq, void *arg);
|
||||||
void omap_irq_preinstall(struct drm_device *dev);
|
void omap_irq_preinstall(struct drm_device *dev);
|
||||||
int omap_irq_postinstall(struct drm_device *dev);
|
int omap_irq_postinstall(struct drm_device *dev);
|
||||||
void omap_irq_uninstall(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_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_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
|
||||||
int omap_drm_irq_uninstall(struct drm_device *dev);
|
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,
|
int omap_crtc_apply(struct drm_crtc *crtc,
|
||||||
struct omap_drm_apply *apply);
|
struct omap_drm_apply *apply);
|
||||||
void omap_crtc_pre_init(void);
|
void omap_crtc_pre_init(void);
|
||||||
|
void omap_crtc_pre_uninit(void);
|
||||||
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
||||||
struct drm_plane *plane, enum omap_channel channel, int id);
|
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)
|
static void omap_encoder_destroy(struct drm_encoder *encoder)
|
||||||
{
|
{
|
||||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||||
|
|
||||||
|
omap_encoder_set_enabled(encoder, false);
|
||||||
|
|
||||||
drm_encoder_cleanup(encoder);
|
drm_encoder_cleanup(encoder);
|
||||||
kfree(omap_encoder);
|
kfree(omap_encoder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,12 +45,11 @@ static void omap_irq_update(struct drm_device *dev)
|
||||||
dispc_read_irqenable(); /* flush posted write */
|
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;
|
struct omap_drm_private *priv = dev->dev_private;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
dispc_runtime_get();
|
|
||||||
spin_lock_irqsave(&list_lock, flags);
|
spin_lock_irqsave(&list_lock, flags);
|
||||||
|
|
||||||
if (!WARN_ON(irq->registered)) {
|
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);
|
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();
|
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;
|
unsigned long flags;
|
||||||
|
|
||||||
dispc_runtime_get();
|
|
||||||
spin_lock_irqsave(&list_lock, flags);
|
spin_lock_irqsave(&list_lock, flags);
|
||||||
|
|
||||||
if (!WARN_ON(!irq->registered)) {
|
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);
|
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();
|
dispc_runtime_put();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3691,7 +3691,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
pm_runtime_enable(&pdev->dev);
|
||||||
pm_runtime_irq_safe(&pdev->dev);
|
|
||||||
|
|
||||||
r = dispc_runtime_get();
|
r = dispc_runtime_get();
|
||||||
if (r)
|
if (r)
|
||||||
|
|
Loading…
Reference in New Issue