@@ -290,9 +290,15 @@ struct exynos_dsim_host_ops {
int (*detach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device);
};
+struct exynos_dsim_irq_ops {
+ void (*enable)(struct exynos_dsi *dsim);
+ void (*disable)(struct exynos_dsi *dsim);
+};
+
struct exynos_dsi_plat_data {
enum exynos_dsi_type hw_type;
const struct exynos_dsim_host_ops *host_ops;
+ const struct exynos_dsim_irq_ops *irq_ops;
};
struct exynos_dsi {
@@ -307,7 +313,6 @@ struct exynos_dsi {
struct clk **clks;
struct regulator_bulk_data supplies[2];
int irq;
- struct gpio_desc *te_gpio;
u32 pll_clk_rate;
u32 burst_clk_rate;
@@ -331,6 +336,7 @@ struct exynos_dsi {
struct exynos_dsi_enc {
struct drm_encoder encoder;
+ struct gpio_desc *te_gpio;
};
#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
@@ -1344,18 +1350,38 @@ static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void exynos_dsi_enable_irq(struct exynos_dsi *dsi)
+static void _exynos_dsi_enable_irq(struct exynos_dsi *dsim)
{
- enable_irq(dsi->irq);
+ struct _exynos_dsi *dsi = dsim->priv;
if (dsi->te_gpio)
enable_irq(gpiod_to_irq(dsi->te_gpio));
}
-static void exynos_dsi_disable_irq(struct exynos_dsi *dsi)
+static void _exynos_dsi_disable_irq(struct exynos_dsi *dsim)
{
+ struct _exynos_dsi *dsi = dsim->priv;
+
if (dsi->te_gpio)
disable_irq(gpiod_to_irq(dsi->te_gpio));
+}
+
+static void exynos_dsi_enable_irq(struct exynos_dsi *dsi)
+{
+ const struct exynos_dsi_plat_data *pdata = dsi->plat_data;
+
+ enable_irq(dsi->irq);
+
+ if (pdata->irq_ops && pdata->irq_ops->enable)
+ pdata->irq_ops->enable(dsi);
+}
+
+static void exynos_dsi_disable_irq(struct exynos_dsi *dsi)
+{
+ const struct exynos_dsi_plat_data *pdata = dsi->plat_data;
+
+ if (pdata->irq_ops && pdata->irq_ops->disable)
+ pdata->irq_ops->disable(dsi);
disable_irq(dsi->irq);
}
@@ -1384,9 +1410,10 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)
return 0;
}
-static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
+static int exynos_dsi_register_te_irq(struct exynos_dsi *dsim,
struct device *panel)
{
+ struct _exynos_dsi *dsi = dsim->priv;
int ret;
int te_gpio_irq;
@@ -1394,7 +1421,7 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
if (!dsi->te_gpio) {
return 0;
} else if (IS_ERR(dsi->te_gpio)) {
- dev_err(dsi->dev, "gpio request failed with %ld\n",
+ dev_err(dsim->dev, "gpio request failed with %ld\n",
PTR_ERR(dsi->te_gpio));
return PTR_ERR(dsi->te_gpio);
}
@@ -1404,7 +1431,7 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL,
IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi);
if (ret) {
- dev_err(dsi->dev, "request interrupt failed with %d\n", ret);
+ dev_err(dsim->dev, "request interrupt failed with %d\n", ret);
gpiod_put(dsi->te_gpio);
return ret;
}
@@ -1412,8 +1439,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
return 0;
}
-static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
+static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsim)
{
+ struct _exynos_dsi *dsi = dsim->priv;
+
if (dsi->te_gpio) {
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
gpiod_put(dsi->te_gpio);
@@ -2033,6 +2062,11 @@ static const struct dev_pm_ops exynos_dsi_pm_ops = {
pm_runtime_force_resume)
};
+static const struct exynos_dsim_irq_ops exynos_dsi_irq_ops = {
+ .enable = _exynos_dsi_enable_irq,
+ .disable = _exynos_dsi_disable_irq,
+};
+
static const struct exynos_dsim_host_ops exynos_dsi_host_ops = {
.register_host = exynos_dsi_register_host,
.unregister_host = exynos_dsi_unregister_host,
@@ -2043,26 +2077,31 @@ static const struct exynos_dsim_host_ops exynos_dsi_host_ops = {
static const struct exynos_dsi_plat_data exynos3250_dsi_pdata = {
.hw_type = DSIM_TYPE_EXYNOS3250,
.host_ops = &exynos_dsi_host_ops,
+ .irq_ops = &exynos_dsi_irq_ops,
};
static const struct exynos_dsi_plat_data exynos4210_dsi_pdata = {
.hw_type = DSIM_TYPE_EXYNOS4210,
.host_ops = &exynos_dsi_host_ops,
+ .irq_ops = &exynos_dsi_irq_ops,
};
static const struct exynos_dsi_plat_data exynos5410_dsi_pdata = {
.hw_type = DSIM_TYPE_EXYNOS5410,
.host_ops = &exynos_dsi_host_ops,
+ .irq_ops = &exynos_dsi_irq_ops,
};
static const struct exynos_dsi_plat_data exynos5422_dsi_pdata = {
.hw_type = DSIM_TYPE_EXYNOS5422,
.host_ops = &exynos_dsi_host_ops,
+ .irq_ops = &exynos_dsi_irq_ops,
};
static const struct exynos_dsi_plat_data exynos5433_dsi_pdata = {
.hw_type = DSIM_TYPE_EXYNOS5433,
.host_ops = &exynos_dsi_host_ops,
+ .irq_ops = &exynos_dsi_irq_ops,
};
static const struct of_device_id exynos_dsi_of_match[] = {
Enable and disable of te_gpio's are Exynos platform specific irq handling, so add the exynos based irq operations and hook them for exynos plat_data. Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> --- Changes for v11: - none Changes for v10: - split from previous series patch "drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge" drivers/gpu/drm/exynos/exynos_drm_dsi.c | 55 +++++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-)