]> Git Repo - J-linux.git/commitdiff
Merge tag 'leds-next-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds
authorLinus Torvalds <[email protected]>
Wed, 17 Jan 2024 23:25:27 +0000 (15:25 -0800)
committerLinus Torvalds <[email protected]>
Wed, 17 Jan 2024 23:25:27 +0000 (15:25 -0800)
Pull LED updates from Lee Jones:
 "New Drivers:
   - Add support for Allwinner A100 RGB LED controller
   - Add support for Maxim 5970 Dual Hot-swap controller

  New Device Support:
   - Add support for AW20108 to Awinic LED driver

  New Functionality:
   - Extend support for Net speeds to include; 2.5G, 5G and 10G
   - Allow tx/rx and cts/dsr/dcd/rng TTY LEDS to be turned on and off
     via sysfs if required
   - Add support for hardware control in AW200xx

  Fix-ups:
   - Use safer methods for string handling
   - Improve error handling; return proper error values, simplify,
     avoid duplicates, etc
   - Replace Mutex use with the Completion mechanism
   - Fix include lists; alphabetise, remove unused, explicitly add used
   - Use generic platform device properties
   - Use/convert to new/better APIs/helpers/MACROs instead of
     hand-rolling implementations
   - Device Tree binding adaptions/conversions/creation
   - Continue work to remove superfluous platform .remove() call-backs
   - Remove superfluous/defunct code
   - Trivial; whitespace, unused variables, spelling, clean-ups, etc
   - Avoid unnecessary duplicate locks

  Bug Fixes:
   - Repair Kconfig based dependency lists
   - Ensure unused dynamically allocated data is freed after use
   - Fix support for brightness control
   - Add missing sufficient delays during reset to ensure correct
     operation
   - Avoid division-by-zero issues"

* tag 'leds-next-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (45 commits)
  leds: trigger: netdev: Add core support for hw not supporting fallback to LED sw control
  leds: trigger: panic: Don't register panic notifier if creating the trigger failed
  leds: sun50i-a100: Convert to be agnostic to property provider
  leds: max5970: Add missing headers
  leds: max5970: Make use of dev_err_probe()
  leds: max5970: Make use of device properties
  leds: max5970: Remove unused variable
  leds: rgb: Drop obsolete dependency on COMPILE_TEST
  leds: sun50i-a100: Avoid division-by-zero warning
  leds: trigger: Remove unused function led_trigger_rename_static()
  leds: qcom-lpg: Introduce a wrapper for getting driver data from a pwm chip
  leds: gpio: Add kernel log if devm_fwnode_gpiod_get() fails
  dt-bindings: leds: qcom,spmi-flash-led: Fix example node name
  dt-bindings: leds: aw200xx: Fix led pattern and add reg constraints
  dt-bindings: leds: awinic,aw200xx: Add AW20108 device
  leds: aw200xx: Add support for aw20108 device
  leds: aw200xx: Improve autodim calculation method
  leds: aw200xx: Enable disable_locking flag in regmap config
  leds: aw200xx: Add delay after software reset
  dt-bindings: leds: aw200xx: Remove property "awinic,display-rows"
  ...

1  2 
drivers/leds/trigger/ledtrig-netdev.c

index d76214fa9ad8645441e9c53814719ba0109f30ac,836610292b37d02f1c137340aab824fde9269def..8e5475819590e056142dae6ac1dd8c0dbe186d84
   * tx -  LED blinks on transmitted data
   * rx -  LED blinks on receive data
   *
+  * Note: If the user selects a mode that is not supported by hw, default
+  * behavior is to fall back to software control of the LED. However not every
+  * hw supports software control. LED callbacks brightness_set() and
+  * brightness_set_blocking() are NULL in this case. hw_control_is_supported()
+  * should use available means supported by hw to inform the user that selected
+  * mode isn't supported by hw. This could be switching off the LED or any
+  * hw blink mode. If software control fallback isn't possible, we return
+  * -EOPNOTSUPP to the user, but still store the selected mode. This is needed
+  * in case an intermediate unsupported mode is necessary to switch from one
+  * supported mode to another.
   */
  
  struct led_netdev_data {
@@@ -99,6 -109,18 +109,18 @@@ static void set_baseline_state(struct l
                    trigger_data->link_speed == SPEED_1000)
                        blink_on = true;
  
+               if (test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) &&
+                   trigger_data->link_speed == SPEED_2500)
+                       blink_on = true;
+               if (test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) &&
+                   trigger_data->link_speed == SPEED_5000)
+                       blink_on = true;
+               if (test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) &&
+                   trigger_data->link_speed == SPEED_10000)
+                       blink_on = true;
                if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
                    trigger_data->duplex == DUPLEX_HALF)
                        blink_on = true;
