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

greybus: power_supply: Add runtime pm support

Modify Power_supply greybus driver to support runtime PM framework.

During charging state, the driver will block remote device of suspending,
and then enables runtime suspend when remote device is in none chargin
state.

Testing Done: Compiled and verified on EVT2, EVT2 1x2 GPB test module
and Device class daughter board.

Signed-off-by: Philip Yang <yang_philip@projectara.com>
Reviewed-by: Rui Miguel Silva <rui.silva@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>

authored by

Philip Yang and committed by
Greg Kroah-Hartman
4e013b64 6a57ddc9

+59 -3
+59 -3
drivers/staging/greybus/power_supply.c
··· 50 50 bool changed; 51 51 struct gb_power_supply_prop *props; 52 52 enum power_supply_property *props_raw; 53 + bool pm_acquired; 54 + struct mutex supply_lock; 53 55 }; 54 56 55 57 struct gb_power_supplies { ··· 77 75 struct gb_power_supply_prop *prop); 78 76 }; 79 77 78 + static void gb_power_supply_state_change(struct gb_power_supply *gbpsy, 79 + struct gb_power_supply_prop *prop); 80 + 80 81 static const struct gb_power_supply_changes psy_props_changes[] = { 81 82 { .prop = GB_POWER_SUPPLY_PROP_STATUS, 82 83 .tolerance_change = 0, 83 - .prop_changed = NULL, 84 + .prop_changed = gb_power_supply_state_change, 84 85 }, 85 86 { .prop = GB_POWER_SUPPLY_PROP_TEMP, 86 87 .tolerance_change = 500, ··· 353 348 power_supply_changed(gbpsy->psy); 354 349 } 355 350 #endif 351 + 352 + static void gb_power_supply_state_change(struct gb_power_supply *gbpsy, 353 + struct gb_power_supply_prop *prop) 354 + { 355 + struct gb_connection *connection = get_conn_from_psy(gbpsy); 356 + int ret; 357 + 358 + /* 359 + * Check gbpsy->pm_acquired to make sure only one pair of 'get_sync' 360 + * and 'put_autosuspend' runtime pm call for state property change. 361 + */ 362 + mutex_lock(&gbpsy->supply_lock); 363 + 364 + if ((prop->val == GB_POWER_SUPPLY_STATUS_CHARGING) && 365 + !gbpsy->pm_acquired) { 366 + ret = gb_pm_runtime_get_sync(connection->bundle); 367 + if (ret) 368 + dev_err(&connection->bundle->dev, 369 + "Fail to set wake lock for charging state\n"); 370 + else 371 + gbpsy->pm_acquired = true; 372 + } else { 373 + if (gbpsy->pm_acquired) { 374 + ret = gb_pm_runtime_put_autosuspend(connection->bundle); 375 + if (ret) 376 + dev_err(&connection->bundle->dev, 377 + "Fail to set wake unlock for none charging\n"); 378 + else 379 + gbpsy->pm_acquired = false; 380 + } 381 + } 382 + 383 + mutex_unlock(&gbpsy->supply_lock); 384 + } 356 385 357 386 static void check_changed(struct gb_power_supply *gbpsy, 358 387 struct gb_power_supply_prop *prop) ··· 694 655 695 656 static int gb_power_supply_status_get(struct gb_power_supply *gbpsy) 696 657 { 658 + struct gb_connection *connection = get_conn_from_psy(gbpsy); 697 659 int ret = 0; 698 660 int i; 699 661 700 662 if (is_cache_valid(gbpsy)) 701 663 return 0; 664 + 665 + ret = gb_pm_runtime_get_sync(connection->bundle); 666 + if (ret) 667 + return ret; 702 668 703 669 for (i = 0; i < gbpsy->properties_count; i++) { 704 670 ret = __gb_power_supply_property_update(gbpsy, ··· 715 671 if (ret == 0) 716 672 gbpsy->last_update = jiffies; 717 673 674 + gb_pm_runtime_put_autosuspend(connection->bundle); 718 675 return ret; 719 676 } 720 677 ··· 770 725 struct gb_power_supply_set_property_request req; 771 726 int ret; 772 727 728 + ret = gb_pm_runtime_get_sync(connection->bundle); 729 + if (ret) 730 + return ret; 731 + 773 732 prop = get_psy_prop(gbpsy, psp); 774 - if (!prop) 775 - return -EINVAL; 733 + if (!prop) { 734 + ret = -EINVAL; 735 + goto out; 736 + } 737 + 776 738 req.psy_id = gbpsy->id; 777 739 req.property = prop->gb_prop; 778 740 req.prop_val = cpu_to_le32((s32)val); ··· 793 741 prop->val = val; 794 742 795 743 out: 744 + gb_pm_runtime_put_autosuspend(connection->bundle); 796 745 return ret; 797 746 } 798 747 ··· 935 882 sizeof(gbpsy->name)); 936 883 if (ret < 0) 937 884 return ret; 885 + 886 + mutex_init(&gbpsy->supply_lock); 938 887 939 888 ret = gb_power_supply_register(gbpsy); 940 889 if (ret < 0) ··· 1122 1067 if (ret < 0) 1123 1068 goto error_connection_disable; 1124 1069 1070 + gb_pm_runtime_put_autosuspend(bundle); 1125 1071 return 0; 1126 1072 1127 1073 error_connection_disable: