<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/drivers/leds/led-class.c, branch v3.17</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>Revert "leds: convert blink timer to workqueue"</title>
<updated>2014-09-02T17:02:13+00:00</updated>
<author>
<name>Jiri Kosina</name>
<email>jkosina@suse.cz</email>
</author>
<published>2014-09-02T09:03:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9067359faf890b3a18ab38c792d458fba77b32b4'/>
<id>9067359faf890b3a18ab38c792d458fba77b32b4</id>
<content type='text'>
This reverts commit 8b37e1bef5a6b60e949e28a4db3006e4b00bd758.

It's broken as it changes led_blink_set() in a way that it can now sleep
(while synchronously waiting for workqueue to be cancelled). That's a
problem, because it's possible that this function gets called from atomic
context (tpt_trig_timer() takes a readlock and thus disables preemption).

This has been brought up 3 weeks ago already [1] but no proper fix has
materialized, and I keep seeing the problem since 3.17-rc1.

[1] https://lkml.org/lkml/2014/8/16/128

 BUG: sleeping function called from invalid context at kernel/workqueue.c:2650
 in_atomic(): 1, irqs_disabled(): 0, pid: 2335, name: wpa_supplicant
 5 locks held by wpa_supplicant/2335:
  #0:  (rtnl_mutex){+.+.+.}, at: [&lt;ffffffff814c7c92&gt;] rtnl_lock+0x12/0x20
  #1:  (&amp;wdev-&gt;mtx){+.+.+.}, at: [&lt;ffffffffc06e649c&gt;] cfg80211_mgd_wext_siwessid+0x5c/0x180 [cfg80211]
  #2:  (&amp;local-&gt;mtx){+.+.+.}, at: [&lt;ffffffffc0817dea&gt;] ieee80211_prep_connection+0x17a/0x9a0 [mac80211]
  #3:  (&amp;local-&gt;chanctx_mtx){+.+.+.}, at: [&lt;ffffffffc08081ed&gt;] ieee80211_vif_use_channel+0x5d/0x2a0 [mac80211]
  #4:  (&amp;trig-&gt;leddev_list_lock){.+.+..}, at: [&lt;ffffffffc081e68c&gt;] tpt_trig_timer+0xec/0x170 [mac80211]
 CPU: 0 PID: 2335 Comm: wpa_supplicant Not tainted 3.17.0-rc3 #1
 Hardware name: LENOVO 7470BN2/7470BN2, BIOS 6DET38WW (2.02 ) 12/19/2008
  ffff8800360b5a50 ffff8800751f76d8 ffffffff8159e97f ffff8800360b5a30
  ffff8800751f76e8 ffffffff810739a5 ffff8800751f77b0 ffffffff8106862f
  ffffffff810685d0 0aa2209200000000 ffff880000000004 ffff8800361c59d0
 Call Trace:
  [&lt;ffffffff8159e97f&gt;] dump_stack+0x4d/0x66
  [&lt;ffffffff810739a5&gt;] __might_sleep+0xe5/0x120
  [&lt;ffffffff8106862f&gt;] flush_work+0x5f/0x270
  [&lt;ffffffff810685d0&gt;] ? mod_delayed_work_on+0x80/0x80
  [&lt;ffffffff810945ca&gt;] ? mark_held_locks+0x6a/0x90
  [&lt;ffffffff81068a5f&gt;] ? __cancel_work_timer+0x6f/0x100
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff81068a6b&gt;] __cancel_work_timer+0x7b/0x100
  [&lt;ffffffff81068b0e&gt;] cancel_delayed_work_sync+0xe/0x10
  [&lt;ffffffff8147cf3b&gt;] led_blink_set+0x1b/0x40
  [&lt;ffffffffc081e6b0&gt;] tpt_trig_timer+0x110/0x170 [mac80211]
  [&lt;ffffffffc081ecdd&gt;] ieee80211_mod_tpt_led_trig+0x9d/0x160 [mac80211]
  [&lt;ffffffffc07e4278&gt;] __ieee80211_recalc_idle+0x98/0x140 [mac80211]
  [&lt;ffffffffc07e59ce&gt;] ieee80211_idle_off+0xe/0x10 [mac80211]
  [&lt;ffffffffc0804e5b&gt;] ieee80211_add_chanctx+0x3b/0x220 [mac80211]
  [&lt;ffffffffc08062e4&gt;] ieee80211_new_chanctx+0x44/0xf0 [mac80211]
  [&lt;ffffffffc080838a&gt;] ieee80211_vif_use_channel+0x1fa/0x2a0 [mac80211]
  [&lt;ffffffffc0817df8&gt;] ieee80211_prep_connection+0x188/0x9a0 [mac80211]
  [&lt;ffffffffc081c246&gt;] ieee80211_mgd_auth+0x256/0x2e0 [mac80211]
  [&lt;ffffffffc07eab33&gt;] ieee80211_auth+0x13/0x20 [mac80211]
  [&lt;ffffffffc06cb006&gt;] cfg80211_mlme_auth+0x106/0x270 [cfg80211]
  [&lt;ffffffffc06ce085&gt;] cfg80211_conn_do_work+0x155/0x3b0 [cfg80211]
  [&lt;ffffffffc06cf670&gt;] cfg80211_connect+0x3f0/0x540 [cfg80211]
  [&lt;ffffffffc06e6148&gt;] cfg80211_mgd_wext_connect+0x158/0x1f0 [cfg80211]
  [&lt;ffffffffc06e651e&gt;] cfg80211_mgd_wext_siwessid+0xde/0x180 [cfg80211]
  [&lt;ffffffffc06e36c0&gt;] ? cfg80211_wext_giwessid+0x50/0x50 [cfg80211]
  [&lt;ffffffffc06e36dd&gt;] cfg80211_wext_siwessid+0x1d/0x40 [cfg80211]
  [&lt;ffffffff81584d0c&gt;] ioctl_standard_iw_point+0x14c/0x3e0
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff8158502a&gt;] ioctl_standard_call+0x8a/0xd0
  [&lt;ffffffff81584fa0&gt;] ? ioctl_standard_iw_point+0x3e0/0x3e0
  [&lt;ffffffff81584b76&gt;] wireless_process_ioctl.constprop.10+0xb6/0x100
  [&lt;ffffffff8158521d&gt;] wext_handle_ioctl+0x5d/0xb0
  [&lt;ffffffff814cfb29&gt;] dev_ioctl+0x329/0x620
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff8149c7f2&gt;] sock_ioctl+0x142/0x2e0
  [&lt;ffffffff811b0140&gt;] do_vfs_ioctl+0x300/0x520
  [&lt;ffffffff815a67fb&gt;] ? sysret_check+0x1b/0x56
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff811b03e1&gt;] SyS_ioctl+0x81/0xa0
  [&lt;ffffffff815a67d6&gt;] system_call_fastpath+0x1a/0x1f
 wlan0: send auth to 00:0b:6b:3c:8c:e4 (try 1/3)
 wlan0: authenticated
 wlan0: associate with 00:0b:6b:3c:8c:e4 (try 1/3)
 wlan0: RX AssocResp from 00:0b:6b:3c:8c:e4 (capab=0x431 status=0 aid=2)
 wlan0: associated
 IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
 cfg80211: Calling CRDA for country: NA
 wlan0: Limiting TX power to 27 (27 - 0) dBm as advertised by 00:0b:6b:3c:8c:e4

 =================================
 [ INFO: inconsistent lock state ]
 3.17.0-rc3 #1 Not tainted
 ---------------------------------
 inconsistent {SOFTIRQ-ON-W} -&gt; {IN-SOFTIRQ-W} usage.
 swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
  ((&amp;(&amp;led_cdev-&gt;blink_work)-&gt;work)){+.?...}, at: [&lt;ffffffff810685d0&gt;] flush_work+0x0/0x270
 {SOFTIRQ-ON-W} state was registered at:
   [&lt;ffffffff81094dbe&gt;] __lock_acquire+0x30e/0x1a30
   [&lt;ffffffff81096c81&gt;] lock_acquire+0x91/0x110
   [&lt;ffffffff81068608&gt;] flush_work+0x38/0x270
   [&lt;ffffffff81068a6b&gt;] __cancel_work_timer+0x7b/0x100
   [&lt;ffffffff81068b0e&gt;] cancel_delayed_work_sync+0xe/0x10
   [&lt;ffffffff8147cf3b&gt;] led_blink_set+0x1b/0x40
   [&lt;ffffffffc081e6b0&gt;] tpt_trig_timer+0x110/0x170 [mac80211]
   [&lt;ffffffffc081ecdd&gt;] ieee80211_mod_tpt_led_trig+0x9d/0x160 [mac80211]
   [&lt;ffffffffc07e4278&gt;] __ieee80211_recalc_idle+0x98/0x140 [mac80211]
   [&lt;ffffffffc07e59ce&gt;] ieee80211_idle_off+0xe/0x10 [mac80211]
   [&lt;ffffffffc0804e5b&gt;] ieee80211_add_chanctx+0x3b/0x220 [mac80211]
   [&lt;ffffffffc08062e4&gt;] ieee80211_new_chanctx+0x44/0xf0 [mac80211]
   [&lt;ffffffffc080838a&gt;] ieee80211_vif_use_channel+0x1fa/0x2a0 [mac80211]
   [&lt;ffffffffc0817df8&gt;] ieee80211_prep_connection+0x188/0x9a0 [mac80211]
   [&lt;ffffffffc081c246&gt;] ieee80211_mgd_auth+0x256/0x2e0 [mac80211]
   [&lt;ffffffffc07eab33&gt;] ieee80211_auth+0x13/0x20 [mac80211]
   [&lt;ffffffffc06cb006&gt;] cfg80211_mlme_auth+0x106/0x270 [cfg80211]
   [&lt;ffffffffc06ce085&gt;] cfg80211_conn_do_work+0x155/0x3b0 [cfg80211]
   [&lt;ffffffffc06cf670&gt;] cfg80211_connect+0x3f0/0x540 [cfg80211]
   [&lt;ffffffffc06e6148&gt;] cfg80211_mgd_wext_connect+0x158/0x1f0 [cfg80211]
   [&lt;ffffffffc06e651e&gt;] cfg80211_mgd_wext_siwessid+0xde/0x180 [cfg80211]
   [&lt;ffffffffc06e36dd&gt;] cfg80211_wext_siwessid+0x1d/0x40 [cfg80211]
   [&lt;ffffffff81584d0c&gt;] ioctl_standard_iw_point+0x14c/0x3e0
   [&lt;ffffffff8158502a&gt;] ioctl_standard_call+0x8a/0xd0
   [&lt;ffffffff81584b76&gt;] wireless_process_ioctl.constprop.10+0xb6/0x100
   [&lt;ffffffff8158521d&gt;] wext_handle_ioctl+0x5d/0xb0
   [&lt;ffffffff814cfb29&gt;] dev_ioctl+0x329/0x620
   [&lt;ffffffff8149c7f2&gt;] sock_ioctl+0x142/0x2e0
   [&lt;ffffffff811b0140&gt;] do_vfs_ioctl+0x300/0x520
   [&lt;ffffffff811b03e1&gt;] SyS_ioctl+0x81/0xa0
   [&lt;ffffffff815a67d6&gt;] system_call_fastpath+0x1a/0x1f
 irq event stamp: 493416
 hardirqs last  enabled at (493416): [&lt;ffffffff81068a5f&gt;] __cancel_work_timer+0x6f/0x100
 hardirqs last disabled at (493415): [&lt;ffffffff81067e9f&gt;] try_to_grab_pending+0x1f/0x160
 softirqs last  enabled at (493408): [&lt;ffffffff81053ced&gt;] _local_bh_enable+0x1d/0x50
 softirqs last disabled at (493409): [&lt;ffffffff81054c75&gt;] irq_exit+0xa5/0xb0

 other info that might help us debug this:
  Possible unsafe locking scenario:

        CPU0
        ----
   lock((&amp;(&amp;led_cdev-&gt;blink_work)-&gt;work));
   &lt;Interrupt&gt;
     lock((&amp;(&amp;led_cdev-&gt;blink_work)-&gt;work));

  *** DEADLOCK ***

 2 locks held by swapper/0/0:
  #0:  (((&amp;tpt_trig-&gt;timer))){+.-...}, at: [&lt;ffffffff810b4c50&gt;] call_timer_fn+0x0/0x180
  #1:  (&amp;trig-&gt;leddev_list_lock){.+.?..}, at: [&lt;ffffffffc081e68c&gt;] tpt_trig_timer+0xec/0x170 [mac80211]

 stack backtrace:
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.17.0-rc3 #1
 Hardware name: LENOVO 7470BN2/7470BN2, BIOS 6DET38WW (2.02 ) 12/19/2008
  ffffffff8246eb30 ffff88007c203b00 ffffffff8159e97f ffffffff81a194c0
  ffff88007c203b50 ffffffff81599c29 0000000000000001 ffffffff00000001
  ffff880000000000 0000000000000006 ffffffff81a194c0 ffffffff81093ad0
 Call Trace:
  &lt;IRQ&gt;  [&lt;ffffffff8159e97f&gt;] dump_stack+0x4d/0x66
  [&lt;ffffffff81599c29&gt;] print_usage_bug+0x1f4/0x205
  [&lt;ffffffff81093ad0&gt;] ? check_usage_backwards+0x140/0x140
  [&lt;ffffffff810944d3&gt;] mark_lock+0x223/0x2b0
  [&lt;ffffffff81094d60&gt;] __lock_acquire+0x2b0/0x1a30
  [&lt;ffffffff81096c81&gt;] lock_acquire+0x91/0x110
  [&lt;ffffffff810685d0&gt;] ? mod_delayed_work_on+0x80/0x80
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff81068608&gt;] flush_work+0x38/0x270
  [&lt;ffffffff810685d0&gt;] ? mod_delayed_work_on+0x80/0x80
  [&lt;ffffffff810945ca&gt;] ? mark_held_locks+0x6a/0x90
  [&lt;ffffffff81068a5f&gt;] ? __cancel_work_timer+0x6f/0x100
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff8109469d&gt;] ? trace_hardirqs_on_caller+0xad/0x1c0
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff81068a6b&gt;] __cancel_work_timer+0x7b/0x100
  [&lt;ffffffff81068b0e&gt;] cancel_delayed_work_sync+0xe/0x10
  [&lt;ffffffff8147cf3b&gt;] led_blink_set+0x1b/0x40
  [&lt;ffffffffc081e6b0&gt;] tpt_trig_timer+0x110/0x170 [mac80211]
  [&lt;ffffffff810b4cc5&gt;] call_timer_fn+0x75/0x180
  [&lt;ffffffff810b4c50&gt;] ? process_timeout+0x10/0x10
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff810b50ac&gt;] run_timer_softirq+0x1fc/0x2f0
  [&lt;ffffffff81054805&gt;] __do_softirq+0x115/0x2e0
  [&lt;ffffffff81054c75&gt;] irq_exit+0xa5/0xb0
  [&lt;ffffffff810049b3&gt;] do_IRQ+0x53/0xf0
  [&lt;ffffffff815a74af&gt;] common_interrupt+0x6f/0x6f
  &lt;EOI&gt;  [&lt;ffffffff8147b56e&gt;] ? cpuidle_enter_state+0x6e/0x180
  [&lt;ffffffff8147b732&gt;] cpuidle_enter+0x12/0x20
  [&lt;ffffffff8108bba0&gt;] cpu_startup_entry+0x330/0x360
  [&lt;ffffffff8158fb51&gt;] rest_init+0xc1/0xd0
  [&lt;ffffffff8158fa90&gt;] ? csum_partial_copy_generic+0x170/0x170
  [&lt;ffffffff81af3ff2&gt;] start_kernel+0x44f/0x45a
  [&lt;ffffffff81af399c&gt;] ? set_init_arg+0x53/0x53
  [&lt;ffffffff81af35ad&gt;] x86_64_start_reservations+0x2a/0x2c
  [&lt;ffffffff81af36a0&gt;] x86_64_start_kernel+0xf1/0xf4

