summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c19
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c11
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.h3
3 files changed, 31 insertions, 2 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 52438404c8c9..1ff6ab6371e8 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -43,6 +43,8 @@
#include <drm/exynos_drm.h>
+#include <media/cec-notifier.h>
+
#include "exynos_drm_crtc.h"
#define HOTPLUG_DEBOUNCE_MS 1100
@@ -118,6 +120,7 @@ struct hdmi_context {
bool dvi_mode;
struct delayed_work hotplug_work;
struct drm_display_mode current_mode;
+ struct cec_notifier *notifier;
const struct hdmi_driver_data *drv_data;
void __iomem *regs;
@@ -821,6 +824,7 @@ static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
if (gpiod_get_value(hdata->hpd_gpio))
return connector_status_connected;
+ cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
return connector_status_disconnected;
}
@@ -859,6 +863,7 @@ static int hdmi_get_modes(struct drm_connector *connector)
edid->width_cm, edid->height_cm);
drm_mode_connector_update_edid_property(connector, edid);
+ cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
ret = drm_add_edid_modes(connector, edid);
@@ -1501,6 +1506,7 @@ static void hdmi_disable(struct drm_encoder *encoder)
if (funcs && funcs->disable)
(*funcs->disable)(crtc);
+ cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
cancel_delayed_work(&hdata->hotplug_work);
hdmiphy_disable(hdata);
@@ -1880,15 +1886,22 @@ static int hdmi_probe(struct platform_device *pdev)
}
}
+ hdata->notifier = cec_notifier_get(&pdev->dev);
+ if (hdata->notifier == NULL) {
+ ret = -ENOMEM;
+ goto err_hdmiphy;
+ }
+
pm_runtime_enable(dev);
ret = component_add(&pdev->dev, &hdmi_component_ops);
if (ret)
- goto err_disable_pm_runtime;
+ goto err_notifier_put;
return ret;
-err_disable_pm_runtime:
+err_notifier_put:
+ cec_notifier_put(hdata->notifier);
pm_runtime_disable(dev);
err_hdmiphy:
@@ -1907,9 +1920,11 @@ static int hdmi_remove(struct platform_device *pdev)
struct hdmi_context *hdata = platform_get_drvdata(pdev);
cancel_delayed_work_sync(&hdata->hotplug_work);
+ cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
component_del(&pdev->dev, &hdmi_component_ops);
+ cec_notifier_put(hdata->notifier);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR(hdata->reg_hdmi_en))
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index ce2dcba679d5..243905b6ae59 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -771,6 +771,8 @@ static void sti_hdmi_disable(struct drm_bridge *bridge)
clk_disable_unprepare(hdmi->clk_pix);
hdmi->enabled = false;
+
+ cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
}
/**
@@ -973,6 +975,7 @@ static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
DRM_DEBUG_KMS("%s : %dx%d cm\n",
(hdmi->hdmi_monitor ? "hdmi monitor" : "dvi monitor"),
edid->width_cm, edid->height_cm);
+ cec_notifier_set_phys_addr_from_edid(hdmi->notifier, edid);
count = drm_add_edid_modes(connector, edid);
drm_mode_connector_update_edid_property(connector, edid);
@@ -1035,6 +1038,7 @@ sti_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
DRM_DEBUG_DRIVER("hdmi cable disconnected\n");
+ cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
return connector_status_disconnected;
}
@@ -1423,6 +1427,10 @@ static int sti_hdmi_probe(struct platform_device *pdev)
goto release_adapter;
}
+ hdmi->notifier = cec_notifier_get(&pdev->dev);
+ if (!hdmi->notifier)
+ goto release_adapter;
+
hdmi->reset = devm_reset_control_get(dev, "hdmi");
/* Take hdmi out of reset */
if (!IS_ERR(hdmi->reset))
@@ -1442,11 +1450,14 @@ static int sti_hdmi_remove(struct platform_device *pdev)
{
struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
+ cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
+
i2c_put_adapter(hdmi->ddc_adapt);
if (hdmi->audio_pdev)
platform_device_unregister(hdmi->audio_pdev);
component_del(&pdev->dev, &sti_hdmi_ops);
+ cec_notifier_put(hdmi->notifier);
return 0;
}
diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h
index 407012350f1a..c6469b56ce7e 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.h
+++ b/drivers/gpu/drm/sti/sti_hdmi.h
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <drm/drmP.h>
+#include <media/cec-notifier.h>
#define HDMI_STA 0x0010
#define HDMI_STA_DLL_LCK BIT(5)
@@ -64,6 +65,7 @@ static const struct drm_prop_enum_list colorspace_mode_names[] = {
* @audio_pdev: ASoC hdmi-codec platform device
* @audio: hdmi audio parameters.
* @drm_connector: hdmi connector
+ * @notifier: hotplug detect notifier
*/
struct sti_hdmi {
struct device dev;
@@ -89,6 +91,7 @@ struct sti_hdmi {
struct platform_device *audio_pdev;
struct hdmi_audio_params audio;
struct drm_connector *drm_connector;
+ struct cec_notifier *notifier;
};
u32 hdmi_read(struct sti_hdmi *hdmi, int offset);