mirror of https://gitee.com/openkylin/linux.git
drm: dw-hdmi: use cec_notifier_conn_(un)register
Use the new cec_notifier_conn_(un)register() functions to (un)register the notifier for the HDMI connector, and fill in the cec_connector_info. Changes since v6: - move cec_notifier_conn_unregister to a bridge detach function, - add a mutex protecting a CEC notifier. Changes since v4: - typo fix Changes since v2: - removed unnecessary NULL check before a call to cec_notifier_conn_unregister, - use cec_notifier_phys_addr_invalidate to invalidate physical address. Changes since v1: Add memory barrier to make sure that the notifier becomes visible to the irq thread once it is fully constructed. Signed-off-by: Dariusz Marcinkiewicz <darekm@google.com> Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190814104520.6001-9-darekm@google.com
This commit is contained in:
parent
96158346b5
commit
7070fe7386
|
@ -190,6 +190,7 @@ struct dw_hdmi {
|
|||
void (*enable_audio)(struct dw_hdmi *hdmi);
|
||||
void (*disable_audio)(struct dw_hdmi *hdmi);
|
||||
|
||||
struct mutex cec_notifier_mutex;
|
||||
struct cec_notifier *cec_notifier;
|
||||
};
|
||||
|
||||
|
@ -2230,6 +2231,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
|
|||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
struct drm_encoder *encoder = bridge->encoder;
|
||||
struct drm_connector *connector = &hdmi->connector;
|
||||
struct cec_connector_info conn_info;
|
||||
struct cec_notifier *notifier;
|
||||
|
||||
connector->interlace_allowed = 1;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
@ -2243,9 +2246,29 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
|
|||
|
||||
drm_connector_attach_encoder(connector, encoder);
|
||||
|
||||
cec_fill_conn_info_from_drm(&conn_info, connector);
|
||||
|
||||
notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
|
||||
if (!notifier)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&hdmi->cec_notifier_mutex);
|
||||
hdmi->cec_notifier = notifier;
|
||||
mutex_unlock(&hdmi->cec_notifier_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
|
||||
{
|
||||
struct dw_hdmi *hdmi = bridge->driver_private;
|
||||
|
||||
mutex_lock(&hdmi->cec_notifier_mutex);
|
||||
cec_notifier_conn_unregister(hdmi->cec_notifier);
|
||||
hdmi->cec_notifier = NULL;
|
||||
mutex_unlock(&hdmi->cec_notifier_mutex);
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *mode)
|
||||
|
@ -2302,6 +2325,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
|
|||
|
||||
static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
|
||||
.attach = dw_hdmi_bridge_attach,
|
||||
.detach = dw_hdmi_bridge_detach,
|
||||
.enable = dw_hdmi_bridge_enable,
|
||||
.disable = dw_hdmi_bridge_disable,
|
||||
.mode_set = dw_hdmi_bridge_mode_set,
|
||||
|
@ -2409,9 +2433,11 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
|
|||
phy_stat & HDMI_PHY_HPD,
|
||||
phy_stat & HDMI_PHY_RX_SENSE);
|
||||
|
||||
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
|
||||
cec_notifier_set_phys_addr(hdmi->cec_notifier,
|
||||
CEC_PHYS_ADDR_INVALID);
|
||||
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
|
||||
mutex_lock(&hdmi->cec_notifier_mutex);
|
||||
cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
|
||||
mutex_unlock(&hdmi->cec_notifier_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
|
||||
|
@ -2597,6 +2623,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
|||
|
||||
mutex_init(&hdmi->mutex);
|
||||
mutex_init(&hdmi->audio_mutex);
|
||||
mutex_init(&hdmi->cec_notifier_mutex);
|
||||
spin_lock_init(&hdmi->audio_lock);
|
||||
|
||||
ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
|
||||
|
@ -2729,12 +2756,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
|||
if (ret)
|
||||
goto err_iahb;
|
||||
|
||||
hdmi->cec_notifier = cec_notifier_get(dev);
|
||||
if (!hdmi->cec_notifier) {
|
||||
ret = -ENOMEM;
|
||||
goto err_iahb;
|
||||
}
|
||||
|
||||
/*
|
||||
* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
|
||||
* N and cts values before enabling phy
|
||||
|
@ -2833,9 +2854,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
|||
hdmi->ddc = NULL;
|
||||
}
|
||||
|
||||
if (hdmi->cec_notifier)
|
||||
cec_notifier_put(hdmi->cec_notifier);
|
||||
|
||||
clk_disable_unprepare(hdmi->iahb_clk);
|
||||
if (hdmi->cec_clk)
|
||||
clk_disable_unprepare(hdmi->cec_clk);
|
||||
|
@ -2857,9 +2875,6 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
|
|||
/* Disable all interrupts */
|
||||
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
|
||||
|
||||
if (hdmi->cec_notifier)
|
||||
cec_notifier_put(hdmi->cec_notifier);
|
||||
|
||||
clk_disable_unprepare(hdmi->iahb_clk);
|
||||
clk_disable_unprepare(hdmi->isfr_clk);
|
||||
if (hdmi->cec_clk)
|
||||
|
|
Loading…
Reference in New Issue