Cc: Vincent Donnefort &lt;vdonnefort@gmail.com&gt;
Cc: Hugh Dickins &lt;hughd@google.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Jiri Kosina &lt;jkosina@suse.cz&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 8b37e1bef5a6b60e949e28a4db3006e4b00bd758.

It's broken as it changes led_blink_set() in a way that it can now sleep
(while synchronously waiting for workqueue to be cancelled). That's a
problem, because it's possible that this function gets called from atomic
context (tpt_trig_timer() takes a readlock and thus disables preemption).

This has been brought up 3 weeks ago already [1] but no proper fix has
materialized, and I keep seeing the problem since 3.17-rc1.

[1] https://lkml.org/lkml/2014/8/16/128

 BUG: sleeping function called from invalid context at kernel/workqueue.c:2650
 in_atomic(): 1, irqs_disabled(): 0, pid: 2335, name: wpa_supplicant
 5 locks held by wpa_supplicant/2335:
  #0:  (rtnl_mutex){+.+.+.}, at: [&lt;ffffffff814c7c92&gt;] rtnl_lock+0x12/0x20
  #1:  (&amp;wdev-&gt;mtx){+.+.+.}, at: [&lt;ffffffffc06e649c&gt;] cfg80211_mgd_wext_siwessid+0x5c/0x180 [cfg80211]
  #2:  (&amp;local-&gt;mtx){+.+.+.}, at: [&lt;ffffffffc0817dea&gt;] ieee80211_prep_connection+0x17a/0x9a0 [mac80211]
  #3:  (&amp;local-&gt;chanctx_mtx){+.+.+.}, at: [&lt;ffffffffc08081ed&gt;] ieee80211_vif_use_channel+0x5d/0x2a0 [mac80211]
  #4:  (&amp;trig-&gt;leddev_list_lock){.+.+..}, at: [&lt;ffffffffc081e68c&gt;] tpt_trig_timer+0xec/0x170 [mac80211]
 CPU: 0 PID: 2335 Comm: wpa_supplicant Not tainted 3.17.0-rc3 #1
 Hardware name: LENOVO 7470BN2/7470BN2, BIOS 6DET38WW (2.02 ) 12/19/2008
  ffff8800360b5a50 ffff8800751f76d8 ffffffff8159e97f ffff8800360b5a30
  ffff8800751f76e8 ffffffff810739a5 ffff8800751f77b0 ffffffff8106862f
  ffffffff810685d0 0aa2209200000000 ffff880000000004 ffff8800361c59d0
 Call Trace:
  [&lt;ffffffff8159e97f&gt;] dump_stack+0x4d/0x66
  [&lt;ffffffff810739a5&gt;] __might_sleep+0xe5/0x120
  [&lt;ffffffff8106862f&gt;] flush_work+0x5f/0x270
  [&lt;ffffffff810685d0&gt;] ? mod_delayed_work_on+0x80/0x80
  [&lt;ffffffff810945ca&gt;] ? mark_held_locks+0x6a/0x90
  [&lt;ffffffff81068a5f&gt;] ? __cancel_work_timer+0x6f/0x100
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff81068a6b&gt;] __cancel_work_timer+0x7b/0x100
  [&lt;ffffffff81068b0e&gt;] cancel_delayed_work_sync+0xe/0x10
  [&lt;ffffffff8147cf3b&gt;] led_blink_set+0x1b/0x40
  [&lt;ffffffffc081e6b0&gt;] tpt_trig_timer+0x110/0x170 [mac80211]
  [&lt;ffffffffc081ecdd&gt;] ieee80211_mod_tpt_led_trig+0x9d/0x160 [mac80211]
  [&lt;ffffffffc07e4278&gt;] __ieee80211_recalc_idle+0x98/0x140 [mac80211]
  [&lt;ffffffffc07e59ce&gt;] ieee80211_idle_off+0xe/0x10 [mac80211]
  [&lt;ffffffffc0804e5b&gt;] ieee80211_add_chanctx+0x3b/0x220 [mac80211]
  [&lt;ffffffffc08062e4&gt;] ieee80211_new_chanctx+0x44/0xf0 [mac80211]
  [&lt;ffffffffc080838a&gt;] ieee80211_vif_use_channel+0x1fa/0x2a0 [mac80211]
  [&lt;ffffffffc0817df8&gt;] ieee80211_prep_connection+0x188/0x9a0 [mac80211]
  [&lt;ffffffffc081c246&gt;] ieee80211_mgd_auth+0x256/0x2e0 [mac80211]
  [&lt;ffffffffc07eab33&gt;] ieee80211_auth+0x13/0x20 [mac80211]
  [&lt;ffffffffc06cb006&gt;] cfg80211_mlme_auth+0x106/0x270 [cfg80211]
  [&lt;ffffffffc06ce085&gt;] cfg80211_conn_do_work+0x155/0x3b0 [cfg80211]
  [&lt;ffffffffc06cf670&gt;] cfg80211_connect+0x3f0/0x540 [cfg80211]
  [&lt;ffffffffc06e6148&gt;] cfg80211_mgd_wext_connect+0x158/0x1f0 [cfg80211]
  [&lt;ffffffffc06e651e&gt;] cfg80211_mgd_wext_siwessid+0xde/0x180 [cfg80211]
  [&lt;ffffffffc06e36c0&gt;] ? cfg80211_wext_giwessid+0x50/0x50 [cfg80211]
  [&lt;ffffffffc06e36dd&gt;] cfg80211_wext_siwessid+0x1d/0x40 [cfg80211]
  [&lt;ffffffff81584d0c&gt;] ioctl_standard_iw_point+0x14c/0x3e0
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff8158502a&gt;] ioctl_standard_call+0x8a/0xd0
  [&lt;ffffffff81584fa0&gt;] ? ioctl_standard_iw_point+0x3e0/0x3e0
  [&lt;ffffffff81584b76&gt;] wireless_process_ioctl.constprop.10+0xb6/0x100
  [&lt;ffffffff8158521d&gt;] wext_handle_ioctl+0x5d/0xb0
  [&lt;ffffffff814cfb29&gt;] dev_ioctl+0x329/0x620
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff8149c7f2&gt;] sock_ioctl+0x142/0x2e0
  [&lt;ffffffff811b0140&gt;] do_vfs_ioctl+0x300/0x520
  [&lt;ffffffff815a67fb&gt;] ? sysret_check+0x1b/0x56
  [&lt;ffffffff810946ed&gt;] ? trace_hardirqs_on_caller+0xfd/0x1c0
  [&lt;ffffffff811b03e1&gt;] SyS_ioctl+0x81/0xa0
  [&lt;ffffffff815a67d6&gt;] system_call_fastpath+0x1a/0x1f
 wlan0: send auth to 00:0b:6b:3c:8c:e4 (try 1/3)
 wlan0: authenticated
 wlan0: associate with 00:0b:6b:3c:8c:e4 (try 1/3)
 wlan0: RX AssocResp from 00:0b:6b:3c:8c:e4 (capab=0x431 status=0 aid=2)
 wlan0: associated
 IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
 cfg80211: Calling CRDA for country: NA
 wlan0: Limiting TX power to 27 (27 - 0) dBm as advertised by 00:0b:6b:3c:8c:e4

 =================================
 [ INFO: inconsistent lock state ]
 3.17.0-rc3 #1 Not tainted
 ---------------------------------
 inconsistent {SOFTIRQ-ON-W} -&gt; {IN-SOFTIRQ-W} usage.
 swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
  ((&amp;(&amp;led_cdev-&gt;blink_work)-&gt;work)){+.?...}, at: [&lt;ffffffff810685d0&gt;] flush_work+0x0/0x270
 {SOFTIRQ-ON-W} state was registered at:
   [&lt;ffffffff81094dbe&gt;] __lock_acquire+0x30e/0x1a30
   [&lt;ffffffff81096c81&gt;] lock_acquire+0x91/0x110
   [&lt;ffffffff81068608&gt;] flush_work+0x38/0x270
   [&lt;ffffffff81068a6b&gt;] __cancel_work_timer+0x7b/0x100
   [&lt;ffffffff81068b0e&gt;] cancel_delayed_work_sync+0xe/0x10
   [&lt;ffffffff8147cf3b&gt;] led_blink_set+0x1b/0x40
   [&lt;ffffffffc081e6b0&gt;] tpt_trig_timer+0x110/0x170 [mac80211]
   [&lt;ffffffffc081ecdd&gt;] ieee80211_mod_tpt_led_trig+0x9d/0x160 [mac80211]
   [&lt;ffffffffc07e4278&gt;] __ieee80211_recalc_idle+0x98/0x140 [mac80211]
   [&lt;ffffffffc07e59ce&gt;] ieee80211_idle_off+0xe/0x10 [mac80211]
   [&lt;ffffffffc0804e5b&gt;] ieee80211_add_chanctx+0x3b/0x220 [mac80211]
   [&lt;ffffffffc08062e4&gt;] ieee80211_new_chanctx+0x44/0xf0 [mac80211]
   [&lt;ffffffffc080838a&gt;] ieee80211_vif_use_channel+0x1fa/0x2a0 [mac80211]
   [&lt;ffffffffc0817df8&gt;] ieee80211_prep_connection+0x188/0x9a0 [mac80211]
   [&lt;ffffffffc081c246&gt;] ieee80211_mgd_auth+0x256/0x2e0 [mac80211]
   [&lt;ffffffffc07eab33&gt;] ieee80211_auth+0x13/0x20 [mac80211]
   [&lt;ffffffffc06cb006&gt;] cfg80211_mlme_auth+0x106/0x270 [cfg80211]
   [&lt;ffffffffc06ce085&gt;] cfg80211_conn_do_work+0x155/0x3b0 [cfg80211]
   [&lt;ffffffffc06cf670&gt;] cfg80211_connect+0x3f0/0x540 [cfg80211]
   [&lt;ffffffffc06e6148&gt;] cfg80211_mgd_wext_connect+0x158/0x1f0 [cfg80211]
   [&lt;ffffffffc06e651e&gt;] cfg80211_mgd_wext_siwessid+0xde/0x180 [cfg80211]
   [&lt;ffffffffc06e36dd&gt;] cfg80211_wext_siwessid+0x1d/0x40 [cfg80211]
   [&lt;ffffffff81584d0c&gt;] ioctl_standard_iw_point+0x14c/0x3e0
   [&lt;ffffffff8158502a&gt;] ioctl_standard_call+0x8a/0xd0
   [&lt;ffffffff81584b76&gt;] wireless_process_ioctl.constprop.10+0xb6/0x100
   [&lt;ffffffff8158521d&gt;] wext_handle_ioctl+0x5d/0xb0
   [&lt;ffffffff814cfb29&gt;] dev_ioctl+0x329/0x620
   [&lt;ffffffff8149c7f2&gt;] sock_ioctl+0x142/0x2e0
   [&lt;ffffffff811b0140&gt;] do_vfs_ioctl+0x300/0x520
   [&lt;ffffffff811b03e1&gt;] SyS_ioctl+0x81/0xa0
   [&lt;ffffffff815a67d6&gt;] system_call_fastpath+0x1a/0x1f
 irq event stamp: 493416
 hardirqs last  enabled at (493416): [&lt;ffffffff81068a5f&gt;] __cancel_work_timer+0x6f/0x100
 hardirqs last disabled at (493415): [&lt;ffffffff81067e9f&gt;] try_to_grab_pending+0x1f/0x160
 softirqs last  enabled at (493408): [&lt;ffffffff81053ced&gt;] _local_bh_enable+0x1d/0x50
 softirqs last disabled at (493409): [&lt;ffffffff81054c75&gt;] irq_exit+0xa5/0xb0

 other info that might help us debug this:
  Possible unsafe locking scenario:

        CPU0
        ----
   lock((&amp;(&amp;led_cdev-&gt;blink_work)-&gt;work));
   &lt;Interrupt&gt;
     lock((&amp;(&amp;led_cdev-&gt;blink_work)-&gt;work));

  *** DEADLOCK ***

 2 locks held by swapper/0/0:
  #0:  (((&amp;tpt_trig-&gt;timer))){+.-...}, at: [&lt;ffffffff810b4c50&gt;] call_timer_fn+0x0/0x180
  #1:  (&amp;trig-&gt;leddev_list_lock){.+.?..}, at: [&lt;ffffffffc081e68c&gt;] tpt_trig_timer+0xec/0x170 [mac80211]

 stack backtrace:
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.17.0-rc3 #1
 Hardware name: LENOVO 7470BN2/7470BN2, BIOS 6DET38WW (2.02 ) 12/19/2008
  ffffffff8246eb30 ffff88007c203b00 ffffffff8159e97f ffffffff81a194c0
  ffff88007c203b50 ffffffff81599c29 0000000000000001 ffffffff00000001
  ffff880000000000 0000000000000006 ffffffff81a194c0 ffffffff81093ad0
 Call Trace:
  &lt;IRQ&gt;  [&lt;ffffffff8159e97f&gt;] dump_stack+0x4d/0x66
  [&lt;ffffffff81599c29&gt;] print_usage_bug+0x1f4/0x205
  [&lt;ffffffff81093ad0&gt;] ? check_usage_backwards+0x140/0x140
  [&lt;ffffffff810944d3&gt;] mark_lock+0x223/0x2b0
  [&lt;ffffffff81094d60&gt;] __lock_acquire+0x2b0/0x1a30
  [&lt;ffffffff81096c81&gt;] lock_acquire+0x91/0x110
  [&lt;ffffffff810685d0&gt;] ? mod_delayed_work_on+0x80/0x80
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff81068608&gt;] flush_work+0x38/0x270
  [&lt;ffffffff810685d0&gt;] ? mod_delayed_work_on+0x80/0x80
  [&lt;ffffffff810945ca&gt;] ? mark_held_locks+0x6a/0x90
  [&lt;ffffffff81068a5f&gt;] ? __cancel_work_timer+0x6f/0x100
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff8109469d&gt;] ? trace_hardirqs_on_caller+0xad/0x1c0
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff81068a6b&gt;] __cancel_work_timer+0x7b/0x100
  [&lt;ffffffff81068b0e&gt;] cancel_delayed_work_sync+0xe/0x10
  [&lt;ffffffff8147cf3b&gt;] led_blink_set+0x1b/0x40
  [&lt;ffffffffc081e6b0&gt;] tpt_trig_timer+0x110/0x170 [mac80211]
  [&lt;ffffffff810b4cc5&gt;] call_timer_fn+0x75/0x180
  [&lt;ffffffff810b4c50&gt;] ? process_timeout+0x10/0x10
  [&lt;ffffffffc081e5a0&gt;] ? __ieee80211_get_rx_led_name+0x10/0x10 [mac80211]
  [&lt;ffffffff810b50ac&gt;] run_timer_softirq+0x1fc/0x2f0
  [&lt;ffffffff81054805&gt;] __do_softirq+0x115/0x2e0
  [&lt;ffffffff81054c75&gt;] irq_exit+0xa5/0xb0
  [&lt;ffffffff810049b3&gt;] do_IRQ+0x53/0xf0
  [&lt;ffffffff815a74af&gt;] common_interrupt+0x6f/0x6f
  &lt;EOI&gt;  [&lt;ffffffff8147b56e&gt;] ? cpuidle_enter_state+0x6e/0x180
  [&lt;ffffffff8147b732&gt;] cpuidle_enter+0x12/0x20
  [&lt;ffffffff8108bba0&gt;] cpu_startup_entry+0x330/0x360
  [&lt;ffffffff8158fb51&gt;] rest_init+0xc1/0xd0
  [&lt;ffffffff8158fa90&gt;] ? csum_partial_copy_generic+0x170/0x170
  [&lt;ffffffff81af3ff2&gt;] start_kernel+0x44f/0x45a
  [&lt;ffffffff81af399c&gt;] ? set_init_arg+0x53/0x53
  [&lt;ffffffff81af35ad&gt;] x86_64_start_reservations+0x2a/0x2c
  [&lt;ffffffff81af36a0&gt;] x86_64_start_kernel+0xf1/0xf4

