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

drm: omapdrm: sdi: Allocate the sdi private data structure dynamically

The sdi private data structure is currently stored as a global
variable. While no platform with multiple SDI encoders currently exists
nor is planned, this doesn't comply with the kernel device model and
should thus be fixed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

authored by

Laurent Pinchart and committed by
Tomi Valkeinen
24aac601 c44991ce

+86 -65
+86 -65
drivers/gpu/drm/omapdrm/dss/sdi.c
··· 29 29 #include "omapdss.h" 30 30 #include "dss.h" 31 31 32 - static struct { 32 + struct sdi_device { 33 33 struct platform_device *pdev; 34 34 struct dss_device *dss; 35 35 ··· 41 41 int datapairs; 42 42 43 43 struct omap_dss_device output; 44 + }; 44 45 45 - bool port_initialized; 46 - } sdi; 46 + #define dssdev_to_sdi(dssdev) container_of(dssdev, struct sdi_device, output) 47 47 48 48 struct sdi_clk_calc_ctx { 49 + struct sdi_device *sdi; 49 50 unsigned long pck_min, pck_max; 50 51 51 52 unsigned long fck; ··· 72 71 73 72 ctx->fck = fck; 74 73 75 - return dispc_div_calc(sdi.dss->dispc, fck, 74 + return dispc_div_calc(ctx->sdi->dss->dispc, fck, 76 75 ctx->pck_min, ctx->pck_max, 77 76 dpi_calc_dispc_cb, ctx); 78 77 } 79 78 80 - static int sdi_calc_clock_div(unsigned long pclk, 81 - unsigned long *fck, 82 - struct dispc_clock_info *dispc_cinfo) 79 + static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk, 80 + unsigned long *fck, 81 + struct dispc_clock_info *dispc_cinfo) 83 82 { 84 83 int i; 85 - struct sdi_clk_calc_ctx ctx; 84 + struct sdi_clk_calc_ctx ctx = { .sdi = sdi }; 86 85 87 86 /* 88 87 * DSS fclk gives us very few possibilities, so finding a good pixel ··· 101 100 ctx.pck_min = 0; 102 101 ctx.pck_max = pclk + 1000 * i * i * i; 103 102 104 - ok = dss_div_calc(sdi.dss, pclk, ctx.pck_min, 103 + ok = dss_div_calc(sdi->dss, pclk, ctx.pck_min, 105 104 dpi_calc_dss_cb, &ctx); 106 105 if (ok) { 107 106 *fck = ctx.fck; ··· 113 112 return -EINVAL; 114 113 } 115 114 116 - static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 115 + static void sdi_config_lcd_manager(struct sdi_device *sdi) 117 116 { 118 - sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 117 + sdi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 119 118 120 - sdi.mgr_config.stallmode = false; 121 - sdi.mgr_config.fifohandcheck = false; 119 + sdi->mgr_config.stallmode = false; 120 + sdi->mgr_config.fifohandcheck = false; 122 121 123 - sdi.mgr_config.video_port_width = 24; 124 - sdi.mgr_config.lcden_sig_polarity = 1; 122 + sdi->mgr_config.video_port_width = 24; 123 + sdi->mgr_config.lcden_sig_polarity = 1; 125 124 126 - dss_mgr_set_lcd_config(&sdi.output, &sdi.mgr_config); 125 + dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config); 127 126 } 128 127 129 128 static int sdi_display_enable(struct omap_dss_device *dssdev) 130 129 { 131 - struct videomode *vm = &sdi.vm; 130 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 131 + struct videomode *vm = &sdi->vm; 132 132 unsigned long fck; 133 133 struct dispc_clock_info dispc_cinfo; 134 134 unsigned long pck; 135 135 int r; 136 136 137 - if (!sdi.output.dispc_channel_connected) { 137 + if (!sdi->output.dispc_channel_connected) { 138 138 DSSERR("failed to enable display: no output/manager\n"); 139 139 return -ENODEV; 140 140 } 141 141 142 - r = regulator_enable(sdi.vdds_sdi_reg); 142 + r = regulator_enable(sdi->vdds_sdi_reg); 143 143 if (r) 144 144 goto err_reg_enable; 145 145 146 - r = dispc_runtime_get(sdi.dss->dispc); 146 + r = dispc_runtime_get(sdi->dss->dispc); 147 147 if (r) 148 148 goto err_get_dispc; 149 149 150 150 /* 15.5.9.1.2 */ 151 151 vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_SYNC_POSEDGE; 152 152 153 - r = sdi_calc_clock_div(vm->pixelclock, &fck, &dispc_cinfo); 153 + r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo); 154 154 if (r) 155 155 goto err_calc_clock_div; 156 156 157 - sdi.mgr_config.clock_info = dispc_cinfo; 157 + sdi->mgr_config.clock_info = dispc_cinfo; 158 158 159 159 pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div; 160 160 ··· 167 165 } 168 166 169 167 170 - dss_mgr_set_timings(&sdi.output, vm); 168 + dss_mgr_set_timings(&sdi->output, vm); 171 169 172 - r = dss_set_fck_rate(sdi.dss, fck); 170 + r = dss_set_fck_rate(sdi->dss, fck); 173 171 if (r) 174 172 goto err_set_dss_clock_div; 175 173 176 - sdi_config_lcd_manager(dssdev); 174 + sdi_config_lcd_manager(sdi); 177 175 178 176 /* 179 177 * LCLK and PCLK divisors are located in shadow registers, and we ··· 186 184 * need to care about the shadow register mechanism for pck-free. The 187 185 * exact reason for this is unknown. 188 186 */ 189 - dispc_mgr_set_clock_div(sdi.dss->dispc, sdi.output.dispc_channel, 190 - &sdi.mgr_config.clock_info); 187 + dispc_mgr_set_clock_div(sdi->dss->dispc, sdi->output.dispc_channel, 188 + &sdi->mgr_config.clock_info); 191 189 192 - dss_sdi_init(sdi.dss, sdi.datapairs); 193 - r = dss_sdi_enable(sdi.dss); 190 + dss_sdi_init(sdi->dss, sdi->datapairs); 191 + r = dss_sdi_enable(sdi->dss); 194 192 if (r) 195 193 goto err_sdi_enable; 196 194 mdelay(2); 197 195 198 - r = dss_mgr_enable(&sdi.output); 196 + r = dss_mgr_enable(&sdi->output); 199 197 if (r) 200 198 goto err_mgr_enable; 201 199 202 200 return 0; 203 201 204 202 err_mgr_enable: 205 - dss_sdi_disable(sdi.dss); 203 + dss_sdi_disable(sdi->dss); 206 204 err_sdi_enable: 207 205 err_set_dss_clock_div: 208 206 err_calc_clock_div: 209 - dispc_runtime_put(sdi.dss->dispc); 207 + dispc_runtime_put(sdi->dss->dispc); 210 208 err_get_dispc: 211 - regulator_disable(sdi.vdds_sdi_reg); 209 + regulator_disable(sdi->vdds_sdi_reg); 212 210 err_reg_enable: 213 211 return r; 214 212 } 215 213 216 214 static void sdi_display_disable(struct omap_dss_device *dssdev) 217 215 { 218 - dss_mgr_disable(&sdi.output); 216 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 219 217 220 - dss_sdi_disable(sdi.dss); 218 + dss_mgr_disable(&sdi->output); 221 219 222 - dispc_runtime_put(sdi.dss->dispc); 220 + dss_sdi_disable(sdi->dss); 223 221 224 - regulator_disable(sdi.vdds_sdi_reg); 222 + dispc_runtime_put(sdi->dss->dispc); 223 + 224 + regulator_disable(sdi->vdds_sdi_reg); 225 225 } 226 226 227 227 static void sdi_set_timings(struct omap_dss_device *dssdev, 228 228 struct videomode *vm) 229 229 { 230 - sdi.vm = *vm; 230 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 231 + 232 + sdi->vm = *vm; 231 233 } 232 234 233 235 static void sdi_get_timings(struct omap_dss_device *dssdev, 234 236 struct videomode *vm) 235 237 { 236 - *vm = sdi.vm; 238 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 239 + 240 + *vm = sdi->vm; 237 241 } 238 242 239 243 static int sdi_check_timings(struct omap_dss_device *dssdev, 240 244 struct videomode *vm) 241 245 { 246 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 242 247 enum omap_channel channel = dssdev->dispc_channel; 243 248 244 - if (!dispc_mgr_timings_ok(sdi.dss->dispc, channel, vm)) 249 + if (!dispc_mgr_timings_ok(sdi->dss->dispc, channel, vm)) 245 250 return -EINVAL; 246 251 247 252 if (vm->pixelclock == 0) ··· 257 248 return 0; 258 249 } 259 250 260 - static int sdi_init_regulator(void) 251 + static int sdi_init_regulator(struct sdi_device *sdi) 261 252 { 262 253 struct regulator *vdds_sdi; 263 254 264 - if (sdi.vdds_sdi_reg) 255 + if (sdi->vdds_sdi_reg) 265 256 return 0; 266 257 267 - vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi"); 258 + vdds_sdi = devm_regulator_get(&sdi->pdev->dev, "vdds_sdi"); 268 259 if (IS_ERR(vdds_sdi)) { 269 260 if (PTR_ERR(vdds_sdi) != -EPROBE_DEFER) 270 261 DSSERR("can't get VDDS_SDI regulator\n"); 271 262 return PTR_ERR(vdds_sdi); 272 263 } 273 264 274 - sdi.vdds_sdi_reg = vdds_sdi; 265 + sdi->vdds_sdi_reg = vdds_sdi; 275 266 276 267 return 0; 277 268 } ··· 279 270 static int sdi_connect(struct omap_dss_device *dssdev, 280 271 struct omap_dss_device *dst) 281 272 { 273 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 282 274 int r; 283 275 284 - r = sdi_init_regulator(); 276 + r = sdi_init_regulator(sdi); 285 277 if (r) 286 278 return r; 287 279 288 - r = dss_mgr_connect(&sdi.output, dssdev); 280 + r = dss_mgr_connect(&sdi->output, dssdev); 289 281 if (r) 290 282 return r; 291 283 ··· 294 284 if (r) { 295 285 DSSERR("failed to connect output to new device: %s\n", 296 286 dst->name); 297 - dss_mgr_disconnect(&sdi.output, dssdev); 287 + dss_mgr_disconnect(&sdi->output, dssdev); 298 288 return r; 299 289 } 300 290 ··· 304 294 static void sdi_disconnect(struct omap_dss_device *dssdev, 305 295 struct omap_dss_device *dst) 306 296 { 297 + struct sdi_device *sdi = dssdev_to_sdi(dssdev); 298 + 307 299 WARN_ON(dst != dssdev->dst); 308 300 309 301 if (dst != dssdev->dst) ··· 313 301 314 302 omapdss_output_unset_device(dssdev); 315 303 316 - dss_mgr_disconnect(&sdi.output, dssdev); 304 + dss_mgr_disconnect(&sdi->output, dssdev); 317 305 } 318 306 319 307 static const struct omapdss_sdi_ops sdi_ops = { ··· 328 316 .get_timings = sdi_get_timings, 329 317 }; 330 318 331 - static void sdi_init_output(struct platform_device *pdev) 319 + static void sdi_init_output(struct sdi_device *sdi) 332 320 { 333 - struct omap_dss_device *out = &sdi.output; 321 + struct omap_dss_device *out = &sdi->output; 334 322 335 - out->dev = &pdev->dev; 323 + out->dev = &sdi->pdev->dev; 336 324 out->id = OMAP_DSS_OUTPUT_SDI; 337 325 out->output_type = OMAP_DISPLAY_TYPE_SDI; 338 326 out->name = "sdi.0"; ··· 345 333 omapdss_register_output(out); 346 334 } 347 335 348 - static void sdi_uninit_output(struct platform_device *pdev) 336 + static void sdi_uninit_output(struct sdi_device *sdi) 349 337 { 350 - struct omap_dss_device *out = &sdi.output; 351 - 352 - omapdss_unregister_output(out); 338 + omapdss_unregister_output(&sdi->output); 353 339 } 354 340 355 341 int sdi_init_port(struct dss_device *dss, struct platform_device *pdev, 356 342 struct device_node *port) 357 343 { 344 + struct sdi_device *sdi; 358 345 struct device_node *ep; 359 346 u32 datapairs; 360 347 int r; 361 348 349 + sdi = kzalloc(sizeof(*sdi), GFP_KERNEL); 350 + if (!sdi) 351 + return -ENOMEM; 352 + 362 353 ep = of_get_next_child(port, NULL); 363 - if (!ep) 364 - return 0; 354 + if (!ep) { 355 + r = 0; 356 + goto err_free; 357 + } 365 358 366 359 r = of_property_read_u32(ep, "datapairs", &datapairs); 367 360 if (r) { ··· 374 357 goto err_datapairs; 375 358 } 376 359 377 - sdi.datapairs = datapairs; 378 - sdi.dss = dss; 360 + sdi->datapairs = datapairs; 361 + sdi->dss = dss; 379 362 380 363 of_node_put(ep); 381 364 382 - sdi.pdev = pdev; 365 + sdi->pdev = pdev; 366 + port->data = sdi; 383 367 384 - sdi_init_output(pdev); 385 - 386 - sdi.port_initialized = true; 368 + sdi_init_output(sdi); 387 369 388 370 return 0; 389 371 390 372 err_datapairs: 391 373 of_node_put(ep); 374 + err_free: 375 + kfree(sdi); 392 376 393 377 return r; 394 378 } 395 379 396 380 void sdi_uninit_port(struct device_node *port) 397 381 { 398 - if (!sdi.port_initialized) 382 + struct sdi_device *sdi = port->data; 383 + 384 + if (!sdi) 399 385 return; 400 386 401 - sdi_uninit_output(sdi.pdev); 387 + sdi_uninit_output(sdi); 388 + kfree(sdi); 402 389 }