bbc_envctrl: Clean up properly if kthread_run() fails.

In bbc_envctrl_init() we have to unlink the fan and temp instances
from the lists because our caller is going to free up the 'bp' object
if we return an error.

We can't rely upon bbc_envctrl_cleanup() to do this work for us in
this case.

Reported-by: Patrick Finnegan <pat@computer-refuge.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

+38 -26
+38 -26
drivers/sbus/char/bbc_envctrl.c
··· 522 set_fan_speeds(fp); 523 } 524 525 int bbc_envctrl_init(struct bbc_i2c_bus *bp) 526 { 527 struct of_device *op; ··· 575 int err = PTR_ERR(kenvctrld_task); 576 577 kenvctrld_task = NULL; 578 return err; 579 } 580 } ··· 584 return 0; 585 } 586 587 - static void destroy_one_temp(struct bbc_cpu_temperature *tp) 588 - { 589 - bbc_i2c_detach(tp->client); 590 - kfree(tp); 591 - } 592 - 593 - static void destroy_one_fan(struct bbc_fan_control *fp) 594 - { 595 - bbc_i2c_detach(fp->client); 596 - kfree(fp); 597 - } 598 - 599 void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp) 600 { 601 - struct bbc_cpu_temperature *tp, *tpos; 602 - struct bbc_fan_control *fp, *fpos; 603 - 604 if (kenvctrld_task) 605 kthread_stop(kenvctrld_task); 606 607 - list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { 608 - list_del(&tp->bp_list); 609 - list_del(&tp->glob_list); 610 - destroy_one_temp(tp); 611 - } 612 - 613 - list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) { 614 - list_del(&fp->bp_list); 615 - list_del(&fp->glob_list); 616 - destroy_one_fan(fp); 617 - } 618 }
··· 522 set_fan_speeds(fp); 523 } 524 525 + static void destroy_one_temp(struct bbc_cpu_temperature *tp) 526 + { 527 + bbc_i2c_detach(tp->client); 528 + kfree(tp); 529 + } 530 + 531 + static void destroy_all_temps(struct bbc_i2c_bus *bp) 532 + { 533 + struct bbc_cpu_temperature *tp, *tpos; 534 + 535 + list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { 536 + list_del(&tp->bp_list); 537 + list_del(&tp->glob_list); 538 + destroy_one_temp(tp); 539 + } 540 + } 541 + 542 + static void destroy_one_fan(struct bbc_fan_control *fp) 543 + { 544 + bbc_i2c_detach(fp->client); 545 + kfree(fp); 546 + } 547 + 548 + static void destroy_all_fans(struct bbc_i2c_bus *bp) 549 + { 550 + struct bbc_fan_control *fp, *fpos; 551 + 552 + list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) { 553 + list_del(&fp->bp_list); 554 + list_del(&fp->glob_list); 555 + destroy_one_fan(fp); 556 + } 557 + } 558 + 559 int bbc_envctrl_init(struct bbc_i2c_bus *bp) 560 { 561 struct of_device *op; ··· 541 int err = PTR_ERR(kenvctrld_task); 542 543 kenvctrld_task = NULL; 544 + destroy_all_temps(bp); 545 + destroy_all_fans(bp); 546 return err; 547 } 548 } ··· 548 return 0; 549 } 550 551 void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp) 552 { 553 if (kenvctrld_task) 554 kthread_stop(kenvctrld_task); 555 556 + destroy_all_temps(bp); 557 + destroy_all_fans(bp); 558 }