Rather than having 3 almost-identical functions plus the machinery to keep track of them, it's far simpler to just dynamically select the appropriate register field per variant.
Unified · Split
| @@ -448,21 +448,6 @@ static const struct regmap_irq_chip rk818_irq_chip = { · 447 unmodified lines | ||
| 448 | 448 | |
| 449 | 449 | static struct i2c_client *rk808_i2c_client; |
| 450 | 450 | |
| 451 | −static void rk805_device_shutdown(void) | |
| 452 | −{ | |
| 453 | − int ret; | |
| 454 | − struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); | |
| 455 | − | |
| 456 | − if (!rk808) | |
| 457 | − return; | |
| 458 | − | |
| 459 | − ret = regmap_update_bits(rk808->regmap, | |
| 460 | − RK805_DEV_CTRL_REG, | |
| 461 | − DEV_OFF, DEV_OFF); | |
| 462 | − if (ret) | |
| 463 | − dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); | |
| 464 | −} | |
| 465 | − | |
| 466 | 451 | static void rk805_device_shutdown_prepare(void) |
| 467 | 452 | { |
| 468 | 453 | int ret; |
| @@ -478,32 +463,29 @@ static void rk805_device_shutdown_prepare(void) · 9 unmodified lines | ||
| 478 | 463 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
| 479 | 464 | } |
| 480 | 465 | |
| 481 | −static void rk808_device_shutdown(void) | |
| 482 | −{ | |
| 483 | − int ret; | |
| 484 | − struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); | |
| 485 | − | |
| 486 | − if (!rk808) | |
| 487 | − return; | |
| 488 | − | |
| 489 | − ret = regmap_update_bits(rk808->regmap, | |
| 490 | − RK808_DEVCTRL_REG, | |
| 491 | − DEV_OFF_RST, DEV_OFF_RST); | |
| 492 | − if (ret) | |
| 493 | − dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); | |
| 494 | −} | |
| 495 | − | |
| 496 | −static void rk818_device_shutdown(void) | |
| 466 | +static void rk808_pm_power_off(void) | |
| 497 | 467 | { |
| 498 | 468 | int ret; |
| 469 | + unsigned int reg, bit; | |
| 499 | 470 | struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); |
| 500 | 471 | |
| 501 | − if (!rk808) | |
| 472 | + switch (rk808->variant) { | |
| 473 | + case RK805_ID: | |
| 474 | + reg = RK805_DEV_CTRL_REG; | |
| 475 | + bit = DEV_OFF; | |
| 476 | + break; | |
| 477 | + case RK808_ID: | |
| 478 | + reg = RK808_DEVCTRL_REG, | |
| 479 | + bit = DEV_OFF_RST; | |
| 480 | + break; | |
| 481 | + case RK818_ID: | |
| 482 | + reg = RK818_DEVCTRL_REG; | |
| 483 | + bit = DEV_OFF; | |
| 484 | + break; | |
| 485 | + default: | |
| 502 | 486 | return; |
| 503 | − | |
| 504 | − ret = regmap_update_bits(rk808->regmap, | |
| 505 | − RK818_DEVCTRL_REG, | |
| 506 | − DEV_OFF, DEV_OFF); | |
| 487 | + } | |
| 488 | + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); | |
| 507 | 489 | if (ret) |
| 508 | 490 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
| 509 | 491 | } |
| @@ -592,7 +574,6 @@ static int rk808_probe(struct i2c_client *client, · 82 unmodified lines | ||
| 592 | 574 | nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg); |
| 593 | 575 | cells = rk805s; |
| 594 | 576 | nr_cells = ARRAY_SIZE(rk805s); |
| 595 | − rk808->pm_pwroff_fn = rk805_device_shutdown; | |
| 596 | 577 | rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare; |
| 597 | 578 | break; |
| 598 | 579 | case RK808_ID: |
| @@ -602,7 +583,6 @@ static int rk808_probe(struct i2c_client *client, · 3 unmodified lines | ||
| 602 | 583 | nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); |
| 603 | 584 | cells = rk808s; |
| 604 | 585 | nr_cells = ARRAY_SIZE(rk808s); |
| 605 | − rk808->pm_pwroff_fn = rk808_device_shutdown; | |
| 606 | 586 | break; |
| 607 | 587 | case RK818_ID: |
| 608 | 588 | rk808->regmap_cfg = &rk818_regmap_config; |
| @@ -611,7 +591,6 @@ static int rk808_probe(struct i2c_client *client, · 2 unmodified lines | ||
| 611 | 591 | nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); |
| 612 | 592 | cells = rk818s; |
| 613 | 593 | nr_cells = ARRAY_SIZE(rk818s); |
| 614 | − rk808->pm_pwroff_fn = rk818_device_shutdown; | |
| 615 | 594 | break; |
| 616 | 595 | case RK809_ID: |
| 617 | 596 | case RK817_ID: |
| @@ -673,7 +652,7 @@ static int rk808_probe(struct i2c_client *client, · 55 unmodified lines | ||
| 673 | 652 | |
| 674 | 653 | if (of_property_read_bool(np, "rockchip,system-power-controller")) { |
| 675 | 654 | rk808_i2c_client = client; |
| 676 | − pm_power_off = rk808->pm_pwroff_fn; | |
| 655 | + pm_power_off = rk808_pm_power_off; | |
| 677 | 656 | pm_power_off_prepare = rk808->pm_pwroff_prep_fn; |
| 678 | 657 | } |
| 679 | 658 | |
| @@ -694,7 +673,7 @@ static int rk808_remove(struct i2c_client *client) · 14 unmodified lines | ||
| 694 | 673 | * pm_power_off may points to a function from another module. |
| 695 | 674 | * Check if the pointer is set by us and only then overwrite it. |
| 696 | 675 | */ |
| 697 | − if (rk808->pm_pwroff_fn && pm_power_off == rk808->pm_pwroff_fn) | |
| 676 | + if (pm_power_off == rk808_pm_power_off) | |
| 698 | 677 | pm_power_off = NULL; |
| 699 | 678 | |
| 700 | 679 | /** |
| @@ -620,7 +620,6 @@ struct rk808 { · 619 unmodified lines | ||
| 620 | 620 | long variant; |
| 621 | 621 | const struct regmap_config *regmap_cfg; |
| 622 | 622 | const struct regmap_irq_chip *regmap_irq_chip; |
| 623 | − void (*pm_pwroff_fn)(void); | |
| 624 | 623 | void (*pm_pwroff_prep_fn)(void); |
| 625 | 624 | }; |
| 626 | 625 | #endif /* __LINUX_REGULATOR_RK808_H */ |