diff options
Diffstat (limited to 'drivers/misc/eeprom/at24.c')
-rw-r--r-- | drivers/misc/eeprom/at24.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 33053b0d1fdf..f5cc517d1131 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
@@ -532,6 +532,45 @@ static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata) | |||
532 | return 0; | 532 | return 0; |
533 | } | 533 | } |
534 | 534 | ||
535 | static void at24_remove_dummy_clients(struct at24_data *at24) | ||
536 | { | ||
537 | int i; | ||
538 | |||
539 | for (i = 1; i < at24->num_addresses; i++) | ||
540 | i2c_unregister_device(at24->client[i].client); | ||
541 | } | ||
542 | |||
543 | static int at24_make_dummy_client(struct at24_data *at24, unsigned int index, | ||
544 | struct regmap_config *regmap_config) | ||
545 | { | ||
546 | struct i2c_client *base_client, *dummy_client; | ||
547 | unsigned short int addr; | ||
548 | struct regmap *regmap; | ||
549 | struct device *dev; | ||
550 | |||
551 | base_client = at24->client[0].client; | ||
552 | dev = &base_client->dev; | ||
553 | addr = base_client->addr + index; | ||
554 | |||
555 | dummy_client = i2c_new_dummy(base_client->adapter, | ||
556 | base_client->addr + index); | ||
557 | if (!dummy_client) { | ||
558 | dev_err(dev, "address 0x%02x unavailable\n", addr); | ||
559 | return -EADDRINUSE; | ||
560 | } | ||
561 | |||
562 | regmap = devm_regmap_init_i2c(dummy_client, regmap_config); | ||
563 | if (IS_ERR(regmap)) { | ||
564 | i2c_unregister_device(dummy_client); | ||
565 | return PTR_ERR(regmap); | ||
566 | } | ||
567 | |||
568 | at24->client[index].client = dummy_client; | ||
569 | at24->client[index].regmap = regmap; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
535 | static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) | 574 | static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) |
536 | { | 575 | { |
537 | if (flags & AT24_FLAG_MAC) { | 576 | if (flags & AT24_FLAG_MAC) { |
@@ -637,20 +676,10 @@ static int at24_probe(struct i2c_client *client) | |||
637 | 676 | ||
638 | /* use dummy devices for multiple-address chips */ | 677 | /* use dummy devices for multiple-address chips */ |
639 | for (i = 1; i < num_addresses; i++) { | 678 | for (i = 1; i < num_addresses; i++) { |
640 | at24->client[i].client = i2c_new_dummy(client->adapter, | 679 | err = at24_make_dummy_client(at24, i, ®map_config); |
641 | client->addr + i); | 680 | if (err) { |
642 | if (!at24->client[i].client) { | 681 | at24_remove_dummy_clients(at24); |
643 | dev_err(dev, "address 0x%02x unavailable\n", | 682 | return err; |
644 | client->addr + i); | ||
645 | err = -EADDRINUSE; | ||
646 | goto err_clients; | ||
647 | } | ||
648 | at24->client[i].regmap = devm_regmap_init_i2c( | ||
649 | at24->client[i].client, | ||
650 | ®map_config); | ||
651 | if (IS_ERR(at24->client[i].regmap)) { | ||
652 | err = PTR_ERR(at24->client[i].regmap); | ||
653 | goto err_clients; | ||
654 | } | 683 | } |
655 | } | 684 | } |
656 | 685 | ||
@@ -685,7 +714,7 @@ static int at24_probe(struct i2c_client *client) | |||
685 | nvmem_config.word_size = 1; | 714 | nvmem_config.word_size = 1; |
686 | nvmem_config.size = pdata.byte_len; | 715 | nvmem_config.size = pdata.byte_len; |
687 | 716 | ||
688 | at24->nvmem = nvmem_register(&nvmem_config); | 717 | at24->nvmem = devm_nvmem_register(dev, &nvmem_config); |
689 | if (IS_ERR(at24->nvmem)) { | 718 | if (IS_ERR(at24->nvmem)) { |
690 | err = PTR_ERR(at24->nvmem); | 719 | err = PTR_ERR(at24->nvmem); |
691 | goto err_clients; | 720 | goto err_clients; |
@@ -702,10 +731,7 @@ static int at24_probe(struct i2c_client *client) | |||
702 | return 0; | 731 | return 0; |
703 | 732 | ||
704 | err_clients: | 733 | err_clients: |
705 | for (i = 1; i < num_addresses; i++) | 734 | at24_remove_dummy_clients(at24); |
706 | if (at24->client[i].client) | ||
707 | i2c_unregister_device(at24->client[i].client); | ||
708 | |||
709 | pm_runtime_disable(dev); | 735 | pm_runtime_disable(dev); |
710 | 736 | ||
711 | return err; | 737 | return err; |
@@ -714,15 +740,10 @@ err_clients: | |||
714 | static int at24_remove(struct i2c_client *client) | 740 | static int at24_remove(struct i2c_client *client) |
715 | { | 741 | { |
716 | struct at24_data *at24; | 742 | struct at24_data *at24; |
717 | int i; | ||
718 | 743 | ||
719 | at24 = i2c_get_clientdata(client); | 744 | at24 = i2c_get_clientdata(client); |
720 | 745 | ||
721 | nvmem_unregister(at24->nvmem); | 746 | at24_remove_dummy_clients(at24); |
722 | |||
723 | for (i = 1; i < at24->num_addresses; i++) | ||
724 | i2c_unregister_device(at24->client[i].client); | ||
725 | |||
726 | pm_runtime_disable(&client->dev); | 747 | pm_runtime_disable(&client->dev); |
727 | pm_runtime_set_suspended(&client->dev); | 748 | pm_runtime_set_suspended(&client->dev); |
728 | 749 | ||