Commit 08818e6a authored by Heiko Stuebner's avatar Heiko Stuebner Committed by Mauro Carvalho Chehab

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: default avatarHeiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: default avatarDafna Hirschfeld <dafna.hirschfeld@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 098d9cdf
...@@ -685,12 +685,17 @@ static void rkisp1_handle_buffer(struct rkisp1_capture *cap) ...@@ -685,12 +685,17 @@ static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
spin_unlock(&cap->buf.lock); 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; unsigned int i;
u32 status; u32 status;
status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS); status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
if (!status)
return IRQ_NONE;
rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR); rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) { for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
...@@ -718,6 +723,8 @@ void rkisp1_capture_isr(struct rkisp1_device *rkisp1) ...@@ -718,6 +723,8 @@ void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
cap->is_streaming = false; cap->is_streaming = false;
wake_up(&cap->done); wake_up(&cap->done);
} }
return IRQ_HANDLED;
} }
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define _RKISP1_COMMON_H #define _RKISP1_COMMON_H
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/rkisp1-config.h> #include <linux/rkisp1-config.h>
#include <media/media-device.h> #include <media/media-device.h>
...@@ -455,9 +456,9 @@ void rkisp1_params_configure(struct rkisp1_params *params, ...@@ -455,9 +456,9 @@ void rkisp1_params_configure(struct rkisp1_params *params,
void rkisp1_params_disable(struct rkisp1_params *params); void rkisp1_params_disable(struct rkisp1_params *params);
/* irq handlers */ /* irq handlers */
void rkisp1_isp_isr(struct rkisp1_device *rkisp1); irqreturn_t rkisp1_isp_isr(int irq, void *ctx);
void rkisp1_mipi_isr(struct rkisp1_device *rkisp1); irqreturn_t rkisp1_mipi_isr(int irq, void *ctx);
void rkisp1_capture_isr(struct rkisp1_device *rkisp1); irqreturn_t rkisp1_capture_isr(int irq, void *ctx);
void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris); void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
void rkisp1_params_isr(struct rkisp1_device *rkisp1); void rkisp1_params_isr(struct rkisp1_device *rkisp1);
......
...@@ -101,9 +101,16 @@ ...@@ -101,9 +101,16 @@
* +-----------+ +-----------+ * +-----------+ +-----------+
*/ */
struct rkisp1_isr_data {
const char *name;
irqreturn_t (*isr)(int irq, void *ctx);
};
struct rkisp1_match_data { struct rkisp1_match_data {
const char * const *clks; 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; enum rkisp1_cif_isp_version isp_ver;
}; };
...@@ -386,18 +393,15 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1) ...@@ -386,18 +393,15 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
static irqreturn_t rkisp1_isr(int irq, void *ctx) 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 * Call rkisp1_capture_isr() first to handle the frame that
* potentially completed using the current frame_sequence number before * potentially completed using the current frame_sequence number before
* it is potentially incremented by rkisp1_isp_isr() in the vertical * it is potentially incremented by rkisp1_isp_isr() in the vertical
* sync. * sync.
*/ */
rkisp1_capture_isr(rkisp1); rkisp1_capture_isr(irq, ctx);
rkisp1_isp_isr(rkisp1); rkisp1_isp_isr(irq, ctx);
rkisp1_mipi_isr(rkisp1); rkisp1_mipi_isr(irq, ctx);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -408,9 +412,15 @@ static const char * const rk3399_isp_clks[] = { ...@@ -408,9 +412,15 @@ static const char * const rk3399_isp_clks[] = {
"hclk", "hclk",
}; };
static const struct rkisp1_isr_data rk3399_isp_isrs[] = {
{ NULL, rkisp1_isr },
};
static const struct rkisp1_match_data rk3399_isp_match_data = { static const struct rkisp1_match_data rk3399_isp_match_data = {
.clks = rk3399_isp_clks, .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, .isp_ver = RKISP1_V10,
}; };
...@@ -479,23 +489,27 @@ static int rkisp1_probe(struct platform_device *pdev) ...@@ -479,23 +489,27 @@ static int rkisp1_probe(struct platform_device *pdev)
if (IS_ERR(rkisp1->base_addr)) if (IS_ERR(rkisp1->base_addr))
return PTR_ERR(rkisp1->base_addr); return PTR_ERR(rkisp1->base_addr);
irq = platform_get_irq(pdev, 0); for (i = 0; i < match_data->isr_size; i++) {
if (irq < 0) irq = (match_data->isrs[i].name) ?
return irq; platform_get_irq_byname(pdev, match_data->isrs[i].name) :
platform_get_irq(pdev, i);
ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED, if (irq < 0)
dev_driver_string(dev), dev); return irq;
if (ret) {
dev_err(dev, "request irq failed: %d\n", ret); ret = devm_request_irq(dev, irq, match_data->isrs[i].isr, IRQF_SHARED,
return ret; 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]; 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) if (ret)
return ret; return ret;
rkisp1->clk_size = match_data->size; rkisp1->clk_size = match_data->clk_size;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
......
...@@ -1106,13 +1106,15 @@ void rkisp1_isp_unregister(struct rkisp1_device *rkisp1) ...@@ -1106,13 +1106,15 @@ void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
* Interrupt handlers * 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; u32 val, status;
status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS); status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
if (!status) if (!status)
return; return IRQ_NONE;
rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR); rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
...@@ -1147,6 +1149,8 @@ void rkisp1_mipi_isr(struct rkisp1_device *rkisp1) ...@@ -1147,6 +1149,8 @@ void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
} else { } else {
rkisp1->debug.mipi_error++; rkisp1->debug.mipi_error++;
} }
return IRQ_HANDLED;
} }
static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp) 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) ...@@ -1159,13 +1163,15 @@ static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
v4l2_event_queue(isp->sd.devnode, &event); 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; u32 status, isp_err;
status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS); status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
if (!status) if (!status)
return; return IRQ_NONE;
rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR); rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
...@@ -1207,4 +1213,6 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1) ...@@ -1207,4 +1213,6 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
*/ */
rkisp1_params_isr(rkisp1); rkisp1_params_isr(rkisp1);
} }
return IRQ_HANDLED;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment