summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/tegra/dc/nvhdcp.c26
-rw-r--r--include/video/nvhdcp.h1
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/nvhdcp.c b/drivers/video/tegra/dc/nvhdcp.c
index 10c451d9ff74..261d1a877c90 100644
--- a/drivers/video/tegra/dc/nvhdcp.c
+++ b/drivers/video/tegra/dc/nvhdcp.c
@@ -470,6 +470,20 @@ static int verify_ksv(u64 k)
return (i != 20) ? -EINVAL : 0;
}
+static int get_nvhdcp_state(struct tegra_nvhdcp *nvhdcp,
+ struct tegra_nvhdcp_packet *pkt)
+{
+ mutex_lock(&nvhdcp->lock);
+ if (nvhdcp->state != STATE_LINK_VERIFY) {
+ memset(pkt, 0, sizeof *pkt);
+ pkt->packet_results = TEGRA_NVHDCP_RESULT_LINK_FAILED;
+ } else {
+ pkt->packet_results = TEGRA_NVHDCP_RESULT_SUCCESS;
+ }
+ mutex_unlock(&nvhdcp->lock);
+ return 0;
+}
+
/* get Status and Kprime signature - READ_S on TMDS0_LINK0 only */
static int get_s_prime(struct tegra_nvhdcp *nvhdcp, struct tegra_nvhdcp_packet *pkt)
{
@@ -1158,6 +1172,18 @@ static long nvhdcp_dev_ioctl(struct file *filp,
case TEGRAIO_NVHDCP_RENEGOTIATE:
e = tegra_nvhdcp_renegotiate(nvhdcp);
break;
+
+ case TEGRAIO_NVHDCP_HDCP_STATE:
+ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt)
+ return -ENOMEM;
+ e = get_nvhdcp_state(nvhdcp, pkt);
+ if (copy_to_user((void __user *)arg, pkt, sizeof(*pkt))) {
+ e = -EFAULT;
+ goto kfree_pkt;
+ }
+ kfree(pkt);
+ return e;
}
return e;
diff --git a/include/video/nvhdcp.h b/include/video/nvhdcp.h
index f282ff8caa99..cf27ee50ca27 100644
--- a/include/video/nvhdcp.h
+++ b/include/video/nvhdcp.h
@@ -87,5 +87,6 @@ struct tegra_nvhdcp_packet {
#define TEGRAIO_NVHDCP_READ_M _IOWR('F', 0x73, struct tegra_nvhdcp_packet)
#define TEGRAIO_NVHDCP_READ_S _IOWR('F', 0x74, struct tegra_nvhdcp_packet)
#define TEGRAIO_NVHDCP_RENEGOTIATE _IO('F', 0x75)
+#define TEGRAIO_NVHDCP_HDCP_STATE _IOR('F', 0x76, struct tegra_nvhdcp_packet)
#endif