Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: Convert the eeprom driver to a new-style i2c driver

The new-style eeprom driver implements the optional detect() callback
to cover the use cases of the legacy driver.

Signed-off-by: Jean Delvare <khali@linux-fr.org>

authored by

Jean Delvare and committed by
Jean Delvare
68be3363 bd4bc3db

+40 -52
+40 -52
drivers/i2c/chips/eeprom.c
··· 47 47 48 48 /* Each client has this additional data */ 49 49 struct eeprom_data { 50 - struct i2c_client client; 51 50 struct mutex update_lock; 52 51 u8 valid; /* bitfield, bit!=0 if slice is valid */ 53 52 unsigned long last_updated[8]; /* In jiffies, 8 slices */ ··· 54 55 enum eeprom_nature nature; 55 56 }; 56 57 57 - 58 - static int eeprom_attach_adapter(struct i2c_adapter *adapter); 59 - static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind); 60 - static int eeprom_detach_client(struct i2c_client *client); 61 - 62 - /* This is the driver that will be inserted */ 63 - static struct i2c_driver eeprom_driver = { 64 - .driver = { 65 - .name = "eeprom", 66 - }, 67 - .attach_adapter = eeprom_attach_adapter, 68 - .detach_client = eeprom_detach_client, 69 - }; 70 58 71 59 static void eeprom_update_client(struct i2c_client *client, u8 slice) 72 60 { ··· 134 148 .read = eeprom_read, 135 149 }; 136 150 137 - static int eeprom_attach_adapter(struct i2c_adapter *adapter) 151 + /* Return 0 if detection is successful, -ENODEV otherwise */ 152 + static int eeprom_detect(struct i2c_client *client, int kind, 153 + struct i2c_board_info *info) 138 154 { 139 - if (!(adapter->class & (I2C_CLASS_DDC | I2C_CLASS_SPD))) 140 - return 0; 141 - return i2c_probe(adapter, &addr_data, eeprom_detect); 142 - } 143 - 144 - /* This function is called by i2c_probe */ 145 - static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) 146 - { 147 - struct i2c_client *client; 148 - struct eeprom_data *data; 149 - int err = 0; 155 + struct i2c_adapter *adapter = client->adapter; 150 156 151 157 /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all 152 158 addresses 0x50-0x57, but we only care about 0x50. So decline 153 159 attaching to addresses >= 0x51 on DDC buses */ 154 - if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51) 155 - goto exit; 160 + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) 161 + return -ENODEV; 156 162 157 163 /* There are four ways we can read the EEPROM data: 158 164 (1) I2C block reads (faster, but unsupported by most adapters) ··· 155 177 because all known adapters support one of the first two. */ 156 178 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA) 157 179 && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) 158 - goto exit; 180 + return -ENODEV; 181 + 182 + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); 183 + 184 + return 0; 185 + } 186 + 187 + static int eeprom_probe(struct i2c_client *client, 188 + const struct i2c_device_id *id) 189 + { 190 + struct i2c_adapter *adapter = client->adapter; 191 + struct eeprom_data *data; 192 + int err; 159 193 160 194 if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { 161 195 err = -ENOMEM; 162 196 goto exit; 163 197 } 164 198 165 - client = &data->client; 166 199 memset(data->data, 0xff, EEPROM_SIZE); 167 200 i2c_set_clientdata(client, data); 168 - client->addr = address; 169 - client->adapter = adapter; 170 - client->driver = &eeprom_driver; 171 - 172 - /* Fill in the remaining client fields */ 173 - strlcpy(client->name, "eeprom", I2C_NAME_SIZE); 174 201 mutex_init(&data->update_lock); 175 202 data->nature = UNKNOWN; 176 203 177 - /* Tell the I2C layer a new client has arrived */ 178 - if ((err = i2c_attach_client(client))) 179 - goto exit_kfree; 180 - 181 204 /* Detect the Vaio nature of EEPROMs. 182 205 We use the "PCG-" or "VGN-" prefix as the signature. */ 183 - if (address == 0x57 206 + if (client->addr == 0x57 184 207 && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { 185 208 char name[4]; 186 209 ··· 200 221 /* create the sysfs eeprom file */ 201 222 err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); 202 223 if (err) 203 - goto exit_detach; 224 + goto exit_kfree; 204 225 205 226 return 0; 206 227 207 - exit_detach: 208 - i2c_detach_client(client); 209 228 exit_kfree: 210 229 kfree(data); 211 230 exit: 212 231 return err; 213 232 } 214 233 215 - static int eeprom_detach_client(struct i2c_client *client) 234 + static int eeprom_remove(struct i2c_client *client) 216 235 { 217 - int err; 218 - 219 236 sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); 220 - 221 - err = i2c_detach_client(client); 222 - if (err) 223 - return err; 224 - 225 237 kfree(i2c_get_clientdata(client)); 226 238 227 239 return 0; 228 240 } 241 + 242 + static const struct i2c_device_id eeprom_id[] = { 243 + { "eeprom", 0 }, 244 + { } 245 + }; 246 + 247 + static struct i2c_driver eeprom_driver = { 248 + .driver = { 249 + .name = "eeprom", 250 + }, 251 + .probe = eeprom_probe, 252 + .remove = eeprom_remove, 253 + .id_table = eeprom_id, 254 + 255 + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, 256 + .detect = eeprom_detect, 257 + .address_data = &addr_data, 258 + }; 229 259 230 260 static int __init eeprom_init(void) 231 261 {