media: rockchip: rkisp1: allow separate interrupts

Depending on the per-soc implementation there can be one interrupt
for isp, mipi and capture events or separate per-event interrupts.

So simply check for the presence of a named "mi" interrupt
to differentiate between the two cases.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
Heiko Stuebner 2021-07-23 09:32:15 +02:00 committed by Mauro Carvalho Chehab
parent 098d9cdfdf
commit 08818e6a1d
4 changed files with 57 additions and 27 deletions

View File

@ -685,12 +685,17 @@ static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
spin_unlock(&cap->buf.lock);
}
void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
unsigned int i;
u32 status;
status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
if (!status)
return IRQ_NONE;
rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
@ -718,6 +723,8 @@ void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
cap->is_streaming = false;
wake_up(&cap->done);
}
return IRQ_HANDLED;
}
/* ----------------------------------------------------------------------------

View File

@ -12,6 +12,7 @@
#define _RKISP1_COMMON_H
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/rkisp1-config.h>
#include <media/media-device.h>
@ -455,9 +456,9 @@ void rkisp1_params_configure(struct rkisp1_params *params,
void rkisp1_params_disable(struct rkisp1_params *params);
/* irq handlers */
void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
irqreturn_t rkisp1_isp_isr(int irq, void *ctx);
irqreturn_t rkisp1_mipi_isr(int irq, void *ctx);
irqreturn_t rkisp1_capture_isr(int irq, void *ctx);
void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
void rkisp1_params_isr(struct rkisp1_device *rkisp1);

View File

@ -101,9 +101,16 @@
* +-----------+ +-----------+
*/
struct rkisp1_isr_data {
const char *name;
irqreturn_t (*isr)(int irq, void *ctx);
};
struct rkisp1_match_data {
const char * const *clks;
unsigned int size;
unsigned int clk_size;
const struct rkisp1_isr_data *isrs;
unsigned int isr_size;
enum rkisp1_cif_isp_version isp_ver;
};
@ -386,18 +393,15 @@ err_unreg_isp_subdev:
static irqreturn_t rkisp1_isr(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
/*
* Call rkisp1_capture_isr() first to handle the frame that
* potentially completed using the current frame_sequence number before
* it is potentially incremented by rkisp1_isp_isr() in the vertical
* sync.
*/
rkisp1_capture_isr(rkisp1);
rkisp1_isp_isr(rkisp1);
rkisp1_mipi_isr(rkisp1);
rkisp1_capture_isr(irq, ctx);
rkisp1_isp_isr(irq, ctx);
rkisp1_mipi_isr(irq, ctx);
return IRQ_HANDLED;
}
@ -408,9 +412,15 @@ static const char * const rk3399_isp_clks[] = {
"hclk",
};
static const struct rkisp1_isr_data rk3399_isp_isrs[] = {
{ NULL, rkisp1_isr },
};
static const struct rkisp1_match_data rk3399_isp_match_data = {
.clks = rk3399_isp_clks,
.size = ARRAY_SIZE(rk3399_isp_clks),
.clk_size = ARRAY_SIZE(rk3399_isp_clks),
.isrs = rk3399_isp_isrs,
.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
.isp_ver = RKISP1_V10,
};
@ -479,23 +489,27 @@ static int rkisp1_probe(struct platform_device *pdev)
if (IS_ERR(rkisp1->base_addr))
return PTR_ERR(rkisp1->base_addr);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
for (i = 0; i < match_data->isr_size; i++) {
irq = (match_data->isrs[i].name) ?
platform_get_irq_byname(pdev, match_data->isrs[i].name) :
platform_get_irq(pdev, i);
if (irq < 0)
return irq;
ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED,
dev_driver_string(dev), dev);
if (ret) {
dev_err(dev, "request irq failed: %d\n", ret);
return ret;
ret = devm_request_irq(dev, irq, match_data->isrs[i].isr, IRQF_SHARED,
dev_driver_string(dev), dev);
if (ret) {
dev_err(dev, "request irq failed: %d\n", ret);
return ret;
}
}
for (i = 0; i < match_data->size; i++)
for (i = 0; i < match_data->clk_size; i++)
rkisp1->clks[i].id = match_data->clks[i];
ret = devm_clk_bulk_get(dev, match_data->size, rkisp1->clks);
ret = devm_clk_bulk_get(dev, match_data->clk_size, rkisp1->clks);
if (ret)
return ret;
rkisp1->clk_size = match_data->size;
rkisp1->clk_size = match_data->clk_size;
pm_runtime_enable(&pdev->dev);

View File

@ -1106,13 +1106,15 @@ void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
* Interrupt handlers
*/
void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
irqreturn_t rkisp1_mipi_isr(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
u32 val, status;
status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
if (!status)
return;
return IRQ_NONE;
rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
@ -1147,6 +1149,8 @@ void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
} else {
rkisp1->debug.mipi_error++;
}
return IRQ_HANDLED;
}
static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
@ -1159,13 +1163,15 @@ static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
v4l2_event_queue(isp->sd.devnode, &event);
}
void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
irqreturn_t rkisp1_isp_isr(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
u32 status, isp_err;
status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
if (!status)
return;
return IRQ_NONE;
rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
@ -1207,4 +1213,6 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
*/
rkisp1_params_isr(rkisp1);
}
return IRQ_HANDLED;
}