media: rockchip: isp1: add vs irq handle

Change-Id: I94e4a22316c3e5a6feea42d4698ceadc21aa82b4
Signed-off-by: Hu Kejun <william.hu@rock-chips.com>
This commit is contained in:
Hu Kejun
2018-10-31 14:15:24 +08:00
committed by Tao Huang
parent d5a3e8be19
commit df8183eff9
4 changed files with 80 additions and 3 deletions

View File

@@ -37,6 +37,7 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
@@ -49,7 +50,6 @@
#include "regs.h"
#include "rkisp1.h"
#include "common.h"
#include "regs.h"
struct isp_match_data {
const char * const *clks;
@@ -246,6 +246,8 @@ static int rkisp1_pipeline_set_stream(struct rkisp1_pipeline *p, bool on)
return 0;
if (on) {
if (dev->vs_irq >= 0)
enable_irq(dev->vs_irq);
rockchip_set_system_status(SYS_STATUS_ISP);
v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, true);
}
@@ -258,6 +260,8 @@ static int rkisp1_pipeline_set_stream(struct rkisp1_pipeline *p, bool on)
}
if (!on) {
if (dev->vs_irq >= 0)
disable_irq(dev->vs_irq);
v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
rockchip_clear_system_status(SYS_STATUS_ISP);
}
@@ -750,6 +754,49 @@ static void rkisp1_iommu_cleanup(struct rkisp1_device *rkisp1_dev)
iommu_domain_free(rkisp1_dev->domain);
}
static int rkisp1_vs_irq_parse(struct platform_device *pdev)
{
int ret;
int vs_irq;
unsigned long vs_irq_flags;
struct gpio_desc *vs_irq_gpio;
struct device *dev = &pdev->dev;
struct rkisp1_device *isp_dev = dev_get_drvdata(dev);
/* this irq recevice the message of sensor vs from preisp */
isp_dev->vs_irq = -1;
vs_irq_gpio = devm_gpiod_get(dev, "vsirq", GPIOD_IN);
if (!IS_ERR(vs_irq_gpio)) {
vs_irq_flags = IRQF_TRIGGER_RISING |
IRQF_ONESHOT | IRQF_SHARED;
vs_irq = gpiod_to_irq(vs_irq_gpio);
if (vs_irq < 0) {
dev_err(dev, "GPIO to interrupt failed\n");
return vs_irq;
}
dev_info(dev, "register_irq: %d\n", vs_irq);
ret = devm_request_irq(dev,
vs_irq,
rkisp1_vs_isr_handler,
vs_irq_flags,
"vs_irq_gpio_int",
dev);
if (ret) {
dev_err(dev, "devm_request_irq failed: %d\n", ret);
return ret;
} else {
disable_irq(vs_irq);
isp_dev->vs_irq = vs_irq;
isp_dev->vs_irq_gpio = vs_irq_gpio;
dev_info(dev, "vs_gpio_int interrupt is hooked\n");
}
}
return 0;
}
static int rkisp1_plat_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@@ -825,8 +872,11 @@ static int rkisp1_plat_probe(struct platform_device *pdev)
v4l2_dev->ctrl_handler = &isp_dev->ctrl_handler;
ret = v4l2_device_register(isp_dev->dev, &isp_dev->v4l2_dev);
if (ret < 0)
if (ret < 0) {
v4l2_err(v4l2_dev, "Failed to register v4l2 device: %d\n",
ret);
return ret;
}
ret = media_device_register(&isp_dev->media_dev);
if (ret < 0) {
@@ -843,12 +893,20 @@ static int rkisp1_plat_probe(struct platform_device *pdev)
rkisp1_iommu_init(isp_dev);
pm_runtime_enable(&pdev->dev);
ret = rkisp1_vs_irq_parse(pdev);
if (ret)
goto err_runtime_disable;
return 0;
err_runtime_disable:
pm_runtime_disable(&pdev->dev);
rkisp1_iommu_cleanup(isp_dev);
err_unreg_media_dev:
media_device_unregister(&isp_dev->media_dev);
err_unreg_v4l2_dev:
v4l2_device_unregister(&isp_dev->v4l2_dev);
return ret;
}

View File

@@ -135,6 +135,8 @@ struct rkisp1_device {
unsigned int emd_data_idx;
unsigned int emd_vc;
unsigned int emd_dt;
int vs_irq;
struct gpio_desc *vs_irq_gpio;
};
#endif

View File

@@ -38,6 +38,7 @@
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/kfifo.h>
#include <linux/interrupt.h>
#include <media/v4l2-event.h>
#include <media/media-entity.h>
@@ -1413,7 +1414,8 @@ void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev)
/* start edge of v_sync */
if (isp_mis & CIF_ISP_V_START) {
riksp1_isp_queue_event_sof(&dev->isp_sdev);
if (dev->vs_irq < 0)
riksp1_isp_queue_event_sof(&dev->isp_sdev);
writel(CIF_ISP_V_START, base + CIF_ISP_ICR);
isp_mis_tmp = readl(base + CIF_ISP_MIS);
@@ -1470,3 +1472,15 @@ void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev)
*/
rkisp1_params_isr(&dev->params_vdev, isp_mis);
}
irqreturn_t rkisp1_vs_isr_handler(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkisp1_device *rkisp1_dev = dev_get_drvdata(dev);
if (rkisp1_dev->vs_irq >= 0)
riksp1_isp_queue_event_sof(&rkisp1_dev->isp_sdev);
return IRQ_HANDLED;
}

View File

@@ -37,6 +37,7 @@
#include <linux/kfifo.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <media/v4l2-fwnode.h>
#include "common.h"
@@ -121,6 +122,8 @@ void rkisp1_mipi_v13_isr(unsigned int err1, unsigned int err2,
void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev);
irqreturn_t rkisp1_vs_isr_handler(int irq, void *ctx);
static inline
struct ispsd_out_fmt *rkisp1_get_ispsd_out_fmt(struct rkisp1_isp_subdev *isp_sdev)
{