aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/eeprom/at24.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-14 03:21:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-14 03:21:46 -0400
commit9bca19a01d50143b736f0f59eb3ccc05b1106172 (patch)
tree3321118b4a6bd4c949634bbdbb3d2c03454ae33b /drivers/misc/eeprom/at24.c
parent463f202172c31b9c36278001cabfbad4e12da42e (diff)
parent53e39628ac228fada53cc0106be62c6f65f67501 (diff)
Merge branch 'i2c/for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang: - mainly feature additions to drivers (stm32f7, qup, xlp9xx, mlxcpld, ...) - conversion to use the i2c_8bit_addr_from_msg macro consistently - move includes to platform_data - core updates to allow the (still in review) I3C subsystem to connect - and the regular share of smaller driver updates * 'i2c/for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (68 commits) i2c: qup: fix building without CONFIG_ACPI i2c: tegra: Remove suspend-resume i2c: imx-lpi2c: Switch to SPDX identifier i2c: mxs: Switch to SPDX identifier i2c: busses: make use of i2c_8bit_addr_from_msg i2c: algos: make use of i2c_8bit_addr_from_msg i2c: rcar: document R8A77980 bindings i2c: qup: Add command-line parameter to override SCL frequency i2c: qup: Correct duty cycle for FM and FM+ i2c: qup: Add support for Fast Mode Plus i2c: qup: add probe path for Centriq ACPI devices i2c: robotfuzz-osif: drop pointless test i2c: robotfuzz-osif: remove pointless local variable i2c: rk3x: Don't print visible virtual mapping MMIO address i2c: opal: don't check number of messages in the driver i2c: ibm_iic: don't check number of messages in the driver i2c: imx: Switch to SPDX identifier i2c: mux: pca954x: merge calls to of_match_device and of_device_get_match_data i2c: mux: demux-pinctrl: use proper parent device for demux adapter i2c: mux: improve error message for failed symlink ...
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