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 | static struct i2c_client *rk808_i2c_client; | 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 | static void rk805_device_shutdown_prepare(void) | 451 | static void rk805_device_shutdown_prepare(void) |
| 467 | { | 452 | { |
| 468 | int ret; | 453 | int ret; |
| @@ -478,32 +463,29 @@ static void rk805_device_shutdown_prepare(void) · 9 unmodified lines | |||
| 478 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); | 463 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
| 479 | } | 464 | } |
| 480 | 465 | ||
| 481 | static void rk808_device_shutdown(void) | 466 | static void rk808_pm_power_off(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) | ||
| 497 | { | 467 | { |
| 498 | int ret; | 468 | int ret; |
| 469 | unsigned int reg, bit; | ||
| 499 | struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); | 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 | return; | 486 | return; |
| 503 | 487 | } | |
| 504 | ret = regmap_update_bits(rk808->regmap, | 488 | ret = regmap_update_bits(rk808->regmap, reg, bit, bit); |
| 505 | RK818_DEVCTRL_REG, | ||
| 506 | DEV_OFF, DEV_OFF); | ||
| 507 | if (ret) | 489 | if (ret) |
| 508 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); | 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 | nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg); | 574 | nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg); |
| 593 | cells = rk805s; | 575 | cells = rk805s; |
| 594 | nr_cells = ARRAY_SIZE(rk805s); | 576 | nr_cells = ARRAY_SIZE(rk805s); |
| 595 | rk808->pm_pwroff_fn = rk805_device_shutdown; | ||
| 596 | rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare; | 577 | rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare; |
| 597 | break; | 578 | break; |
| 598 | case RK808_ID: | 579 | case RK808_ID: |
| @@ -602,7 +583,6 @@ static int rk808_probe(struct i2c_client *client, · 3 unmodified lines | |||
| 602 | nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); | 583 | nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); |
| 603 | cells = rk808s; | 584 | cells = rk808s; |
| 604 | nr_cells = ARRAY_SIZE(rk808s); | 585 | nr_cells = ARRAY_SIZE(rk808s); |
| 605 | rk808->pm_pwroff_fn = rk808_device_shutdown; | ||
| 606 | break; | 586 | break; |
| 607 | case RK818_ID: | 587 | case RK818_ID: |
| 608 | rk808->regmap_cfg = &rk818_regmap_config; | 588 | rk808->regmap_cfg = &rk818_regmap_config; |
| @@ -611,7 +591,6 @@ static int rk808_probe(struct i2c_client *client, · 2 unmodified lines | |||
| 611 | nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); | 591 | nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); |
| 612 | cells = rk818s; | 592 | cells = rk818s; |
| 613 | nr_cells = ARRAY_SIZE(rk818s); | 593 | nr_cells = ARRAY_SIZE(rk818s); |
| 614 | rk808->pm_pwroff_fn = rk818_device_shutdown; | ||
| 615 | break; | 594 | break; |
| 616 | case RK809_ID: | 595 | case RK809_ID: |
| 617 | case RK817_ID: | 596 | case RK817_ID: |
| @@ -673,7 +652,7 @@ static int rk808_probe(struct i2c_client *client, · 55 unmodified lines | |||
| 673 | 652 | ||
| 674 | if (of_property_read_bool(np, "rockchip,system-power-controller")) { | 653 | if (of_property_read_bool(np, "rockchip,system-power-controller")) { |
| 675 | rk808_i2c_client = client; | 654 | rk808_i2c_client = client; |
| 676 | pm_power_off = rk808->pm_pwroff_fn; | 655 | pm_power_off = rk808_pm_power_off; |
| 677 | pm_power_off_prepare = rk808->pm_pwroff_prep_fn; | 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 | * pm_power_off may points to a function from another module. | 673 | * pm_power_off may points to a function from another module. |
| 695 | * Check if the pointer is set by us and only then overwrite it. | 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 | pm_power_off = NULL; | 677 | pm_power_off = NULL; |
| 699 | 678 | ||
| 700 | /** | 679 | /** |
| @@ -620,7 +620,6 @@ struct rk808 { · 619 unmodified lines | |||
| 620 | long variant; | 620 | long variant; |
| 621 | const struct regmap_config *regmap_cfg; | 621 | const struct regmap_config *regmap_cfg; |
| 622 | const struct regmap_irq_chip *regmap_irq_chip; | 622 | const struct regmap_irq_chip *regmap_irq_chip; |
| 623 | void (*pm_pwroff_fn)(void); | ||
| 624 | void (*pm_pwroff_prep_fn)(void); | 623 | void (*pm_pwroff_prep_fn)(void); |
| 625 | }; | 624 | }; |
| 626 | #endif /* __LINUX_REGULATOR_RK808_H */ | 625 | #endif /* __LINUX_REGULATOR_RK808_H */ |