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) return 0; } +static void at24_remove_dummy_clients(struct at24_data *at24) +{ + int i; + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i].client); +} + +static int at24_make_dummy_client(struct at24_data *at24, unsigned int index, + struct regmap_config *regmap_config) +{ + struct i2c_client *base_client, *dummy_client; + unsigned short int addr; + struct regmap *regmap; + struct device *dev; + + base_client = at24->client[0].client; + dev = &base_client->dev; + addr = base_client->addr + index; + + dummy_client = i2c_new_dummy(base_client->adapter, + base_client->addr + index); + if (!dummy_client) { + dev_err(dev, "address 0x%02x unavailable\n", addr); + return -EADDRINUSE; + } + + regmap = devm_regmap_init_i2c(dummy_client, regmap_config); + if (IS_ERR(regmap)) { + i2c_unregister_device(dummy_client); + return PTR_ERR(regmap); + } + + at24->client[index].client = dummy_client; + at24->client[index].regmap = regmap; + + return 0; +} + static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) { if (flags & AT24_FLAG_MAC) { @@ -637,20 +676,10 @@ static int at24_probe(struct i2c_client *client) /* use dummy devices for multiple-address chips */ for (i = 1; i < num_addresses; i++) { - at24->client[i].client = i2c_new_dummy(client->adapter, - client->addr + i); - if (!at24->client[i].client) { - dev_err(dev, "address 0x%02x unavailable\n", - client->addr + i); - err = -EADDRINUSE; - goto err_clients; - } - at24->client[i].regmap = devm_regmap_init_i2c( - at24->client[i].client, - ®map_config); - if (IS_ERR(at24->client[i].regmap)) { - err = PTR_ERR(at24->client[i].regmap); - goto err_clients; + err = at24_make_dummy_client(at24, i, ®map_config); + if (err) { + at24_remove_dummy_clients(at24); + return err; } } @@ -685,7 +714,7 @@ static int at24_probe(struct i2c_client *client) nvmem_config.word_size = 1; nvmem_config.size = pdata.byte_len; - at24->nvmem = nvmem_register(&nvmem_config); + at24->nvmem = devm_nvmem_register(dev, &nvmem_config); if (IS_ERR(at24->nvmem)) { err = PTR_ERR(at24->nvmem); goto err_clients; @@ -702,10 +731,7 @@ static int at24_probe(struct i2c_client *client) return 0; err_clients: - for (i = 1; i < num_addresses; i++) - if (at24->client[i].client) - i2c_unregister_device(at24->client[i].client); - + at24_remove_dummy_clients(at24); pm_runtime_disable(dev); return err; @@ -714,15 +740,10 @@ err_clients: static int at24_remove(struct i2c_client *client) { struct at24_data *at24; - int i; at24 = i2c_get_clientdata(client); - nvmem_unregister(at24->nvmem); - - for (i = 1; i < at24->num_addresses; i++) - i2c_unregister_device(at24->client[i].client); - + at24_remove_dummy_clients(at24); pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); |