This adds reboot support to the rk808 pmic driver and enables it for the rk809 and rk817 devices. This only enables if the rockchip,system-power-controller flag is set.
Unified · Split
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/module.h> |
| 20 | 20 | #include <linux/of_device.h> |
| 21 | 21 | #include <linux/regmap.h> |
| 22 | +#include <linux/reboot.h> | |
| 22 | 23 | |
| 23 | 24 | struct rk808_reg_data { |
| 24 | 25 | int addr; |
| @@ -543,6 +544,7 @@ static void rk808_pm_power_off(void) · 518 unmodified lines | ||
| 543 | 544 | reg = RK808_DEVCTRL_REG, |
| 544 | 545 | bit = DEV_OFF_RST; |
| 545 | 546 | break; |
| 547 | + case RK809_ID: | |
| 546 | 548 | case RK817_ID: |
| 547 | 549 | reg = RK817_SYS_CFG(3); |
| 548 | 550 | bit = DEV_OFF; |
| @@ -559,6 +561,34 @@ static void rk808_pm_power_off(void) · 10 unmodified lines | ||
| 559 | 561 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
| 560 | 562 | } |
| 561 | 563 | |
| 564 | +static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd) | |
| 565 | +{ | |
| 566 | + struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); | |
| 567 | + unsigned int reg, bit; | |
| 568 | + int ret; | |
| 569 | + | |
| 570 | + switch (rk808->variant) { | |
| 571 | + case RK809_ID: | |
| 572 | + case RK817_ID: | |
| 573 | + reg = RK817_SYS_CFG(3); | |
| 574 | + bit = DEV_RST; | |
| 575 | + break; | |
| 576 | + | |
| 577 | + default: | |
| 578 | + return NOTIFY_DONE; | |
| 579 | + } | |
| 580 | + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); | |
| 581 | + if (ret) | |
| 582 | + dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n"); | |
| 583 | + | |
| 584 | + return NOTIFY_DONE; | |
| 585 | +} | |
| 586 | + | |
| 587 | +static struct notifier_block rk808_restart_handler = { | |
| 588 | + .notifier_call = rk808_restart_notify, | |
| 589 | + .priority = 192, | |
| 590 | +}; | |
| 591 | + | |
| 562 | 592 | static void rk8xx_shutdown(struct i2c_client *client) |
| 563 | 593 | { |
| 564 | 594 | struct rk808 *rk808 = i2c_get_clientdata(client); |
| @@ -727,6 +757,18 @@ static int rk808_probe(struct i2c_client *client, · 162 unmodified lines | ||
| 727 | 757 | if (of_property_read_bool(np, "rockchip,system-power-controller")) { |
| 728 | 758 | rk808_i2c_client = client; |
| 729 | 759 | pm_power_off = rk808_pm_power_off; |
| 760 | + | |
| 761 | + switch (rk808->variant) { | |
| 762 | + case RK809_ID: | |
| 763 | + case RK817_ID: | |
| 764 | + ret = register_restart_handler(&rk808_restart_handler); | |
| 765 | + if (ret) | |
| 766 | + dev_warn(&client->dev, "failed to register rst handler, %d\n", ret); | |
| 767 | + break; | |
| 768 | + default: | |
| 769 | + dev_dbg(&client->dev, "pmic controlled board reset not supported\n"); | |
| 770 | + break; | |
| 771 | + } | |
| 730 | 772 | } |
| 731 | 773 | |
| 732 | 774 | return 0; |
| @@ -749,6 +791,8 @@ static int rk808_remove(struct i2c_client *client) · 16 unmodified lines | ||
| 749 | 791 | if (pm_power_off == rk808_pm_power_off) |
| 750 | 792 | pm_power_off = NULL; |
| 751 | 793 | |
| 794 | + unregister_restart_handler(&rk808_restart_handler); | |
| 795 | + | |
| 752 | 796 | return 0; |
| 753 | 797 | } |
| 754 | 798 | |
| @@ -373,6 +373,7 @@ enum rk805_reg { · 372 unmodified lines | ||
| 373 | 373 | #define SWITCH2_EN BIT(6) |
| 374 | 374 | #define SWITCH1_EN BIT(5) |
| 375 | 375 | #define DEV_OFF_RST BIT(3) |
| 376 | +#define DEV_RST BIT(2) | |
| 376 | 377 | #define DEV_OFF BIT(0) |
| 377 | 378 | #define RTC_STOP BIT(0) |
| 378 | 379 | |