diff options
author | Wenlong Zhuang <daisen.zhuang@rock-chips.com> | 2019-01-10 11:14:44 +0800 |
---|---|---|
committer | Tao Huang <huangtao@rock-chips.com> | 2019-01-18 16:06:03 +0800 |
commit | 2078e9f7634da559877e7252e3d7420c11c4b954 (patch) | |
tree | 27d51169846e682e54e48d3d518b94a2cde8c4b5 /drivers | |
parent | 3dc4f31060efde92b4aab988d6fe57be79a371df (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.c | 66 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/cif/regs.h | 4 |
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) |