Instead of polling the connector for hotplug, use the hotplug workqueue
to fire a drm hotplug notification when we detect a cable change.
This will also update userspace when the state has changed, and notify
fbdev.
At this point in time, the patch should be a no-op, but it's important
if we want to use EDID to mode set.
BUG=chrome-os-partner:11158
TEST=Tested on snow, no regressions detected
Change-Id: Ib6b0c789f6abc45a118a04dcb8a73e8e35fd4a85
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/38408
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
* option) any later version.
*/
* option) any later version.
*/
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
irq_type = exynos_dp_get_irq_type(dp);
switch (irq_type) {
case DP_IRQ_TYPE_HP_CABLE_IN:
irq_type = exynos_dp_get_irq_type(dp);
switch (irq_type) {
case DP_IRQ_TYPE_HP_CABLE_IN:
- dev_dbg(dp->dev, "Received irq - cable in\n");
- schedule_work(&dp->hotplug_work);
- exynos_dp_clear_hotplug_interrupts(dp);
- break;
case DP_IRQ_TYPE_HP_CABLE_OUT:
case DP_IRQ_TYPE_HP_CABLE_OUT:
- dev_dbg(dp->dev, "Received irq - cable out\n");
+ dev_dbg(dp->dev, "Received irq - type=%d\n", irq_type);
+ schedule_work(&dp->hotplug_work);
exynos_dp_clear_hotplug_interrupts(dp);
break;
case DP_IRQ_TYPE_HP_CHANGE:
exynos_dp_clear_hotplug_interrupts(dp);
break;
case DP_IRQ_TYPE_HP_CHANGE:
dp = container_of(work, struct exynos_dp_device, hotplug_work);
dp = container_of(work, struct exynos_dp_device, hotplug_work);
+ /* Cable is disconnected, skip dp initialization */
+ if (exynos_dp_detect_hpd(dp))
+ goto out;
+
#ifdef CONFIG_DRM_PTN3460
ret = ptn3460_wait_until_ready(30 * 1000);
if (ret) {
#ifdef CONFIG_DRM_PTN3460
ret = ptn3460_wait_until_ready(30 * 1000);
if (ret) {
- ret = exynos_dp_detect_hpd(dp);
- if (ret) {
- /* Cable has been disconnected, we're done */
- return;
- }
-
ret = exynos_dp_handle_edid(dp);
if (ret) {
dev_err(dp->dev, "unable to handle edid\n");
ret = exynos_dp_handle_edid(dp);
if (ret) {
dev_err(dp->dev, "unable to handle edid\n");
exynos_dp_init_video(dp);
exynos_dp_config_video(dp);
exynos_dp_init_video(dp);
exynos_dp_config_video(dp);
+
+out:
+ drm_helper_hpd_irq_event(dp->drm_dev);
}
static int exynos_dp_power_off(struct exynos_dp_device *dp)
}
static int exynos_dp_power_off(struct exynos_dp_device *dp)
break;
case EXYNOS_DRM_DISPLAY_TYPE_FIMD:
type = DRM_MODE_CONNECTOR_eDP;
break;
case EXYNOS_DRM_DISPLAY_TYPE_FIMD:
type = DRM_MODE_CONNECTOR_eDP;
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
break;
default:
type = DRM_MODE_CONNECTOR_Unknown;
break;
default:
type = DRM_MODE_CONNECTOR_Unknown;