Introduce 2 new macros, DSI_CTX_NO_OP and MIPI_DSI_ADD_MULTI_VARIANT.

DSI_CTX_NO_OP calls a function only if the context passed to it hasn't
encountered any errors. It is a generic form of what mipi_dsi_msleep
does.

MIPI_DSI_ADD_MULTI_VARIANT defines a multi style function of any
mipi_dsi function that follows a certain style. This allows us to
greatly reduce the amount of redundant code written for each multi
function. It reduces the overhead for a developer introducing new
mipi_dsi_*_multi functions.

Signed-off-by: Tejas Vipin <tejasvipi...@gmail.com>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 286 ++++++++++-----------------------
 1 file changed, 83 insertions(+), 203 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index a471c46f5ca6..53880b486f22 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1430,214 +1430,94 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
 
 /**
- * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the 
peripheral
- * @ctx: Context for multiple DSI transactions
- * @pps: VESA DSC 1.1 Picture Parameter Set
- *
- * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
-                                  const struct drm_dsc_picture_parameter_set 
*pps)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_picture_parameter_set(dsi, pps);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending PPS failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
-
-/**
- * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
- * @ctx: Context for multiple DSI transactions
- * @enable: Whether to enable or disable the DSC
- * @algo: Selected compression algorithm
- * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS 
entries
- *
- * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
-                                        bool enable,
-                                        enum mipi_dsi_compression_algo algo,
-                                        unsigned int pps_selector)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
-
-/**
- * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_nop() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
+ * DSI_CTX_NO_OP() - Calls a function only if no previous errors have
+ *     occurred.
+ * @func: The function call that needs to happen.
+ * @ctx: Context whose accum_err is checked to decide if the function
+ *     should run.
  */
-void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_dcs_nop(dsi);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending DCS NOP failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
+#define DSI_CTX_NO_OP(func, ctx)       \
+       do {                            \
+               if (!(ctx)->accum_err)  \
+                       func;           \
+       } while (0)
 
 /**
- * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE  packet
- * @ctx: Context for multiple DSI transactions
+ * MIPI_DSI_ADD_MULTI_VARIANT() - Define the multi variant of
+ *     an existing MIPI DSI function.
+ * @proto: The prototype of the desired multi variant
+ * @err: The error string used by dev_err on an error occurring.
+ * @inner_func: Identifier of the function being wrapped
+ * @...: Any arguments that need to be passed to inner_func
  *
- * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
  */
-void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
-
-/**
- * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
-
-/**
- * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_dcs_set_display_off(dsi);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
-
-/**
- * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_dcs_set_display_on(dsi);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
-
-/**
- * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
- * @ctx: Context for multiple DSI transactions
- * @mode: the Tearing Effect Output Line mode
- *
- * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
-                                   enum mipi_dsi_dcs_tear_mode mode)
-{
-       struct mipi_dsi_device *dsi = ctx->dsi;
-       struct device *dev = &dsi->dev;
-       ssize_t ret;
-
-       if (ctx->accum_err)
-               return;
-
-       ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
-       if (ret < 0) {
-               ctx->accum_err = ret;
-               dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
-                       ctx->accum_err);
-       }
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
+#define MIPI_DSI_ADD_MULTI_VARIANT(proto, err, inner_func, ...)        \
+proto {                                                                \
+       struct mipi_dsi_device *dsi = ctx->dsi;                 \
+       struct device *dev = &dsi->dev;                         \
+       int ret;                                                \
+       \
+       if (ctx->accum_err)                                     \
+               return;                                         \
+       \
+       ret = inner_func(dsi, ##__VA_ARGS__);                   \
+       if (ret < 0) {                                          \
+               ctx->accum_err = ret;                           \
+               dev_err(dev, err, ctx->accum_err);              \
+       }                                                       \
+}                                                              \
+EXPORT_SYMBOL(inner_func##_multi);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_picture_parameter_set_multi(
+       struct mipi_dsi_multi_context *ctx,
+       const struct drm_dsc_picture_parameter_set *pps),
+       "sending PPS failed: %d\n",
+       mipi_dsi_picture_parameter_set, pps);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_compression_mode_ext_multi(
+       struct mipi_dsi_multi_context *ctx, bool enable,
+       enum mipi_dsi_compression_algo algo, unsigned int pps_selector),
+       "sending COMPRESSION_MODE failed: %d\n",
+       mipi_dsi_compression_mode_ext, enable, algo, pps_selector);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_dcs_nop_multi(
+       struct mipi_dsi_multi_context *ctx),
+       "sending DCS NOP failed: %d\n",
+       mipi_dsi_dcs_nop);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_dcs_enter_sleep_mode_multi(
+       struct mipi_dsi_multi_context *ctx),
+       "sending DCS ENTER_SLEEP_MODE failed: %d\n",
+       mipi_dsi_dcs_enter_sleep_mode);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_dcs_exit_sleep_mode_multi(
+       struct mipi_dsi_multi_context *ctx),
+       "sending DCS EXIT_SLEEP_MODE failed: %d\n",
+       mipi_dsi_dcs_exit_sleep_mode);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_dcs_set_display_off_multi(
+       struct mipi_dsi_multi_context *ctx),
+       "sending DCS SET_DISPLAY_OFF failed: %d\n",
+       mipi_dsi_dcs_set_display_off);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_dcs_set_display_on_multi(
+       struct mipi_dsi_multi_context *ctx),
+       "sending DCS SET_DISPLAY_ON failed: %d\n",
+       mipi_dsi_dcs_set_display_on);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+       void mipi_dsi_dcs_set_tear_on_multi(
+       struct mipi_dsi_multi_context *ctx,
+       enum mipi_dsi_dcs_tear_mode mode),
+       "sending DCS SET_TEAR_ON failed: %d\n",
+       mipi_dsi_dcs_set_tear_on, mode);
 
 static int mipi_dsi_drv_probe(struct device *dev)
 {
-- 
2.45.2

Reply via email to