leds-pca955x: add proper error handling and fix bogus memory handling

Check the return value of led_classdev_register and unregister all
registered devices, if registering one device fails. Also the dynamic
memory handling is totally bogus. You can't allocate multiple chunks via
kzalloc() and expect them to be in order later. I wonder how this ever
worked.

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Acked-by: Nate Case <ncase@xes-inc.com>
Tested-by: Nate Case <ncase@xes-inc.com>
Acked-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Sven Wegener and committed by Linus Torvalds 95bf14bf 07f696c7

+39 -33
+39 -33
drivers/leds/leds-pca955x.c
··· 248 const struct i2c_device_id *id) 249 { 250 struct pca955x_led *pca955x; 251 - int i; 252 - int err = -ENODEV; 253 struct pca955x_chipdef *chip; 254 struct i2c_adapter *adapter; 255 struct led_platform_data *pdata; 256 257 chip = &pca955x_chipdefs[id->driver_data]; 258 adapter = to_i2c_adapter(client->dev.parent); ··· 281 } 282 } 283 284 - for (i = 0; i < chip->bits; i++) { 285 - pca955x = kzalloc(sizeof(struct pca955x_led), GFP_KERNEL); 286 - if (!pca955x) { 287 - err = -ENOMEM; 288 - goto exit; 289 - } 290 291 - pca955x->chipdef = chip; 292 - pca955x->client = client; 293 - pca955x->led_num = i; 294 /* Platform data can specify LED names and default triggers */ 295 if (pdata) { 296 if (pdata->leds[i].name) 297 - snprintf(pca955x->name, 32, "pca955x:%s", 298 - pdata->leds[i].name); 299 if (pdata->leds[i].default_trigger) 300 - pca955x->led_cdev.default_trigger = 301 pdata->leds[i].default_trigger; 302 } else { 303 - snprintf(pca955x->name, 32, "pca955x:%d", i); 304 } 305 - spin_lock_init(&pca955x->lock); 306 307 - pca955x->led_cdev.name = pca955x->name; 308 - pca955x->led_cdev.brightness_set = 309 - pca955x_led_set; 310 311 - /* 312 - * Client data is a pointer to the _first_ pca955x_led 313 - * struct 314 - */ 315 - if (i == 0) 316 - i2c_set_clientdata(client, pca955x); 317 318 - INIT_WORK(&(pca955x->work), pca955x_led_work); 319 320 - led_classdev_register(&client->dev, &(pca955x->led_cdev)); 321 } 322 323 /* Turn off LEDs */ ··· 333 pca955x_write_psc(client, 1, 0); 334 335 return 0; 336 exit: 337 return err; 338 } 339 340 static int __devexit pca955x_remove(struct i2c_client *client) 341 { 342 struct pca955x_led *pca955x = i2c_get_clientdata(client); 343 - int leds = pca955x->chipdef->bits; 344 int i; 345 346 - for (i = 0; i < leds; i++) { 347 - led_classdev_unregister(&(pca955x->led_cdev)); 348 - cancel_work_sync(&(pca955x->work)); 349 - kfree(pca955x); 350 - pca955x = pca955x + 1; 351 } 352 353 return 0; 354 }
··· 248 const struct i2c_device_id *id) 249 { 250 struct pca955x_led *pca955x; 251 struct pca955x_chipdef *chip; 252 struct i2c_adapter *adapter; 253 struct led_platform_data *pdata; 254 + int i, err; 255 256 chip = &pca955x_chipdefs[id->driver_data]; 257 adapter = to_i2c_adapter(client->dev.parent); ··· 282 } 283 } 284 285 + pca955x = kzalloc(sizeof(*pca955x) * chip->bits, GFP_KERNEL); 286 + if (!pca955x) 287 + return -ENOMEM; 288 289 + i2c_set_clientdata(client, pca955x); 290 + 291 + for (i = 0; i < chip->bits; i++) { 292 + pca955x[i].chipdef = chip; 293 + pca955x[i].client = client; 294 + pca955x[i].led_num = i; 295 + 296 /* Platform data can specify LED names and default triggers */ 297 if (pdata) { 298 if (pdata->leds[i].name) 299 + snprintf(pca955x[i].name, 300 + sizeof(pca955x[i].name), "pca955x:%s", 301 + pdata->leds[i].name); 302 if (pdata->leds[i].default_trigger) 303 + pca955x[i].led_cdev.default_trigger = 304 pdata->leds[i].default_trigger; 305 } else { 306 + snprintf(pca955x[i].name, sizeof(pca955x[i].name), 307 + "pca955x:%d", i); 308 } 309 310 + spin_lock_init(&pca955x[i].lock); 311 312 + pca955x[i].led_cdev.name = pca955x[i].name; 313 + pca955x[i].led_cdev.brightness_set = pca955x_led_set; 314 315 + INIT_WORK(&pca955x[i].work, pca955x_led_work); 316 317 + err = led_classdev_register(&client->dev, &pca955x[i].led_cdev); 318 + if (err < 0) 319 + goto exit; 320 } 321 322 /* Turn off LEDs */ ··· 336 pca955x_write_psc(client, 1, 0); 337 338 return 0; 339 + 340 exit: 341 + while (i--) { 342 + led_classdev_unregister(&pca955x[i].led_cdev); 343 + cancel_work_sync(&pca955x[i].work); 344 + } 345 + 346 + kfree(pca955x); 347 + i2c_set_clientdata(client, NULL); 348 + 349 return err; 350 } 351 352 static int __devexit pca955x_remove(struct i2c_client *client) 353 { 354 struct pca955x_led *pca955x = i2c_get_clientdata(client); 355 int i; 356 357 + for (i = 0; i < pca955x->chipdef->bits; i++) { 358 + led_classdev_unregister(&pca955x[i].led_cdev); 359 + cancel_work_sync(&pca955x[i].work); 360 } 361 + 362 + kfree(pca955x); 363 + i2c_set_clientdata(client, NULL); 364 365 return 0; 366 }