-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Zach Brown says: ==================== Add support for led triggers on phy link state change Fix skge driver that declared enum contants that conflicted with enum constants in linux/leds.h Create function that encapsulates actions taken during the adjust phy link step of phy state changes. Create function that provides list of speeds currently supported by the phy. Add support for led triggers on phy link state changes by adding a config option. When set the config option will create a set of led triggers for each phy device. Users can use the led triggers to represent link state changes on the phy. v2: * New patch that creates phy_adjust_link function to encapsulate actions taken when adjusting phy link during phy state changes * led trigger speed strings changed to match existing phy speed strings * New function that maps speeds to led triggers * Replace magic constants with definitions when declaring trigger name buffer and number of triggers. v3: * Changed LED_ON to LED_REG_ON in skge driver to avoid possible future conflict and improve consistency. * Dropped rtl8712 patch that was accepted separately. v4: * tweaked commit message v5 * Changed commit message to explain relationship between the new triggers and leds driven by phys. * Added new patch that creates phy_supported_speeds function. * Moved phy_leds_triggers_register and phy_leds_triggers_unregister to phy_attach and phy_detach respectively. This change is so the phydev->supported field will be filled by the time the triggers are registered. * Changed hardcoded list of triggers to dynamic list determined by speeds return by phy_supported_speeds. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Showing
9 changed files
with
282 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* Copyright (C) 2016 National Instruments Corp. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
#include <linux/leds.h> | ||
#include <linux/phy.h> | ||
#include <linux/netdevice.h> | ||
|
||
static struct phy_led_trigger *phy_speed_to_led_trigger(struct phy_device *phy, | ||
unsigned int speed) | ||
{ | ||
unsigned int i; | ||
|
||
for (i = 0; i < phy->phy_num_led_triggers; i++) { | ||
if (phy->phy_led_triggers[i].speed == speed) | ||
return &phy->phy_led_triggers[i]; | ||
} | ||
return NULL; | ||
} | ||
|
||
void phy_led_trigger_change_speed(struct phy_device *phy) | ||
{ | ||
struct phy_led_trigger *plt; | ||
|
||
if (!phy->link) | ||
goto out_change_speed; | ||
|
||
if (phy->speed == 0) | ||
return; | ||
|
||
plt = phy_speed_to_led_trigger(phy, phy->speed); | ||
if (!plt) { | ||
netdev_alert(phy->attached_dev, | ||
"No phy led trigger registered for speed(%d)\n", | ||
phy->speed); | ||
goto out_change_speed; | ||
} | ||
|
||
if (plt != phy->last_triggered) { | ||
led_trigger_event(&phy->last_triggered->trigger, LED_OFF); | ||
led_trigger_event(&plt->trigger, LED_FULL); | ||
phy->last_triggered = plt; | ||
} | ||
return; | ||
|
||
out_change_speed: | ||
if (phy->last_triggered) { | ||
led_trigger_event(&phy->last_triggered->trigger, | ||
LED_OFF); | ||
phy->last_triggered = NULL; | ||
} | ||
} | ||
EXPORT_SYMBOL_GPL(phy_led_trigger_change_speed); | ||
|
||
static int phy_led_trigger_register(struct phy_device *phy, | ||
struct phy_led_trigger *plt, | ||
unsigned int speed) | ||
{ | ||
char name_suffix[PHY_LED_TRIGGER_SPEED_SUFFIX_SIZE]; | ||
|
||
plt->speed = speed; | ||
|
||
if (speed < SPEED_1000) | ||
snprintf(name_suffix, sizeof(name_suffix), "%dMbps", speed); | ||
else if (speed == SPEED_2500) | ||
snprintf(name_suffix, sizeof(name_suffix), "2.5Gbps"); | ||
else | ||
snprintf(name_suffix, sizeof(name_suffix), "%dGbps", | ||
DIV_ROUND_CLOSEST(speed, 1000)); | ||
|
||
snprintf(plt->name, sizeof(plt->name), PHY_ID_FMT ":%s", | ||
phy->mdio.bus->id, phy->mdio.addr, name_suffix); | ||
plt->trigger.name = plt->name; | ||
|
||
return led_trigger_register(&plt->trigger); | ||
} | ||
|
||
static void phy_led_trigger_unregister(struct phy_led_trigger *plt) | ||
{ | ||
led_trigger_unregister(&plt->trigger); | ||
} | ||
|
||
int phy_led_triggers_register(struct phy_device *phy) | ||
{ | ||
int i, err; | ||
unsigned int speeds[50]; | ||
|
||
phy->phy_num_led_triggers = phy_supported_speeds(phy, speeds, | ||
ARRAY_SIZE(speeds)); | ||
if (!phy->phy_num_led_triggers) | ||
return 0; | ||
|
||
phy->phy_led_triggers = devm_kzalloc(&phy->mdio.dev, | ||
sizeof(struct phy_led_trigger) * | ||
phy->phy_num_led_triggers, | ||
GFP_KERNEL); | ||
if (!phy->phy_led_triggers) | ||
return -ENOMEM; | ||
|
||
for (i = 0; i < phy->phy_num_led_triggers; i++) { | ||
err = phy_led_trigger_register(phy, &phy->phy_led_triggers[i], | ||
speeds[i]); | ||
if (err) | ||
goto out_unreg; | ||
} | ||
|
||
phy->last_triggered = NULL; | ||
phy_led_trigger_change_speed(phy); | ||
|
||
return 0; | ||
out_unreg: | ||
while (i--) | ||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]); | ||
devm_kfree(&phy->mdio.dev, phy->phy_led_triggers); | ||
return err; | ||
} | ||
EXPORT_SYMBOL_GPL(phy_led_triggers_register); | ||
|
||
void phy_led_triggers_unregister(struct phy_device *phy) | ||
{ | ||
int i; | ||
|
||
for (i = 0; i < phy->phy_num_led_triggers; i++) | ||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]); | ||
|
||
devm_kfree(&phy->mdio.dev, phy->phy_led_triggers); | ||
} | ||
EXPORT_SYMBOL_GPL(phy_led_triggers_unregister); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.