Message ID | 9f3c3d64b3fb327a4c235f182d46f8d6c6d0da15.1516812845.git.joseph.salisbury@canonical.com |
---|---|
State | New |
Headers | show |
Series | rfkill: Add rfkill-any LED trigger | expand |
On 02.02.2018 15:24, Joseph Salisbury wrote: > From: Michał Kępień <kernel@kempniu.pl> > > BugLink: http://bugs.launchpad.net/bugs/1745130 > > Add a new "global" (i.e. not per-rfkill device) LED trigger, rfkill-any, > which may be useful on laptops with a single "radio LED" and multiple > radio transmitters. The trigger is meant to turn a LED on whenever > there is at least one radio transmitter active and turn it off > otherwise. > > Signed-off-by: Michał Kępień <kernel@kempniu.pl> > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > (back ported from commit 9b8e34e211b15af429b72388a8f2b3b1823d172e) > Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- Strictly this is something that should be using the HWE kernel (maybe depends on how badly one thinks about a non-working LED for accumulated transmission activity). But since it is mostly "new driver" category and relatively contained I do not see real strong reasons to push against it. -Stefan > net/rfkill/core.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 72 insertions(+) > > diff --git a/net/rfkill/core.c b/net/rfkill/core.c > index cf5b69a..9e43ad9 100644 > --- a/net/rfkill/core.c > +++ b/net/rfkill/core.c > @@ -174,6 +174,50 @@ static void rfkill_led_trigger_unregister(struct rfkill *rfkill) > { > led_trigger_unregister(&rfkill->led_trigger); > } > + > +static struct led_trigger rfkill_any_led_trigger; > +static struct work_struct rfkill_any_work; > + > +static void rfkill_any_led_trigger_worker(struct work_struct *work) > +{ > + enum led_brightness brightness = LED_OFF; > + struct rfkill *rfkill; > + > + mutex_lock(&rfkill_global_mutex); > + list_for_each_entry(rfkill, &rfkill_list, node) { > + if (!(rfkill->state & RFKILL_BLOCK_ANY)) { > + brightness = LED_FULL; > + break; > + } > + } > + mutex_unlock(&rfkill_global_mutex); > + > + led_trigger_event(&rfkill_any_led_trigger, brightness); > +} > + > +static void rfkill_any_led_trigger_event(void) > +{ > + schedule_work(&rfkill_any_work); > +} > + > +static void rfkill_any_led_trigger_activate(struct led_classdev *led_cdev) > +{ > + rfkill_any_led_trigger_event(); > +} > + > +static int rfkill_any_led_trigger_register(void) > +{ > + INIT_WORK(&rfkill_any_work, rfkill_any_led_trigger_worker); > + rfkill_any_led_trigger.name = "rfkill-any"; > + rfkill_any_led_trigger.activate = rfkill_any_led_trigger_activate; > + return led_trigger_register(&rfkill_any_led_trigger); > +} > + > +static void rfkill_any_led_trigger_unregister(void) > +{ > + led_trigger_unregister(&rfkill_any_led_trigger); > + cancel_work_sync(&rfkill_any_work); > +} > #else > static void rfkill_led_trigger_event(struct rfkill *rfkill) > { > @@ -187,6 +231,19 @@ static inline int rfkill_led_trigger_register(struct rfkill *rfkill) > static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill) > { > } > + > +static void rfkill_any_led_trigger_event(void) > +{ > +} > + > +static int rfkill_any_led_trigger_register(void) > +{ > + return 0; > +} > + > +static void rfkill_any_led_trigger_unregister(void) > +{ > +} > #endif /* CONFIG_RFKILL_LEDS */ > > static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill, > @@ -318,6 +375,7 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) > spin_unlock_irqrestore(&rfkill->lock, flags); > > rfkill_led_trigger_event(rfkill); > + rfkill_any_led_trigger_event(); > > if (prev != curr) > rfkill_event(rfkill); > @@ -487,6 +545,8 @@ bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) > if (!rfkill->registered) > return ret; > > + rfkill_any_led_trigger_event(); > + > if (change) > schedule_work(&rfkill->uevent_work); > > @@ -529,6 +589,7 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) > schedule_work(&rfkill->uevent_work); > > rfkill_led_trigger_event(rfkill); > + rfkill_any_led_trigger_event(); > > return blocked; > } > @@ -578,6 +639,7 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) > schedule_work(&rfkill->uevent_work); > > rfkill_led_trigger_event(rfkill); > + rfkill_any_led_trigger_event(); > } > } > EXPORT_SYMBOL(rfkill_set_states); > @@ -989,6 +1051,7 @@ int __must_check rfkill_register(struct rfkill *rfkill) > #endif > } > > + rfkill_any_led_trigger_event(); > rfkill_send_events(rfkill, RFKILL_OP_ADD); > > mutex_unlock(&rfkill_global_mutex); > @@ -1021,6 +1084,7 @@ void rfkill_unregister(struct rfkill *rfkill) > mutex_lock(&rfkill_global_mutex); > rfkill_send_events(rfkill, RFKILL_OP_DEL); > list_del_init(&rfkill->node); > + rfkill_any_led_trigger_event(); > mutex_unlock(&rfkill_global_mutex); > > rfkill_led_trigger_unregister(rfkill); > @@ -1276,6 +1340,10 @@ static int __init rfkill_init(void) > goto out; > } > > + error = rfkill_any_led_trigger_register(); > + if (error) > + goto error_led_trigger; > + > #ifdef CONFIG_RFKILL_INPUT > error = rfkill_handler_init(); > if (error) { > @@ -1287,6 +1355,9 @@ static int __init rfkill_init(void) > > out: > return error; > + > +error_led_trigger: > + misc_deregister(&rfkill_miscdev); > } > subsys_initcall(rfkill_init); > > @@ -1295,6 +1366,7 @@ static void __exit rfkill_exit(void) > #ifdef CONFIG_RFKILL_INPUT > rfkill_handler_exit(); > #endif > + rfkill_any_led_trigger_unregister(); > misc_deregister(&rfkill_miscdev); > class_unregister(&rfkill_class); > } >
On 02/02/18 15:24, Joseph Salisbury wrote: > From: Michał Kępień <kernel@kempniu.pl> > > BugLink: http://bugs.launchpad.net/bugs/1745130 > > Add a new "global" (i.e. not per-rfkill device) LED trigger, rfkill-any, > which may be useful on laptops with a single "radio LED" and multiple > radio transmitters. The trigger is meant to turn a LED on whenever > there is at least one radio transmitter active and turn it off > otherwise. > > Signed-off-by: Michał Kępień <kernel@kempniu.pl> > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > (back ported from commit 9b8e34e211b15af429b72388a8f2b3b1823d172e) > Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com> Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> > --- > net/rfkill/core.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 72 insertions(+) > > diff --git a/net/rfkill/core.c b/net/rfkill/core.c > index cf5b69a..9e43ad9 100644 > --- a/net/rfkill/core.c > +++ b/net/rfkill/core.c > @@ -174,6 +174,50 @@ static void rfkill_led_trigger_unregister(struct rfkill *rfkill) > { > led_trigger_unregister(&rfkill->led_trigger); > } > + > +static struct led_trigger rfkill_any_led_trigger; > +static struct work_struct rfkill_any_work; > + > +static void rfkill_any_led_trigger_worker(struct work_struct *work) > +{ > + enum led_brightness brightness = LED_OFF; > + struct rfkill *rfkill; > + > + mutex_lock(&rfkill_global_mutex); > + list_for_each_entry(rfkill, &rfkill_list, node) { > + if (!(rfkill->state & RFKILL_BLOCK_ANY)) { > + brightness = LED_FULL; > + break; > + } > + } > + mutex_unlock(&rfkill_global_mutex); > + > + led_trigger_event(&rfkill_any_led_trigger, brightness); > +} > + > +static void rfkill_any_led_trigger_event(void) > +{ > + schedule_work(&rfkill_any_work); > +} > + > +static void rfkill_any_led_trigger_activate(struct led_classdev *led_cdev) > +{ > + rfkill_any_led_trigger_event(); > +} > + > +static int rfkill_any_led_trigger_register(void) > +{ > + INIT_WORK(&rfkill_any_work, rfkill_any_led_trigger_worker); > + rfkill_any_led_trigger.name = "rfkill-any"; > + rfkill_any_led_trigger.activate = rfkill_any_led_trigger_activate; > + return led_trigger_register(&rfkill_any_led_trigger); > +} > + > +static void rfkill_any_led_trigger_unregister(void) > +{ > + led_trigger_unregister(&rfkill_any_led_trigger); > + cancel_work_sync(&rfkill_any_work); > +} > #else > static void rfkill_led_trigger_event(struct rfkill *rfkill) > { > @@ -187,6 +231,19 @@ static inline int rfkill_led_trigger_register(struct rfkill *rfkill) > static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill) > { > } > + > +static void rfkill_any_led_trigger_event(void) > +{ > +} > + > +static int rfkill_any_led_trigger_register(void) > +{ > + return 0; > +} > + > +static void rfkill_any_led_trigger_unregister(void) > +{ > +} > #endif /* CONFIG_RFKILL_LEDS */ > > static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill, > @@ -318,6 +375,7 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) > spin_unlock_irqrestore(&rfkill->lock, flags); > > rfkill_led_trigger_event(rfkill); > + rfkill_any_led_trigger_event(); > > if (prev != curr) > rfkill_event(rfkill); > @@ -487,6 +545,8 @@ bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) > if (!rfkill->registered) > return ret; > > + rfkill_any_led_trigger_event(); > + > if (change) > schedule_work(&rfkill->uevent_work); > > @@ -529,6 +589,7 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) > schedule_work(&rfkill->uevent_work); > > rfkill_led_trigger_event(rfkill); > + rfkill_any_led_trigger_event(); > > return blocked; > } > @@ -578,6 +639,7 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) > schedule_work(&rfkill->uevent_work); > > rfkill_led_trigger_event(rfkill); > + rfkill_any_led_trigger_event(); > } > } > EXPORT_SYMBOL(rfkill_set_states); > @@ -989,6 +1051,7 @@ int __must_check rfkill_register(struct rfkill *rfkill) > #endif > } > > + rfkill_any_led_trigger_event(); > rfkill_send_events(rfkill, RFKILL_OP_ADD); > > mutex_unlock(&rfkill_global_mutex); > @@ -1021,6 +1084,7 @@ void rfkill_unregister(struct rfkill *rfkill) > mutex_lock(&rfkill_global_mutex); > rfkill_send_events(rfkill, RFKILL_OP_DEL); > list_del_init(&rfkill->node); > + rfkill_any_led_trigger_event(); > mutex_unlock(&rfkill_global_mutex); > > rfkill_led_trigger_unregister(rfkill); > @@ -1276,6 +1340,10 @@ static int __init rfkill_init(void) > goto out; > } > > + error = rfkill_any_led_trigger_register(); > + if (error) > + goto error_led_trigger; > + > #ifdef CONFIG_RFKILL_INPUT > error = rfkill_handler_init(); > if (error) { > @@ -1287,6 +1355,9 @@ static int __init rfkill_init(void) > > out: > return error; > + > +error_led_trigger: > + misc_deregister(&rfkill_miscdev); > } > subsys_initcall(rfkill_init); > > @@ -1295,6 +1366,7 @@ static void __exit rfkill_exit(void) > #ifdef CONFIG_RFKILL_INPUT > rfkill_handler_exit(); > #endif > + rfkill_any_led_trigger_unregister(); > misc_deregister(&rfkill_miscdev); > class_unregister(&rfkill_class); > } >
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index cf5b69a..9e43ad9 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -174,6 +174,50 @@ static void rfkill_led_trigger_unregister(struct rfkill *rfkill) { led_trigger_unregister(&rfkill->led_trigger); } + +static struct led_trigger rfkill_any_led_trigger; +static struct work_struct rfkill_any_work; + +static void rfkill_any_led_trigger_worker(struct work_struct *work) +{ + enum led_brightness brightness = LED_OFF; + struct rfkill *rfkill; + + mutex_lock(&rfkill_global_mutex); + list_for_each_entry(rfkill, &rfkill_list, node) { + if (!(rfkill->state & RFKILL_BLOCK_ANY)) { + brightness = LED_FULL; + break; + } + } + mutex_unlock(&rfkill_global_mutex); + + led_trigger_event(&rfkill_any_led_trigger, brightness); +} + +static void rfkill_any_led_trigger_event(void) +{ + schedule_work(&rfkill_any_work); +} + +static void rfkill_any_led_trigger_activate(struct led_classdev *led_cdev) +{ + rfkill_any_led_trigger_event(); +} + +static int rfkill_any_led_trigger_register(void) +{ + INIT_WORK(&rfkill_any_work, rfkill_any_led_trigger_worker); + rfkill_any_led_trigger.name = "rfkill-any"; + rfkill_any_led_trigger.activate = rfkill_any_led_trigger_activate; + return led_trigger_register(&rfkill_any_led_trigger); +} + +static void rfkill_any_led_trigger_unregister(void) +{ + led_trigger_unregister(&rfkill_any_led_trigger); + cancel_work_sync(&rfkill_any_work); +} #else static void rfkill_led_trigger_event(struct rfkill *rfkill) { @@ -187,6 +231,19 @@ static inline int rfkill_led_trigger_register(struct rfkill *rfkill) static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill) { } + +static void rfkill_any_led_trigger_event(void) +{ +} + +static int rfkill_any_led_trigger_register(void) +{ + return 0; +} + +static void rfkill_any_led_trigger_unregister(void) +{ +} #endif /* CONFIG_RFKILL_LEDS */ static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill, @@ -318,6 +375,7 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) spin_unlock_irqrestore(&rfkill->lock, flags); rfkill_led_trigger_event(rfkill); + rfkill_any_led_trigger_event(); if (prev != curr) rfkill_event(rfkill); @@ -487,6 +545,8 @@ bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) if (!rfkill->registered) return ret; + rfkill_any_led_trigger_event(); + if (change) schedule_work(&rfkill->uevent_work); @@ -529,6 +589,7 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) schedule_work(&rfkill->uevent_work); rfkill_led_trigger_event(rfkill); + rfkill_any_led_trigger_event(); return blocked; } @@ -578,6 +639,7 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) schedule_work(&rfkill->uevent_work); rfkill_led_trigger_event(rfkill); + rfkill_any_led_trigger_event(); } } EXPORT_SYMBOL(rfkill_set_states); @@ -989,6 +1051,7 @@ int __must_check rfkill_register(struct rfkill *rfkill) #endif } + rfkill_any_led_trigger_event(); rfkill_send_events(rfkill, RFKILL_OP_ADD); mutex_unlock(&rfkill_global_mutex); @@ -1021,6 +1084,7 @@ void rfkill_unregister(struct rfkill *rfkill) mutex_lock(&rfkill_global_mutex); rfkill_send_events(rfkill, RFKILL_OP_DEL); list_del_init(&rfkill->node); + rfkill_any_led_trigger_event(); mutex_unlock(&rfkill_global_mutex); rfkill_led_trigger_unregister(rfkill); @@ -1276,6 +1340,10 @@ static int __init rfkill_init(void) goto out; } + error = rfkill_any_led_trigger_register(); + if (error) + goto error_led_trigger; + #ifdef CONFIG_RFKILL_INPUT error = rfkill_handler_init(); if (error) { @@ -1287,6 +1355,9 @@ static int __init rfkill_init(void) out: return error; + +error_led_trigger: + misc_deregister(&rfkill_miscdev); } subsys_initcall(rfkill_init); @@ -1295,6 +1366,7 @@ static void __exit rfkill_exit(void) #ifdef CONFIG_RFKILL_INPUT rfkill_handler_exit(); #endif + rfkill_any_led_trigger_unregister(); misc_deregister(&rfkill_miscdev); class_unregister(&rfkill_class); }