aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/eeprom/at24.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/eeprom/at24.c')
-rw-r--r--drivers/misc/eeprom/at24.c71
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
535static 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
543static 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
535static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) 574static 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, &regmap_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 &regmap_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
704err_clients: 733err_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:
714static int at24_remove(struct i2c_client *client) 740static 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