Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panel: st7701: Decouple DSI and DRM parts

Split into a DSI-specific part and a DRM-specific part.

Additionally, use devm_add_action_or_reset() to simplify the flow,
and disable and unprepare the panel on cleanup.

Signed-off-by: Hironori KIKUCHI <kikuchan98@gmail.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20240804061503.881283-3-kikuchan98@gmail.com
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240804061503.881283-3-kikuchan98@gmail.com

authored by

Hironori KIKUCHI and committed by
Neil Armstrong
a055c91a 00b8a47d

+45 -27
+45 -27
drivers/gpu/drm/panel/panel-sitronix-st7701.c
··· 539 539 540 540 mode = drm_mode_duplicate(connector->dev, desc_mode); 541 541 if (!mode) { 542 - dev_err(&st7701->dsi->dev, "failed to add mode %ux%u@%u\n", 542 + dev_err(panel->dev, "failed to add mode %ux%u@%u\n", 543 543 desc_mode->hdisplay, desc_mode->vdisplay, 544 544 drm_mode_vrefresh(desc_mode)); 545 545 return -ENOMEM; ··· 974 974 .gip_sequence = rg_arc_gip_sequence, 975 975 }; 976 976 977 - static int st7701_dsi_probe(struct mipi_dsi_device *dsi) 977 + static void st7701_cleanup(void *data) 978 + { 979 + struct st7701 *st7701 = (struct st7701 *)data; 980 + 981 + drm_panel_remove(&st7701->panel); 982 + drm_panel_disable(&st7701->panel); 983 + drm_panel_unprepare(&st7701->panel); 984 + } 985 + 986 + static int st7701_probe(struct device *dev, int connector_type) 978 987 { 979 988 const struct st7701_panel_desc *desc; 980 989 struct st7701 *st7701; 981 990 int ret; 982 991 983 - st7701 = devm_kzalloc(&dsi->dev, sizeof(*st7701), GFP_KERNEL); 992 + st7701 = devm_kzalloc(dev, sizeof(*st7701), GFP_KERNEL); 984 993 if (!st7701) 985 994 return -ENOMEM; 986 995 987 - desc = of_device_get_match_data(&dsi->dev); 988 - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 989 - MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; 990 - dsi->format = desc->format; 991 - dsi->lanes = desc->lanes; 996 + desc = of_device_get_match_data(dev); 997 + if (!desc) 998 + return -ENODEV; 992 999 993 1000 st7701->supplies[0].supply = "VCC"; 994 1001 st7701->supplies[1].supply = "IOVCC"; 995 1002 996 - ret = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(st7701->supplies), 1003 + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st7701->supplies), 997 1004 st7701->supplies); 998 1005 if (ret < 0) 999 1006 return ret; 1000 1007 1001 - st7701->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW); 1008 + st7701->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 1002 1009 if (IS_ERR(st7701->reset)) { 1003 - dev_err(&dsi->dev, "Couldn't get our reset GPIO\n"); 1010 + dev_err(dev, "Couldn't get our reset GPIO\n"); 1004 1011 return PTR_ERR(st7701->reset); 1005 1012 } 1006 1013 1007 - ret = of_drm_get_panel_orientation(dsi->dev.of_node, &st7701->orientation); 1014 + ret = of_drm_get_panel_orientation(dev->of_node, &st7701->orientation); 1008 1015 if (ret < 0) 1009 - return dev_err_probe(&dsi->dev, ret, "Failed to get orientation\n"); 1016 + return dev_err_probe(dev, ret, "Failed to get orientation\n"); 1010 1017 1011 - drm_panel_init(&st7701->panel, &dsi->dev, &st7701_funcs, 1012 - DRM_MODE_CONNECTOR_DSI); 1018 + drm_panel_init(&st7701->panel, dev, &st7701_funcs, connector_type); 1013 1019 1014 1020 /** 1015 1021 * Once sleep out has been issued, ST7701 IC required to wait 120ms ··· 1034 1028 1035 1029 drm_panel_add(&st7701->panel); 1036 1030 1037 - mipi_dsi_set_drvdata(dsi, st7701); 1038 - st7701->dsi = dsi; 1031 + dev_set_drvdata(dev, st7701); 1039 1032 st7701->desc = desc; 1040 1033 1041 - ret = mipi_dsi_attach(dsi); 1042 - if (ret) 1043 - goto err_attach; 1034 + return devm_add_action_or_reset(dev, st7701_cleanup, st7701); 1035 + } 1036 + 1037 + static int st7701_dsi_probe(struct mipi_dsi_device *dsi) 1038 + { 1039 + struct st7701 *st7701; 1040 + int err; 1041 + 1042 + err = st7701_probe(&dsi->dev, DRM_MODE_CONNECTOR_DSI); 1043 + if (err) 1044 + return err; 1045 + 1046 + st7701 = dev_get_drvdata(&dsi->dev); 1047 + st7701->dsi = dsi; 1048 + 1049 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 1050 + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; 1051 + dsi->format = st7701->desc->format; 1052 + dsi->lanes = st7701->desc->lanes; 1053 + 1054 + err = mipi_dsi_attach(dsi); 1055 + if (err) 1056 + return dev_err_probe(&dsi->dev, err, "Failed to init MIPI DSI\n"); 1044 1057 1045 1058 return 0; 1046 - 1047 - err_attach: 1048 - drm_panel_remove(&st7701->panel); 1049 - return ret; 1050 1059 } 1051 1060 1052 1061 static void st7701_dsi_remove(struct mipi_dsi_device *dsi) 1053 1062 { 1054 - struct st7701 *st7701 = mipi_dsi_get_drvdata(dsi); 1055 - 1056 1063 mipi_dsi_detach(dsi); 1057 - drm_panel_remove(&st7701->panel); 1058 1064 } 1059 1065 1060 1066 static const struct of_device_id st7701_of_match[] = {