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 <tejasvipin76@xxxxxxxxx> --- 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