summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWenlong Zhuang <daisen.zhuang@rock-chips.com>2019-01-10 11:14:44 +0800
committerTao Huang <huangtao@rock-chips.com>2019-01-18 16:06:03 +0800
commit2078e9f7634da559877e7252e3d7420c11c4b954 (patch)
tree27d51169846e682e54e48d3d518b94a2cde8c4b5 /drivers
parent3dc4f31060efde92b4aab988d6fe57be79a371df (diff)
media/cif: add csi host error interrupt handler for RK1808
Change-Id: I934cf09325fcb916c4a0fcffcf01ef869602d48f Signed-off-by: Wenlong Zhuang <daisen.zhuang@rock-chips.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/rockchip/cif/dev.c66
-rw-r--r--drivers/media/platform/rockchip/cif/regs.h4
2 files changed, 70 insertions, 0 deletions
diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c
index beb7a5f54c5d..d08aabdd4ae0 100644
--- a/drivers/media/platform/rockchip/cif/dev.c
+++ b/drivers/media/platform/rockchip/cif/dev.c
@@ -307,6 +307,50 @@ static irqreturn_t rkcif_irq_handler(int irq, void *ctx)
return IRQ_HANDLED;
}
+#define CSIHOST_MAX_ERRINT_COUNT 10
+
+static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
+{
+ struct device *dev = ctx;
+ struct rkcif_device *cif_dev = dev_get_drvdata(dev);
+ static int csi_err1_cnt;
+ u32 val;
+
+ val = read_csihost_reg(cif_dev->csi_base, CSIHOST_ERR1);
+ if (val) {
+ pr_err("ERROR: csi err1 intr: 0x%x\n", val);
+
+ if (++csi_err1_cnt > CSIHOST_MAX_ERRINT_COUNT) {
+ write_csihost_reg(cif_dev->csi_base,
+ CSIHOST_MSK1, 0xffffffff);
+ csi_err1_cnt = 0;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rk_csirx_irq2_handler(int irq, void *ctx)
+{
+ struct device *dev = ctx;
+ struct rkcif_device *cif_dev = dev_get_drvdata(dev);
+ static int csi_err2_cnt;
+ u32 val;
+
+ val = read_csihost_reg(cif_dev->csi_base, CSIHOST_ERR2);
+ if (val) {
+ pr_err("ERROR: csi err2 intr: 0x%x\n", val);
+
+ if (++csi_err2_cnt > CSIHOST_MAX_ERRINT_COUNT) {
+ write_csihost_reg(cif_dev->csi_base,
+ CSIHOST_MSK2, 0xffffffff);
+ csi_err2_cnt = 0;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
static void rkcif_disable_sys_clk(struct rkcif_device *cif_dev)
{
int i;
@@ -477,6 +521,28 @@ static int rkcif_plat_probe(struct platform_device *pdev)
cif_dev->csi_base = devm_ioremap_resource(dev, res);
if (IS_ERR(cif_dev->csi_base))
return PTR_ERR(cif_dev->csi_base);
+
+ irq = platform_get_irq_byname(pdev, "csi-intr1");
+ if (irq > 0) {
+ ret = devm_request_irq(dev, irq, rk_csirx_irq1_handler,
+ 0, dev_driver_string(dev), dev);
+ if (ret < 0)
+ dev_err(dev, "request csi-intr1 irq failed: %d\n",
+ ret);
+ } else {
+ dev_err(dev, "No found irq csi-intr1\n");
+ }
+
+ irq = platform_get_irq_byname(pdev, "csi-intr2");
+ if (irq > 0) {
+ ret = devm_request_irq(dev, irq, rk_csirx_irq2_handler,
+ 0, dev_driver_string(dev), dev);
+ if (ret < 0)
+ dev_err(dev, "request csi-intr2 failed: %d\n",
+ ret);
+ } else {
+ dev_err(dev, "No found irq csi-intr2\n");
+ }
} else {
using_pingpong = 0;
diff --git a/drivers/media/platform/rockchip/cif/regs.h b/drivers/media/platform/rockchip/cif/regs.h
index 958d07035c86..574e3ec17dc0 100644
--- a/drivers/media/platform/rockchip/cif/regs.h
+++ b/drivers/media/platform/rockchip/cif/regs.h
@@ -237,6 +237,10 @@
#define CSIHOST_N_LANES 0x04
#define CSIHOST_PHY_RSTZ 0x0c
#define CSIHOST_RESETN 0x10
+#define CSIHOST_ERR1 0x20
+#define CSIHOST_ERR2 0x24
+#define CSIHOST_MSK1 0x28
+#define CSIHOST_MSK2 0x2c
#define CSIHOST_CONTROL 0x40
#define SW_CPHY_EN(x) ((x) << 0)