aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc/tilcdc_slave.c
diff options
context:
space:
mode:
authorDarren Etheridge <detheridge@ti.com>2013-06-21 14:52:27 -0400
committerDave Airlie <airlied@redhat.com>2013-06-27 19:12:54 -0400
commit39de6194131c155901f96686a063212656d80c2e (patch)
tree251e3247c1c09c27bcd8401fce48aed92fdf7693 /drivers/gpu/drm/tilcdc/tilcdc_slave.c
parentf7b4575601dafb3cf3c568465ec6980de6d09b94 (diff)
drm/tilcdc fixing i2c/slave initialization race
In certain senarios drm will initialize before i2c this means that i2c slave devices like the nxp tda998x will fail to be probed. This patch detects this condition then defers the probe of the slave device and the tilcdc main driver. Signed-off-by: Darren Etheridge <detheridge@ti.com> Acked-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_slave.c')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_slave.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
index 8bf4fd19181c..dfffaf014022 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
@@ -298,6 +298,7 @@ static int slave_probe(struct platform_device *pdev)
298 struct tilcdc_module *mod; 298 struct tilcdc_module *mod;
299 struct pinctrl *pinctrl; 299 struct pinctrl *pinctrl;
300 uint32_t i2c_phandle; 300 uint32_t i2c_phandle;
301 struct i2c_adapter *slavei2c;
301 int ret = -EINVAL; 302 int ret = -EINVAL;
302 303
303 /* bail out early if no DT data: */ 304 /* bail out early if no DT data: */
@@ -306,44 +307,48 @@ static int slave_probe(struct platform_device *pdev)
306 return -ENXIO; 307 return -ENXIO;
307 } 308 }
308 309
309 slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL); 310 /* Bail out early if i2c not specified */
310 if (!slave_mod)
311 return -ENOMEM;
312
313 mod = &slave_mod->base;
314
315 tilcdc_module_init(mod, "slave", &slave_module_ops);
316
317 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
318 if (IS_ERR(pinctrl))
319 dev_warn(&pdev->dev, "pins are not configured\n");
320
321 if (of_property_read_u32(node, "i2c", &i2c_phandle)) { 311 if (of_property_read_u32(node, "i2c", &i2c_phandle)) {
322 dev_err(&pdev->dev, "could not get i2c bus phandle\n"); 312 dev_err(&pdev->dev, "could not get i2c bus phandle\n");
323 goto fail; 313 return ret;
324 } 314 }
325 315
326 mod->preferred_bpp = slave_info.bpp;
327
328 i2c_node = of_find_node_by_phandle(i2c_phandle); 316 i2c_node = of_find_node_by_phandle(i2c_phandle);
329 if (!i2c_node) { 317 if (!i2c_node) {
330 dev_err(&pdev->dev, "could not get i2c bus node\n"); 318 dev_err(&pdev->dev, "could not get i2c bus node\n");
331 goto fail; 319 return ret;
332 } 320 }
333 321
334 slave_mod->i2c = of_find_i2c_adapter_by_node(i2c_node); 322 /* but defer the probe if it can't be initialized it might come later */
335 if (!slave_mod->i2c) { 323 slavei2c = of_find_i2c_adapter_by_node(i2c_node);
324 of_node_put(i2c_node);
325
326 if (!slavei2c) {
327 ret = -EPROBE_DEFER;
328 tilcdc_slave_probedefer(true);
336 dev_err(&pdev->dev, "could not get i2c\n"); 329 dev_err(&pdev->dev, "could not get i2c\n");
337 goto fail; 330 return ret;
338 } 331 }
339 332
340 of_node_put(i2c_node); 333 slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL);
334 if (!slave_mod)
335 return -ENOMEM;
341 336
342 return 0; 337 mod = &slave_mod->base;
343 338
344fail: 339 mod->preferred_bpp = slave_info.bpp;
345 slave_destroy(mod); 340
346 return ret; 341 slave_mod->i2c = slavei2c;
342
343 tilcdc_module_init(mod, "slave", &slave_module_ops);
344
345 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
346 if (IS_ERR(pinctrl))
347 dev_warn(&pdev->dev, "pins are not configured\n");
348
349 tilcdc_slave_probedefer(false);
350
351 return 0;
347} 352}
348 353
349static int slave_remove(struct platform_device *pdev) 354static int slave_remove(struct platform_device *pdev)