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

leds: blinkm: Remove work queue

Now the core implements the work queue, remove it from the driver,
and switch to using brightness_set_blocking op.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Cc: Jan-Simon Moeller <dl9pf@gmx.de>
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>

authored by

Andrew Lunn and committed by
Jacek Anaszewski
7e1761b0 cd042f01

+17 -70
+17 -70
drivers/leds/leds-blinkm.c
··· 39 39 struct i2c_client *i2c_client; 40 40 struct led_classdev led_cdev; 41 41 int id; 42 - atomic_t active; 43 - }; 44 - 45 - struct blinkm_work { 46 - struct blinkm_led *blinkm_led; 47 - struct work_struct work; 48 42 }; 49 43 50 44 #define cdev_to_blmled(c) container_of(c, struct blinkm_led, led_cdev) 51 - #define work_to_blmwork(c) container_of(c, struct blinkm_work, work) 52 45 53 46 struct blinkm_data { 54 47 struct i2c_client *i2c_client; ··· 432 439 return 0; 433 440 } 434 441 435 - static void led_work(struct work_struct *work) 436 - { 437 - int ret; 438 - struct blinkm_led *led; 439 - struct blinkm_data *data; 440 - struct blinkm_work *blm_work = work_to_blmwork(work); 441 - 442 - led = blm_work->blinkm_led; 443 - data = i2c_get_clientdata(led->i2c_client); 444 - ret = blinkm_transfer_hw(led->i2c_client, BLM_GO_RGB); 445 - atomic_dec(&led->active); 446 - dev_dbg(&led->i2c_client->dev, 447 - "# DONE # next_red = %d, next_green = %d," 448 - " next_blue = %d, active = %d\n", 449 - data->next_red, data->next_green, 450 - data->next_blue, atomic_read(&led->active)); 451 - kfree(blm_work); 452 - } 453 - 454 442 static int blinkm_led_common_set(struct led_classdev *led_cdev, 455 443 enum led_brightness value, int color) 456 444 { 457 445 /* led_brightness is 0, 127 or 255 - we just use it here as-is */ 458 446 struct blinkm_led *led = cdev_to_blmled(led_cdev); 459 447 struct blinkm_data *data = i2c_get_clientdata(led->i2c_client); 460 - struct blinkm_work *bl_work; 461 448 462 449 switch (color) { 463 450 case RED: 464 451 /* bail out if there's no change */ 465 452 if (data->next_red == (u8) value) 466 - return 0; 467 - /* we assume a quite fast sequence here ([off]->on->off) 468 - * think of network led trigger - we cannot blink that fast, so 469 - * in case we already have a off->on->off transition queued up, 470 - * we refuse to queue up more. 471 - * Revisit: fast-changing brightness. */ 472 - if (atomic_read(&led->active) > 1) 473 453 return 0; 474 454 data->next_red = (u8) value; 475 455 break; ··· 450 484 /* bail out if there's no change */ 451 485 if (data->next_green == (u8) value) 452 486 return 0; 453 - /* we assume a quite fast sequence here ([off]->on->off) 454 - * Revisit: fast-changing brightness. */ 455 - if (atomic_read(&led->active) > 1) 456 - return 0; 457 487 data->next_green = (u8) value; 458 488 break; 459 489 case BLUE: 460 490 /* bail out if there's no change */ 461 491 if (data->next_blue == (u8) value) 462 - return 0; 463 - /* we assume a quite fast sequence here ([off]->on->off) 464 - * Revisit: fast-changing brightness. */ 465 - if (atomic_read(&led->active) > 1) 466 492 return 0; 467 493 data->next_blue = (u8) value; 468 494 break; ··· 464 506 return -EINVAL; 465 507 } 466 508 467 - bl_work = kzalloc(sizeof(*bl_work), GFP_ATOMIC); 468 - if (!bl_work) 469 - return -ENOMEM; 470 - 471 - atomic_inc(&led->active); 509 + blinkm_transfer_hw(led->i2c_client, BLM_GO_RGB); 472 510 dev_dbg(&led->i2c_client->dev, 473 - "#TO_SCHED# next_red = %d, next_green = %d," 474 - " next_blue = %d, active = %d\n", 511 + "# DONE # next_red = %d, next_green = %d," 512 + " next_blue = %d\n", 475 513 data->next_red, data->next_green, 476 - data->next_blue, atomic_read(&led->active)); 477 - 478 - /* a fresh work _item_ for each change */ 479 - bl_work->blinkm_led = led; 480 - INIT_WORK(&bl_work->work, led_work); 481 - /* queue work in own queue for easy sync on exit*/ 482 - schedule_work(&bl_work->work); 483 - 514 + data->next_blue); 484 515 return 0; 485 516 } 486 517 487 - static void blinkm_led_red_set(struct led_classdev *led_cdev, 518 + static int blinkm_led_red_set(struct led_classdev *led_cdev, 488 519 enum led_brightness value) 489 520 { 490 - blinkm_led_common_set(led_cdev, value, RED); 521 + return blinkm_led_common_set(led_cdev, value, RED); 491 522 } 492 523 493 - static void blinkm_led_green_set(struct led_classdev *led_cdev, 524 + static int blinkm_led_green_set(struct led_classdev *led_cdev, 494 525 enum led_brightness value) 495 526 { 496 - blinkm_led_common_set(led_cdev, value, GREEN); 527 + return blinkm_led_common_set(led_cdev, value, GREEN); 497 528 } 498 529 499 - static void blinkm_led_blue_set(struct led_classdev *led_cdev, 530 + static int blinkm_led_blue_set(struct led_classdev *led_cdev, 500 531 enum led_brightness value) 501 532 { 502 - blinkm_led_common_set(led_cdev, value, BLUE); 533 + return blinkm_led_common_set(led_cdev, value, BLUE); 503 534 } 504 535 505 536 static void blinkm_init_hw(struct i2c_client *client) ··· 616 669 led[i]->id = i; 617 670 led[i]->led_cdev.max_brightness = 255; 618 671 led[i]->led_cdev.flags = LED_CORE_SUSPENDRESUME; 619 - atomic_set(&led[i]->active, 0); 620 672 switch (i) { 621 673 case RED: 622 674 snprintf(blinkm_led_name, sizeof(blinkm_led_name), ··· 623 677 client->adapter->nr, 624 678 client->addr); 625 679 led[i]->led_cdev.name = blinkm_led_name; 626 - led[i]->led_cdev.brightness_set = blinkm_led_red_set; 680 + led[i]->led_cdev.brightness_set_blocking = 681 + blinkm_led_red_set; 627 682 err = led_classdev_register(&client->dev, 628 683 &led[i]->led_cdev); 629 684 if (err < 0) { ··· 640 693 client->adapter->nr, 641 694 client->addr); 642 695 led[i]->led_cdev.name = blinkm_led_name; 643 - led[i]->led_cdev.brightness_set = blinkm_led_green_set; 696 + led[i]->led_cdev.brightness_set_blocking = 697 + blinkm_led_green_set; 644 698 err = led_classdev_register(&client->dev, 645 699 &led[i]->led_cdev); 646 700 if (err < 0) { ··· 657 709 client->adapter->nr, 658 710 client->addr); 659 711 led[i]->led_cdev.name = blinkm_led_name; 660 - led[i]->led_cdev.brightness_set = blinkm_led_blue_set; 712 + led[i]->led_cdev.brightness_set_blocking = 713 + blinkm_led_blue_set; 661 714 err = led_classdev_register(&client->dev, 662 715 &led[i]->led_cdev); 663 716 if (err < 0) { ··· 695 746 int i; 696 747 697 748 /* make sure no workqueue entries are pending */ 698 - for (i = 0; i < 3; i++) { 699 - flush_scheduled_work(); 749 + for (i = 0; i < 3; i++) 700 750 led_classdev_unregister(&data->blinkm_leds[i].led_cdev); 701 - } 702 751 703 752 /* reset rgb */ 704 753 data->next_red = 0x00;