Cc: Vincent Donnefort &lt;vdonnefort@gmail.com&gt;
Cc: Hugh Dickins &lt;hughd@google.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Jiri Kosina &lt;jkosina@suse.cz&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: convert blink timer to workqueue</title>
<updated>2014-07-03T19:02:14+00:00</updated>
<author>
<name>Vincent Donnefort</name>
<email>vdonnefort@gmail.com</email>
</author>
<published>2014-06-14T09:21:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=8b37e1bef5a6b60e949e28a4db3006e4b00bd758'/>
<id>8b37e1bef5a6b60e949e28a4db3006e4b00bd758</id>
<content type='text'>
This patch converts the blink timer from led-core to workqueue which is more
suitable for this kind of non-priority operations. Moreover, timer may lead to
errors when a LED setting function use a scheduling function such as pinctrl
which is using mutex.

Signed-off-by: Vincent Donnefort &lt;vdonnefort@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch converts the blink timer from led-core to workqueue which is more
suitable for this kind of non-priority operations. Moreover, timer may lead to
errors when a LED setting function use a scheduling function such as pinctrl
which is using mutex.

Signed-off-by: Vincent Donnefort &lt;vdonnefort@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: add led-class attribute-group support</title>
<updated>2014-06-25T21:55:03+00:00</updated>
<author>
<name>Johan Hovold</name>
<email>johan@kernel.org</email>
</author>
<published>2014-06-25T17:08:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d0d480cce8f522b37c2c1de38230fc9ad15fa506'/>
<id>d0d480cce8f522b37c2c1de38230fc9ad15fa506</id>
<content type='text'>
Allow led-class devices to be created with optional attribute groups.

