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

Configure Feed

Select the types of activity you want to include in your feed.

dw9768: Enable low-power probe on ACPI

Add support for low-power probe to the driver. Also fix runtime PM API
usage in the driver.

Much of the hassle comes from different factors affecting device power
states during probe for ACPI and DT.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Fixes: 859891228e56 ("media: i2c: dw9768: Add DW9768 VCM driver")

+25 -8
+25 -8
drivers/media/i2c/dw9768.c
··· 414 414 { 415 415 struct device *dev = &client->dev; 416 416 struct dw9768 *dw9768; 417 + bool full_power; 417 418 unsigned int i; 418 419 int ret; 419 420 ··· 470 469 471 470 dw9768->sd.entity.function = MEDIA_ENT_F_LENS; 472 471 472 + /* 473 + * Figure out whether we're going to power up the device here. Generally 474 + * this is done if CONFIG_PM is disabled in a DT system or the device is 475 + * to be powered on in an ACPI system. Similarly for power off in 476 + * remove. 477 + */ 473 478 pm_runtime_enable(dev); 474 - if (!pm_runtime_enabled(dev)) { 479 + full_power = (is_acpi_node(dev_fwnode(dev)) && 480 + acpi_dev_state_d0(dev)) || 481 + (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev)); 482 + if (full_power) { 475 483 ret = dw9768_runtime_resume(dev); 476 484 if (ret < 0) { 477 485 dev_err(dev, "failed to power on: %d\n", ret); 478 486 goto err_clean_entity; 479 487 } 488 + pm_runtime_set_active(dev); 480 489 } 481 490 482 491 ret = v4l2_async_register_subdev(&dw9768->sd); ··· 495 484 goto err_power_off; 496 485 } 497 486 487 + pm_runtime_idle(dev); 488 + 498 489 return 0; 499 490 500 491 err_power_off: 501 - if (pm_runtime_enabled(dev)) 502 - pm_runtime_disable(dev); 503 - else 492 + if (full_power) { 504 493 dw9768_runtime_suspend(dev); 494 + pm_runtime_set_suspended(dev); 495 + } 505 496 err_clean_entity: 497 + pm_runtime_disable(dev); 506 498 media_entity_cleanup(&dw9768->sd.entity); 507 499 err_free_handler: 508 500 v4l2_ctrl_handler_free(&dw9768->ctrls); ··· 517 503 { 518 504 struct v4l2_subdev *sd = i2c_get_clientdata(client); 519 505 struct dw9768 *dw9768 = sd_to_dw9768(sd); 506 + struct device *dev = &client->dev; 520 507 521 508 v4l2_async_unregister_subdev(&dw9768->sd); 522 509 v4l2_ctrl_handler_free(&dw9768->ctrls); 523 510 media_entity_cleanup(&dw9768->sd.entity); 524 - pm_runtime_disable(&client->dev); 525 - if (!pm_runtime_status_suspended(&client->dev)) 526 - dw9768_runtime_suspend(&client->dev); 527 - pm_runtime_set_suspended(&client->dev); 511 + if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) || 512 + (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) { 513 + dw9768_runtime_suspend(dev); 514 + pm_runtime_set_suspended(dev); 515 + } 516 + pm_runtime_disable(dev); 528 517 } 529 518 530 519 static const struct of_device_id dw9768_of_table[] = {