@@@ -226,11 -248,6 +248,11 @@@ static int set_device_name(struct led_n
  
        cancel_delayed_work_sync(&trigger_data->work);
  
 +      /*
 +       * Take RTNL lock before trigger_data lock to prevent potential
 +       * deadlock with netdev notifier registration.
 +       */
 +      rtnl_lock();
        mutex_lock(&trigger_data->lock);
  
        if (trigger_data->net_dev) {
        trigger_data->carrier_link_up = false;
        trigger_data->link_speed = SPEED_UNKNOWN;
        trigger_data->duplex = DUPLEX_UNKNOWN;
 -      if (trigger_data->net_dev != NULL) {
 -              rtnl_lock();
 +      if (trigger_data->net_dev)
                get_device_state(trigger_data);
 -              rtnl_unlock();
 -      }
  
        trigger_data->last_activity = 0;
  
        set_baseline_state(trigger_data);
        mutex_unlock(&trigger_data->lock);
 +      rtnl_unlock();
  
        return 0;
  }
@@@ -289,6 -308,9 +311,9 @@@ static ssize_t netdev_led_attr_show(str
        case TRIGGER_NETDEV_LINK_10:
        case TRIGGER_NETDEV_LINK_100:
        case TRIGGER_NETDEV_LINK_1000:
+       case TRIGGER_NETDEV_LINK_2500:
+       case TRIGGER_NETDEV_LINK_5000:
+       case TRIGGER_NETDEV_LINK_10000:
        case TRIGGER_NETDEV_HALF_DUPLEX:
        case TRIGGER_NETDEV_FULL_DUPLEX:
        case TRIGGER_NETDEV_TX:
@@@ -306,6 -328,7 +331,7 @@@ static ssize_t netdev_led_attr_store(st
                                     size_t size, enum led_trigger_netdev_modes attr)
  {
        struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
+       struct led_classdev *led_cdev = trigger_data->led_cdev;
        unsigned long state, mode = trigger_data->mode;
        int ret;
        int bit;
        case TRIGGER_NETDEV_LINK_10:
        case TRIGGER_NETDEV_LINK_100:
        case TRIGGER_NETDEV_LINK_1000:
+       case TRIGGER_NETDEV_LINK_2500:
+       case TRIGGER_NETDEV_LINK_5000:
+       case TRIGGER_NETDEV_LINK_10000:
        case TRIGGER_NETDEV_HALF_DUPLEX:
        case TRIGGER_NETDEV_FULL_DUPLEX:
        case TRIGGER_NETDEV_TX:
        if (test_bit(TRIGGER_NETDEV_LINK, &mode) &&
            (test_bit(TRIGGER_NETDEV_LINK_10, &mode) ||
             test_bit(TRIGGER_NETDEV_LINK_100, &mode) ||
-            test_bit(TRIGGER_NETDEV_LINK_1000, &mode)))
+            test_bit(TRIGGER_NETDEV_LINK_1000, &mode) ||
+            test_bit(TRIGGER_NETDEV_LINK_2500, &mode) ||
+            test_bit(TRIGGER_NETDEV_LINK_5000, &mode) ||
+            test_bit(TRIGGER_NETDEV_LINK_10000, &mode)))
                return -EINVAL;
  
        cancel_delayed_work_sync(&trigger_data->work);
        trigger_data->mode = mode;
        trigger_data->hw_control = can_hw_control(trigger_data);
  
+       if (!led_cdev->brightness_set && !led_cdev->brightness_set_blocking &&
+           !trigger_data->hw_control)
+               return -EOPNOTSUPP;
        set_baseline_state(trigger_data);
  
        return size;
@@@ -367,6 -400,9 +403,9 @@@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NET
  DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10);
  DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100);
  DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
+ DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500);
+ DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000);
+ DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000);
  DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
  DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
  DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
@@@ -425,6 -461,9 +464,9 @@@ static struct attribute *netdev_trig_at
        &dev_attr_link_10.attr,
        &dev_attr_link_100.attr,
        &dev_attr_link_1000.attr,
+       &dev_attr_link_2500.attr,
+       &dev_attr_link_5000.attr,
+       &dev_attr_link_10000.attr,
        &dev_attr_full_duplex.attr,
        &dev_attr_half_duplex.attr,
        &dev_attr_rx.attr,
@@@ -522,6 -561,9 +564,9 @@@ static void netdev_trig_work(struct wor
                         test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) ||
                         test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) ||
                         test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) ||
+                        test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) ||
+                        test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) ||
+                        test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) ||
                         test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
                         test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
                interval = jiffies_to_msecs(
This page took 0.07947 seconds and 4 git commands to generate.