This is needed in order to allow led drivers to create custom device
attributes in a race-free manner.

Signed-off-by: Johan Hovold &lt;johan@kernel.org&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Allow led-class devices to be created with optional attribute groups.

This is needed in order to allow led drivers to create custom device
attributes in a race-free manner.

Signed-off-by: Johan Hovold &lt;johan@kernel.org&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: convert class code to use dev_groups</title>
<updated>2013-07-27T01:05:17+00:00</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>gregkh@linuxfoundation.org</email>
</author>
<published>2013-07-24T22:05:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=5baa7503a7a0b8d65308ff3b2ab887bf343c65d3'/>
<id>5baa7503a7a0b8d65308ff3b2ab887bf343c65d3</id>
<content type='text'>
The dev_attrs field of struct class is going away soon, dev_groups
should be used instead.  This converts the led class code to use the
correct field.

Acked-by: Bryan Wu &lt;cooloney@gmail.com&gt;
Cc: Richard Purdie &lt;rpurdie@rpsys.net&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The dev_attrs field of struct class is going away soon, dev_groups
should be used instead.  This converts the led class code to use the
correct field.

Acked-by: Bryan Wu &lt;cooloney@gmail.com&gt;
Cc: Richard Purdie &lt;rpurdie@rpsys.net&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: Convert led class driver from legacy pm ops to dev_pm_ops</title>
<updated>2013-06-21T00:36:45+00:00</updated>
<author>
<name>Shuah Khan</name>
<email>shuah.kh@samsung.com</email>
</author>
<published>2013-06-20T19:08:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=73e1ab41a80d36207e8ea7cc2c9897afdeeef387'/>
<id>73e1ab41a80d36207e8ea7cc2c9897afdeeef387</id>
<content type='text'>
Convert drivers/leds/led-class to use dev_pm_ops for power management and
remove Legacy PM ops hooks. With this change, led class registers
suspend/resume callbacks via class-&gt;pm (dev_pm_ops) instead of Legacy
class-&gt;suspend/resume. When __device_suspend() runs call-backs, it will
find class-&gt;pm ops for the led class.

