diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c index 474449ecdbbe..3f5f47a91845 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c @@ -1,34 +1,54 @@ -#include -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include #include #include -#include #include "rockchip-hdmi-cec.h" -#include "linux/ioctl.h" -#include "linux/pagemap.h" static struct cec_device *cec_dev; static int cecreadframe(struct cec_framedata *frame) { - if (frame == NULL || !cec_dev || - cec_dev->readframe == NULL || !cec_dev->enable) - return -1; - else - return cec_dev->readframe(cec_dev->hdmi, frame); + int ret = -1; + + if (!frame || !cec_dev || !cec_dev->readframe || !cec_dev->enable) { + return ret; + } else { + mutex_lock(&cec_dev->hdmi->pclk_lock); + ret = cec_dev->readframe(cec_dev->hdmi, frame); + mutex_unlock(&cec_dev->hdmi->pclk_lock); + return ret; + } } static int cecsendframe(struct cec_framedata *frame) { - if (frame == NULL || !cec_dev || cec_dev->readframe == NULL) - return -1; - else - return cec_dev->sendframe(cec_dev->hdmi, frame); + int ret = -1; + + if (!frame || !cec_dev || !cec_dev->sendframe) { + return ret; + } else { + mutex_lock(&cec_dev->hdmi->pclk_lock); + ret = cec_dev->sendframe(cec_dev->hdmi, frame); + mutex_unlock(&cec_dev->hdmi->pclk_lock); + return ret; + } +} + +static void cecsetlogicaddr(int addr) +{ + if (!cec_dev || !cec_dev->setceclogicaddr) { + return; + } else { + mutex_lock(&cec_dev->hdmi->pclk_lock); + cec_dev->setceclogicaddr(cec_dev->hdmi, addr); + mutex_unlock(&cec_dev->hdmi->pclk_lock); + } } static void cecworkfunc(struct work_struct *work) @@ -191,9 +211,7 @@ static long cec_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case HDMI_IOCTL_CECSETLA: ret = copy_from_user(&cec_dev->address_logic, argp, sizeof(int)); - if (cec_dev->setceclogicaddr) - cec_dev->setceclogicaddr(cec_dev->hdmi, - cec_dev->address_logic); + cecsetlogicaddr(cec_dev->address_logic); break; case HDMI_IOCTL_CECSEND: ret = copy_from_user(&cecsendtemp, argp, diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c index 4a7b5e1812e5..13f9ddb38684 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c @@ -488,6 +488,7 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property, memset(hdmi, 0, sizeof(struct hdmi)); mutex_init(&hdmi->lock); + mutex_init(&hdmi->pclk_lock); hdmi->property = property; hdmi->ops = ops; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi.h b/drivers/video/rockchip/hdmi/rockchip-hdmi.h index 5f1460a0832b..1b84ff6d45f5 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi.h @@ -393,6 +393,7 @@ struct hdmi { struct hdmi_ops *ops; struct mutex lock; /* mutex for hdmi operation */ + struct mutex pclk_lock; /* mutex for pclk operation */ struct workqueue_struct *workqueue; bool uboot; /* if true, HDMI is initialized in uboot*/ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c index b27e89402978..fe2ce384e158 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c @@ -200,12 +200,6 @@ void ext_pll_set_27m_out(void) 0x1d); } -#define HDMI_PD_ON (1 << 0) -#define HDMI_PCLK_ON (1 << 1) -#define HDMI_HDCPCLK_ON (1 << 2) -#define HDMI_CECCLK_ON (1 << 3) -#define HDMI_EXT_PHY_CLK_ON (1 << 4) - static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev) { if (hdmi_dev->soctype == HDMI_SOC_RK322X) { @@ -334,7 +328,9 @@ static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self, 0, 1); if (hdmi_dev->hdcp2_en) hdmi_dev->hdcp2_en(0); + mutex_lock(&hdmi->pclk_lock); rockchip_hdmiv2_clk_disable(hdmi_dev); + mutex_unlock(&hdmi->pclk_lock); #ifdef CONFIG_PINCTRL if (hdmi_dev->soctype == HDMI_SOC_RK3288) gpio_state = @@ -359,7 +355,9 @@ static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self, pinctrl_select_state(pins->p, pins->default_state); #endif + mutex_lock(&hdmi->pclk_lock); rockchip_hdmiv2_clk_enable(hdmi_dev); + mutex_unlock(&hdmi->pclk_lock); rockchip_hdmiv2_dev_initial(hdmi_dev); if (hdmi->ops->hdcp_power_on_cb) hdmi->ops->hdcp_power_on_cb(); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h index 27778ddd366f..cc441e75e179 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h @@ -15,6 +15,12 @@ #define HDMIDBG(format, ...) #endif +#define HDMI_PD_ON BIT(0) +#define HDMI_PCLK_ON BIT(1) +#define HDMI_HDCPCLK_ON BIT(2) +#define HDMI_CECCLK_ON BIT(3) +#define HDMI_EXT_PHY_CLK_ON BIT(4) + struct hdmi_dev_phy_para { u32 maxfreq; int pre_emphasis; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c index a016427c11cc..7af55bc67e4c 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c @@ -21,7 +21,7 @@ static int rockchip_hdmiv2_cec_readframe(struct hdmi *hdmi, int i, count; char *data = (char *)frame; - if (frame == NULL) + if (((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) || !frame) return -1; count = hdmi_readl(hdmi_dev, CEC_RX_CNT); CECDBG("%s count %d\n", __func__, count); @@ -40,6 +40,8 @@ void rockchip_hdmiv2_cec_setcecla(struct hdmi *hdmi, int ceclgaddr) struct hdmi_dev *hdmi_dev = hdmi->property->priv; short val; + if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) + return; if (ceclgaddr < 0 || ceclgaddr > 16) return; val = 1 << ceclgaddr; @@ -53,6 +55,8 @@ static int rockchip_hdmiv2_cec_sendframe(struct hdmi *hdmi, struct hdmi_dev *hdmi_dev = hdmi->property->priv; int i, interrupt; + if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) + return CEC_SEND_NACK; CECDBG("TX srcdestaddr %02x opcode %02x ", frame->srcdestaddr, frame->opcode); if (frame->argcount) {