Signed-off-by: Shuah Khan &lt;shuah.kh@samsung.com&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Convert drivers/leds/led-class to use dev_pm_ops for power management and
remove Legacy PM ops hooks. With this change, led class registers
suspend/resume callbacks via class-&gt;pm (dev_pm_ops) instead of Legacy
class-&gt;suspend/resume. When __device_suspend() runs call-backs, it will
find class-&gt;pm ops for the led class.

Signed-off-by: Shuah Khan &lt;shuah.kh@samsung.com&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: led-class: Fix checkpatch warning</title>
<updated>2012-11-27T22:49:25+00:00</updated>
<author>
<name>Sachin Kamat</name>
<email>sachin.kamat@linaro.org</email>
</author>
<published>2012-11-25T05:27:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d23e7b8b61d012e8a86097c5c6f411ede04ca955'/>
<id>d23e7b8b61d012e8a86097c5c6f411ede04ca955</id>
<content type='text'>
Fixes the following checkpatch warning:
WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(...  to printk(KERN_DEBUG ...
FILE: leds/led-class.c:214:
	printk(KERN_DEBUG "Registered led device: %s\n",

Signed-off-by: Sachin Kamat &lt;sachin.kamat@linaro.org&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes the following checkpatch warning:
WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(...  to printk(KERN_DEBUG ...
FILE: leds/led-class.c:214:
	printk(KERN_DEBUG "Registered led device: %s\n",

Signed-off-by: Sachin Kamat &lt;sachin.kamat@linaro.org&gt;
Signed-off-by: Bryan Wu &lt;cooloney@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: delay led_set_brightness if stopping soft-blink</title>
<updated>2012-09-11T10:32:40+00:00</updated>
<author>
<name>Fabio Baltieri</name>
<email>fabio.baltieri@gmail.com</email>
</author>
<published>2012-08-15T13:44:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d23a22a74fded23a12434c9463fe66cec2b0afcd'/>
<id>d23a22a74fded23a12434c9463fe66cec2b0afcd</id>
<content type='text'>
Delay execution of led_set_brightness() if need to stop soft-blink
timer.

This allows led_set_brightness to be called in hard-irq context even if
soft-blink was activated on that LED.

Signed-off-by: Fabio Baltieri &lt;fabio.baltieri@gmail.com&gt;
Cc: Pawel Moll &lt;pawel.moll@arm.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Delay execution of led_set_brightness() if need to stop soft-blink
timer.

This allows led_set_brightness to be called in hard-irq context even if
soft-blink was activated on that LED.

Signed-off-by: Fabio Baltieri &lt;fabio.baltieri@gmail.com&gt;
Cc: Pawel Moll &lt;pawel.moll@arm.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: Rename led_brightness_set() to led_set_brightness()</title>
<updated>2012-07-23T23:52:34+00:00</updated>
<author>
<name>Shuah Khan</name>
<email>shuahkhan@gmail.com</email>
</author>
<published>2012-06-13T20:34:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=19cd67e2d51225b164560b54b85f943e07deee8a'/>
<id>19cd67e2d51225b164560b54b85f943e07deee8a</id>
<content type='text'>
Rename leds external interface led_brightness_set() to led_set_brightness().
This is the second phase of the change to reduce confusion between the
leds internal and external interfaces that set brightness. With this change,
now the external interface is led_set_brightness(). The first phase renamed
the internal interface led_set_brightness() to __led_set_brightness().
There are no changes to the interface implementations.

Signed-off-by: Shuah Khan &lt;shuahkhan@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rename leds external interface led_brightness_set() to led_set_brightness().
This is the second phase of the change to reduce confusion between the
leds internal and external interfaces that set brightness. With this change,
now the external interface is led_set_brightness(). The first phase renamed
the internal interface led_set_brightness() to __led_set_brightness().
There are no changes to the interface implementations.

Signed-off-by: Shuah Khan &lt;shuahkhan@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: Rename led_set_brightness() to __led_set_brightness()</title>
<updated>2012-07-23T23:52:34+00:00</updated>
<author>
<name>Shuah Khan</name>
<email>shuahkhan@gmail.com</email>
</author>
<published>2012-06-13T02:01:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=0da3e65ba892b8c63d55fa5ec197b6fae55f75f8'/>
<id>0da3e65ba892b8c63d55fa5ec197b6fae55f75f8</id>
<content type='text'>
Rename leds internal interface led_set_brightness() to __led_set_brightness()
to reduce confusion between led_set_brightness() and the external interface
led_brightness_set(). led_brightness_set() cancels the timer and then calls
led_set_brightness().

Signed-off-by: Shuah Khan &lt;shuahkhan@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rename leds internal interface led_set_brightness() to __led_set_brightness()
to reduce confusion between led_set_brightness() and the external interface
led_brightness_set(). led_brightness_set() cancels the timer and then calls
led_set_brightness().

Signed-off-by: Shuah Khan &lt;shuahkhan@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>leds: add oneshot blink functions</title>
<updated>2012-07-23T23:52:34+00:00</updated>
<author>
<name>Fabio Baltieri</name>
<email>fabio.baltieri@gmail.com</email>
</author>
<published>2012-05-26T23:19:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=5bb629c504394f4d42c53a25d75ccb02a393f92f'/>
<id>5bb629c504394f4d42c53a25d75ccb02a393f92f</id>
<content type='text'>
Add two new functions, led_blink_set_oneshot and
led_trigger_blink_oneshot, to be used by triggers for one-shot blink of
led devices.

This is implemented extending the existing software-blink code, and uses
the same timer and handler function.

The behavior of the code is to do a blink-on, blink-off sequence when
the function is called, ignoring other calls until the sequence is
completed so that the leds keep blinking at constant rate if the
functions are called repeatedly.

This is meant to be used by drivers which needs to trigger on sporadic
event, but doesn't have clear busy/idle trigger points.

After the blink sequence the led remains off. This behavior can be
inverted setting the "invert" argument, which blink the led off, than on
and leave the led on after the sequence.

(bryan.wu@canonical.com: rebase to commit 'leds: don't disable blinking
when writing the same value to delay_on or delay_off')

Signed-off-by: Fabio Baltieri &lt;fabio.baltieri@gmail.com&gt;
Acked-by: Shuah Khan &lt;shuahkhan@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add two new functions, led_blink_set_oneshot and
led_trigger_blink_oneshot, to be used by triggers for one-shot blink of
led devices.

This is implemented extending the existing software-blink code, and uses
the same timer and handler function.

The behavior of the code is to do a blink-on, blink-off sequence when
the function is called, ignoring other calls until the sequence is
completed so that the leds keep blinking at constant rate if the
functions are called repeatedly.

This is meant to be used by drivers which needs to trigger on sporadic
event, but doesn't have clear busy/idle trigger points.

After the blink sequence the led remains off. This behavior can be
inverted setting the "invert" argument, which blink the led off, than on
and leave the led on after the sequence.

(bryan.wu@canonical.com: rebase to commit 'leds: don't disable blinking
when writing the same value to delay_on or delay_off')

Signed-off-by: Fabio Baltieri &lt;fabio.baltieri@gmail.com&gt;
Acked-by: Shuah Khan &lt;shuahkhan@gmail.com&gt;
Signed-off-by: Bryan Wu &lt;bryan.wu@canonical.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
