Commit c156d4af authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'leds-next-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds

Pull LED updates from Lee Jones:
 "New Drivers:
   - Add support for Intel Cherry Trail Whiskey Cove PMIC LEDs
   - Add support for Awinic AW20036/AW20054/AW20072 LEDs

  New Device Support:
   - Add support for PMI632 LPG to QCom LPG
   - Add support for PMI8998 to QCom Flash
   - Add support for MT6331, WLEDs and MT6332 to Mediatek MT6323 PMIC

  New Functionality:
   - Implement the LP55xx Charge Pump
   - Add support for suspend / resume to Intel Cherry Trail Whiskey Cove PMIC
   - Add support for breathing mode to Intel Cherry Trail Whiskey Cove PMIC
   - Enable per-pin resolution Pinctrl in LEDs GPIO

  Fix-ups:
   - Allow thread to sleep by switching from spinlock to mutex
   - Add lots of Device Tree bindings / support
   - Adapt relationships / dependencies driven by Kconfig
   - Switch I2C drivers from .probe_new() to .probe()
   - Remove superfluous / duplicate code
   - Replace strlcpy() with strscpy() for efficiency and overflow prevention
   - Staticify various functions
   - Trivial: Fixing coding style
   - Simplify / reduce code

  Bug Fixes:
   - Prevent NETDEV_LED_MODE_LINKUP from being cleared on rename
   - Repair race between led_set_brightness(LED_{OFF,FULL})
   - Fix Oops relating to sleeping in critical sections
   - Clear LED_INIT_DEFAULT_TRIGGER flag when clearing the current trigger
   - Do not leak resources in error handling paths
   - Fix unsigned comparison which can never be negative
   - Provide missing NULL terminating entries in tables
   - Fix misnaming issues"

* tag 'leds-next-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (53 commits)
  leds: leds-mt6323: Adjust return/parameter types in wled get/set callbacks
  leds: sgm3140: Add richtek,rt5033-led compatible
  dt-bindings: leds: sgm3140: Document richtek,rt5033 compatible
  dt-bindings: backlight: kinetic,ktz8866: Add missing type for "current-num-sinks"
  dt-bindings: leds: Drop unneeded quotes
  leds: Fix config reference for AW200xx driver
  leds: leds-mt6323: Add support for WLEDs and MT6332
  leds: leds-mt6323: Add support for MT6331 leds
  leds: leds-mt6323: Open code and drop MT6323_CAL_HW_DUTY macro
  leds: leds-mt6323: Drop MT6323_ prefix from macros and defines
  leds: leds-mt6323: Specify registers and specs in platform data
  dt-bindings: leds: leds-mt6323: Document mt6332 compatible
  dt-bindings: leds: leds-mt6323: Document mt6331 compatible
  leds: simatic-ipc-leds-gpio: Introduce more Kconfig switches
  leds: simatic-ipc-leds-gpio: Split up into multiple drivers
  leds: simatic-ipc-leds-gpio: Move two extra gpio pins into another table
  leds: simatic-ipc-leds-gpio: Add terminating entries to gpio tables
  leds: flash: leds-qcom-flash: Fix an unsigned comparison which can never be negative
  leds: cht-wcove: Remove unneeded semicolon
  leds: cht-wcove: Fix an unsigned comparison which can never be negative
  ...
parents b8ec70ab 877e9119
What: /sys/class/leds/<led>/dim
Date: May 2023
Description: 64-level DIM current. If you write a negative value or
"auto", the dim will be calculated according to the
brightness.
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/awinic,aw200xx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: AWINIC AW200XX LED
maintainers:
- Martin Kurbanov <mmkurbanov@sberdevices.ru>
description: |
This controller is present on AW20036/AW20054/AW20072.
It is a 3x12/6x9/6x12 matrix LED programmed via
an I2C interface, up to 36/54/72 LEDs or 12/18/24 RGBs,
3 pattern controllers for auto breathing or group dimming control.
For more product information please see the link below:
aw20036 - https://www.awinic.com/en/productDetail/AW20036QNR#tech-docs
aw20054 - https://www.awinic.com/en/productDetail/AW20054QNR#tech-docs
aw20072 - https://www.awinic.com/en/productDetail/AW20072QNR#tech-docs
properties:
compatible:
enum:
- awinic,aw20036
- awinic,aw20054
- awinic,aw20072
reg:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
awinic,display-rows:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Leds matrix size
patternProperties:
"^led@[0-9a-f]$":
type: object
$ref: common.yaml#
unevaluatedProperties: false
properties:
reg:
description:
LED number
maxItems: 1
led-max-microamp:
default: 9780
description: |
Note that a driver will take the minimum of all LED limits
since the chip has a single global setting.
The maximum output current of each LED is calculated by the
following formula:
IMAXled = 160000 * (592 / 600.5) * (1 / display-rows)
And the minimum output current formula:
IMINled = 3300 * (592 / 600.5) * (1 / display-rows)
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
- awinic,display-rows
allOf:
- if:
properties:
compatible:
contains:
const: awinic,aw20036
then:
properties:
awinic,display-rows:
enum: [1, 2, 3]
else:
properties:
awinic,display-rows:
enum: [1, 2, 3, 4, 5, 6, 7]
additionalProperties: false
examples:
- |
#include <dt-bindings/leds/common.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
led-controller@3a {
compatible = "awinic,aw20036";
reg = <0x3a>;
#address-cells = <1>;
#size-cells = <0>;
awinic,display-rows = <3>;
led@0 {
reg = <0x0>;
color = <LED_COLOR_ID_RED>;
led-max-microamp = <9780>;
};
led@1 {
reg = <0x1>;
color = <LED_COLOR_ID_GREEN>;
led-max-microamp = <9780>;
};
led@2 {
reg = <0x2>;
color = <LED_COLOR_ID_BLUE>;
led-max-microamp = <9780>;
};
};
};
...
......@@ -33,6 +33,7 @@ properties:
current-num-sinks:
description: number of the LED current sinks' channels.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 2, 3, 4, 5, 6]
kinetic,current-ramp-delay-ms:
......
......@@ -105,8 +105,6 @@ properties:
- audio-mute
# LED indicates bluetooth power state
- bluetooth-power
# LED indicates activity of all CPUs
- cpu
# LED indicates camera flash state
- flash
# LED indicated keyboard capslock
......
......@@ -34,7 +34,7 @@ required:
- color
allOf:
- $ref: "common.yaml#"
- $ref: common.yaml#
additionalProperties: true
......
......@@ -66,6 +66,14 @@ properties:
'#size-cells':
const: 0
ti,charge-pump-mode:
description:
Set the operating mode of the internal charge pump as defined in
<dt-bindings/leds/leds-lp55xx.h>.
$ref: /schemas/types.yaml#/definitions/uint32
default: 3 # auto
maximum: 3
patternProperties:
'^multi-led@[0-8]$':
type: object
......@@ -152,6 +160,7 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/leds/common.h>
#include <dt-bindings/leds/leds-lp55xx.h>
i2c {
#address-cells = <1>;
......@@ -164,6 +173,7 @@ examples:
reg = <0x32>;
clock-mode = /bits/ 8 <2>;
pwr-sel = /bits/ 8 <3>; /* D1~9 connected to VOUT */
ti,charge-pump-mode = <LP55XX_CP_BYPASS>;
led@0 {
reg = <0>;
......
......@@ -12,7 +12,10 @@ For MediaTek PMIC wrapper bindings see:
Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
Required properties:
- compatible : Must be "mediatek,mt6323-led"
- compatible : Must be one of
- "mediatek,mt6323-led"
- "mediatek,mt6331-led"
- "mediatek,mt6332-led"
- address-cells : Must be 1
- size-cells : Must be 0
......
......@@ -16,18 +16,24 @@ description: >
properties:
compatible:
enum:
- qcom,pm660l-lpg
- qcom,pm8150b-lpg
- qcom,pm8150l-lpg
- qcom,pm8350c-pwm
- qcom,pm8916-pwm
- qcom,pm8941-lpg
- qcom,pm8994-lpg
- qcom,pmc8180c-lpg
- qcom,pmi8994-lpg
- qcom,pmi8998-lpg
- qcom,pmk8550-pwm
oneOf:
- enum:
- qcom,pm660l-lpg
- qcom,pm8150b-lpg
- qcom,pm8150l-lpg
- qcom,pm8350c-pwm
- qcom,pm8916-pwm
- qcom,pm8941-lpg
- qcom,pm8994-lpg
- qcom,pmc8180c-lpg
- qcom,pmi632-lpg
- qcom,pmi8994-lpg
- qcom,pmi8998-lpg
- qcom,pmk8550-pwm
- items:
- enum:
- qcom,pm8550-pwm
- const: qcom,pm8350c-pwm
"#pwm-cells":
const: 2
......
......@@ -20,6 +20,7 @@ properties:
compatible:
enum:
- ocs,ocp8110
- richtek,rt5033-led
- sgmicro,sgm3140
enable-gpios:
......
......@@ -26,6 +26,8 @@ properties:
- qcom,pm8150c-flash-led
- qcom,pm8150l-flash-led
- qcom,pm8350c-flash-led
- qcom,pm8550-flash-led
- qcom,pmi8998-flash-led
- const: qcom,spmi-flash-led
reg:
......
......@@ -32,7 +32,7 @@ patternProperties:
properties:
rohm,led-compatible:
description: LED identification string
$ref: "/schemas/types.yaml#/definitions/string"
$ref: /schemas/types.yaml#/definitions/string
enum:
- bd71828-ambled
- bd71828-grnled
......
......@@ -71,6 +71,7 @@ properties:
- qcom,pm8998
- qcom,pma8084
- qcom,pmd9635
- qcom,pmi632
- qcom,pmi8950
- qcom,pmi8962
- qcom,pmi8994
......
......@@ -17,6 +17,7 @@ LEDs
uleds
leds-blinkm
leds-cht-wcove
leds-el15203000
leds-lm3556
leds-lp3944
......
.. SPDX-License-Identifier: GPL-2.0
===========================================================
Kernel driver for Intel Cherry Trail Whiskey Cove PMIC LEDs
===========================================================
/sys/class/leds/<led>/hw_pattern
--------------------------------
Specify a hardware pattern for the Whiskey Cove PMIC LEDs.
The only supported pattern is hardware breathing mode::
"0 2000 1 2000"
^
|
Max-| ---
| / \
| / \
| / \ /
| / \ /
Min-|- ---
|
0------2------4--> time (sec)
The rise and fall times must be the same value.
Supported values are 2000, 1000, 500 and 250 for
breathing frequencies of 1/4, 1/2, 1 and 2 Hz.
The set pattern only controls the timing. For max brightness the last
set brightness is used and the max brightness can be changed
while breathing by writing the brightness attribute.
This is just like how blinking works in the LED subsystem,
for both sw and hw blinking the brightness can also be changed
while blinking. Breathing on this hw really is just a variant
mode of blinking.
......@@ -58,6 +58,7 @@ LEDs on notebook body, indicating that sound input / output is muted.
* System notification
Good: "rgb:status"
Legacy: "status-led:{red,green,blue}" (Motorola Droid 4)
Legacy: "lp5523:{r,g,b}" (Nokia N900)
......@@ -65,7 +66,7 @@ Phones usually have multi-color status LED.
* Power management
Good: "platform:*:charging" (allwinner sun50i)
Good: "platform:*:charging" (allwinner sun50i, leds-cht-wcove)
* Screen
......
......@@ -94,6 +94,19 @@ config LEDS_ARIEL
Say Y to if your machine is a Dell Wyse 3020 thin client.
config LEDS_AW200XX
tristate "LED support for Awinic AW20036/AW20054/AW20072"
depends on LEDS_CLASS
depends on I2C
help
This option enables support for the AW20036/AW20054/AW20072 LED driver.
It is a 3x12/6x9/6x12 matrix LED driver programmed via
an I2C interface, up to 36/54/72 LEDs or 12/18/24 RGBs,
3 pattern controllers for auto breathing or group dimming control.
To compile this driver as a module, choose M here: the module
will be called leds-aw200xx.
config LEDS_AW2013
tristate "LED support for Awinic AW2013"
depends on LEDS_CLASS && I2C && OF
......@@ -122,6 +135,17 @@ config LEDS_BCM6358
This option enables support for LEDs connected to the BCM6358
LED HW controller accessed via MMIO registers.
config LEDS_CHT_WCOVE
tristate "LED support for Intel Cherry Trail Whiskey Cove PMIC"
depends on LEDS_CLASS
depends on INTEL_SOC_PMIC_CHTWC
help
This option enables support for charger and general purpose LEDs
connected to the Intel Cherrytrail Whiskey Cove PMIC.
To compile this driver as a module, choose M here: the module
will be called leds-cht-wcove.
config LEDS_CPCAP
tristate "LED Support for Motorola CPCAP"
depends on LEDS_CLASS
......@@ -676,7 +700,7 @@ config LEDS_LM355x
config LEDS_OT200
tristate "LED support for the Bachmann OT200"
depends on LEDS_CLASS && HAS_IOMEM && (X86_32 || COMPILE_TEST)
depends on LEDS_CLASS && HAS_IOPORT && (X86_32 || COMPILE_TEST)
help
This option enables support for the LEDs on the Bachmann OT200.
Say Y to enable LEDs on the Bachmann OT200.
......@@ -807,8 +831,7 @@ config LEDS_SPI_BYTE
supported: Ubiquiti airCube ISP microcontroller based LED controller.
config LEDS_TI_LMU_COMMON
tristate "LED driver for TI LMU"
depends on LEDS_CLASS
tristate "LED driver for TI LMU" if COMPILE_TEST
select REGMAP
help
Say Y to enable the LED driver for TI LMU devices.
......@@ -817,16 +840,16 @@ config LEDS_TI_LMU_COMMON
config LEDS_LM3697
tristate "LED driver for LM3697"
depends on LEDS_TI_LMU_COMMON
depends on I2C && OF
depends on LEDS_CLASS && I2C && OF
select LEDS_TI_LMU_COMMON
help
Say Y to enable the LM3697 LED driver for TI LMU devices.
This supports the LED device LM3697.
config LEDS_LM36274
tristate "LED driver for LM36274"
depends on LEDS_TI_LMU_COMMON
depends on MFD_TI_LMU
depends on LEDS_CLASS && MFD_TI_LMU
select LEDS_TI_LMU_COMMON
help
Say Y to enable the LM36274 LED driver for TI LMU devices.
This supports the LED device LM36274.
......
......@@ -14,12 +14,14 @@ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o
obj-$(CONFIG_LEDS_APU) += leds-apu.o
obj-$(CONFIG_LEDS_ARIEL) += leds-ariel.o
obj-$(CONFIG_LEDS_AW200XX) += leds-aw200xx.o
obj-$(CONFIG_LEDS_AW2013) += leds-aw2013.o
obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o
obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o
obj-$(CONFIG_LEDS_BD2606MVV) += leds-bd2606mvv.o
obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
obj-$(CONFIG_LEDS_CHT_WCOVE) += leds-cht-wcove.o
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
......
......@@ -425,7 +425,7 @@ static void aat1290_init_v4l2_flash_config(struct aat1290_led *led,
struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
struct led_flash_setting *s;
strlcpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
strscpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
sizeof(v4l2_sd_cfg->dev_name));
s = &v4l2_sd_cfg->intensity;
......
......@@ -651,8 +651,8 @@ static int as3645a_v4l2_setup(struct as3645a *flash)
},
};
strlcpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name));
strlcpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name,
strscpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name));
strscpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name,
sizeof(cfgind.dev_name));
flash->vf = v4l2_flash_init(
......@@ -759,7 +759,7 @@ static struct i2c_driver as3645a_i2c_driver = {
.of_match_table = as3645a_of_table,
.name = AS_NAME,
},
.probe_new = as3645a_probe,
.probe = as3645a_probe,
.remove = as3645a_remove,
.id_table = as3645a_id_table,
};
......
......@@ -471,7 +471,7 @@ static struct i2c_driver lm3601x_i2c_driver = {
.name = "lm3601x",
.of_match_table = of_lm3601x_leds_match,
},
.probe_new = lm3601x_probe,
.probe = lm3601x_probe,
.remove = lm3601x_remove,
.id_table = lm3601x_id,
};
......
......@@ -18,7 +18,8 @@
#define FLASH_TYPE_VAL 0x18
#define FLASH_SUBTYPE_REG 0x05
#define FLASH_SUBTYPE_3CH_VAL 0x04
#define FLASH_SUBTYPE_3CH_PM8150_VAL 0x04
#define FLASH_SUBTYPE_3CH_PMI8998_VAL 0x03
#define FLASH_SUBTYPE_4CH_VAL 0x07
#define FLASH_STS_3CH_OTST1 BIT(0)
......@@ -416,6 +417,14 @@ static int qcom_flash_led_brightness_set(struct led_classdev *led_cdev,
bool enable = !!brightness;
int rc;
rc = set_flash_strobe(led, SW_STROBE, false);
if (rc)
return rc;
rc = set_flash_module_en(led, false);
if (rc)
return rc;
rc = set_flash_current(led, current_ma, TORCH_MODE);
if (rc)
return rc;
......@@ -529,9 +538,9 @@ static int qcom_flash_register_led_device(struct device *dev,
struct led_init_data init_data;
struct led_classdev_flash *flash = &led->flash;
struct led_flash_setting *brightness, *timeout;
u32 count, current_ua, timeout_us;
u32 current_ua, timeout_us;
u32 channels[4];
int i, rc;
int i, rc, count;
count = fwnode_property_count_u32(node, "led-sources");
if (count <= 0) {
......@@ -682,7 +691,7 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
return rc;
}
if (val == FLASH_SUBTYPE_3CH_VAL) {
if (val == FLASH_SUBTYPE_3CH_PM8150_VAL || val == FLASH_SUBTYPE_3CH_PMI8998_VAL) {
flash_data->hw_type = QCOM_MVFLASH_3CH;
flash_data->max_channels = 3;
regs = mvflash_3ch_regs;
......
......@@ -419,7 +419,7 @@ static struct i2c_driver rt4505_driver = {
.name = "rt4505",
.of_match_table = of_match_ptr(rt4505_leds_match),
},
.probe_new = rt4505_probe,
.probe = rt4505_probe,
.remove = rt4505_remove,
.shutdown = rt4505_shutdown,
};
......
......@@ -291,6 +291,7 @@ static int sgm3140_remove(struct platform_device *pdev)
static const struct of_device_id sgm3140_dt_match[] = {
{ .compatible = "ocs,ocp8110" },
{ .compatible = "richtek,rt5033-led" },
{ .compatible = "sgmicro,sgm3140" },
{ /* sentinel */ }
};
......
......@@ -409,7 +409,7 @@ static int led_classdev_next_name(const char *init_name, char *name,
int ret = 0;
struct device *dev;
strlcpy(name, init_name, len);
strscpy(name, init_name, len);
while ((ret < len) &&
(dev = class_find_device_by_name(leds_class, name))) {
......
......@@ -114,21 +114,14 @@ static void led_timer_function(struct timer_list *t)
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
}
static void set_brightness_delayed(struct work_struct *ws)
static void set_brightness_delayed_set_brightness(struct led_classdev *led_cdev,
unsigned int value)
{
struct led_classdev *led_cdev =
container_of(ws, struct led_classdev, set_brightness_work);
int ret = 0;
if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) {
led_cdev->delayed_set_value = LED_OFF;
led_stop_software_blink(led_cdev);
}
ret = __led_set_brightness(led_cdev, led_cdev->delayed_set_value);
ret = __led_set_brightness(led_cdev, value);
if (ret == -ENOTSUPP)
ret = __led_set_brightness_blocking(led_cdev,
led_cdev->delayed_set_value);
ret = __led_set_brightness_blocking(led_cdev, value);
if (ret < 0 &&
/* LED HW might have been unplugged, therefore don't warn */
!(ret == -ENODEV && (led_cdev->flags & LED_UNREGISTERING) &&
......@@ -137,6 +130,37 @@ static void set_brightness_delayed(struct work_struct *ws)
"Setting an LED's brightness failed (%d)\n", ret);
}
static void set_brightness_delayed(struct work_struct *ws)
{
struct led_classdev *led_cdev =
container_of(ws, struct led_classdev, set_brightness_work);
if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) {
led_stop_software_blink(led_cdev);
set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
}
/*
* Triggers may call led_set_brightness(LED_OFF),
* led_set_brightness(LED_FULL) in quick succession to disable blinking
* and turn the LED on. Both actions may have been scheduled to run
* before this work item runs once. To make sure this works properly
* handle LED_SET_BRIGHTNESS_OFF first.
*/
if (test_and_clear_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags))
set_brightness_delayed_set_brightness(led_cdev, LED_OFF);
if (test_and_clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags))
set_brightness_delayed_set_brightness(led_cdev, led_cdev->delayed_set_value);
if (test_and_clear_bit(LED_SET_BLINK, &led_cdev->work_flags)) {
unsigned long delay_on = led_cdev->delayed_delay_on;
unsigned long delay_off = led_cdev->delayed_delay_off;
led_blink_set(led_cdev, &delay_on, &delay_off);
}
}
static void led_set_software_blink(struct led_classdev *led_cdev,
unsigned long delay_on,
unsigned long delay_off)
......@@ -229,6 +253,22 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev,
}
EXPORT_SYMBOL_GPL(led_blink_set_oneshot);
void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on,
unsigned long delay_off)
{
/* If necessary delegate to a work queue task. */
if (led_cdev->blink_set && led_cdev->brightness_set_blocking) {
led_cdev->delayed_delay_on = delay_on;
led_cdev->delayed_delay_off = delay_off;
set_bit(LED_SET_BLINK, &led_cdev->work_flags);
schedule_work(&led_cdev->set_brightness_work);
return;
}
led_blink_set(led_cdev, &delay_on, &delay_off);
}
EXPORT_SYMBOL_GPL(led_blink_set_nosleep);
void led_stop_software_blink(struct led_classdev *led_cdev)
{
del_timer_sync(&led_cdev->blink_timer);
......@@ -271,8 +311,23 @@ void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value)
if (!__led_set_brightness(led_cdev, value))
return;
/* If brightness setting can sleep, delegate it to a work queue task */
led_cdev->delayed_set_value = value;
/*
* Brightness setting can sleep, delegate it to a work queue task.
* value 0 / LED_OFF is special, since it also disables hw-blinking
* (sw-blink disable is handled in led_set_brightness()).
* To avoid a hw-blink-disable getting lost when a second brightness
* change is done immediately afterwards (before the work runs),
* it uses a separate work_flag.
*/
if (value) {
led_cdev->delayed_set_value = value;
set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
} else {
clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
clear_bit(LED_SET_BLINK, &led_cdev->work_flags);
set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
}
schedule_work(&led_cdev->set_brightness_work);
}
EXPORT_SYMBOL_GPL(led_set_brightness_nopm);
......
......@@ -185,6 +185,7 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
led_cdev->trigger = NULL;
led_cdev->trigger_data = NULL;
led_cdev->activated = false;
led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER;
led_set_brightness(led_cdev, LED_OFF);
}
if (trig) {
......@@ -393,8 +394,8 @@ void led_trigger_event(struct led_trigger *trig,
EXPORT_SYMBOL_GPL(led_trigger_event);
static void led_trigger_blink_setup(struct led_trigger *trig,
unsigned long *delay_on,
unsigned long *delay_off,
unsigned long delay_on,
unsigned long delay_off,
int oneshot,
int invert)
{
......@@ -406,25 +407,25 @@ static void led_trigger_blink_setup(struct led_trigger *trig,
rcu_read_lock();
list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) {
if (oneshot)
led_blink_set_oneshot(led_cdev, delay_on, delay_off,
led_blink_set_oneshot(led_cdev, &delay_on, &delay_off,
invert);
else
led_blink_set(led_cdev, delay_on, delay_off);
led_blink_set_nosleep(led_cdev, delay_on, delay_off);
}
rcu_read_unlock();
}
void led_trigger_blink(struct led_trigger *trig,
unsigned long *delay_on,
unsigned long *delay_off)
unsigned long delay_on,
unsigned long delay_off)
{
led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0);
}
EXPORT_SYMBOL_GPL(led_trigger_blink);
void led_trigger_blink_oneshot(struct led_trigger *trig,
unsigned long *delay_on,
unsigned long *delay_off,
unsigned long delay_on,
unsigned long delay_off,
int invert)
{
led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert);
......
......@@ -346,7 +346,7 @@ static struct i2c_driver an30259a_driver = {
.name = "leds-an30259a",
.of_match_table = of_match_ptr(an30259a_match_table),
},
.probe_new = an30259a_probe,
.probe = an30259a_probe,
.remove = an30259a_remove,
.id_table = an30259a_id,
};
......
This diff is collapsed.
......@@ -422,7 +422,7 @@ static struct i2c_driver aw2013_driver = {
.name = "leds-aw2013",
.of_match_table = of_match_ptr(aw2013_match_table),
},
.probe_new = aw2013_probe,
.probe = aw2013_probe,
.remove = aw2013_remove,
};
......
......@@ -150,7 +150,7 @@ static struct i2c_driver bd2606mvv_driver = {
.name = "leds-bd2606mvv",
.of_match_table = of_match_ptr(of_bd2606mvv_leds_match),
},
.probe_new = bd2606mvv_probe,
.probe = bd2606mvv_probe,
};
module_i2c_driver(bd2606mvv_driver);
......
......@@ -786,7 +786,7 @@ static struct i2c_driver bd2802_i2c_driver = {
.name = "BD2802",
.pm = &bd2802_pm,
},
.probe_new = bd2802_probe,
.probe = bd2802_probe,
.remove = bd2802_remove,
.id_table = bd2802_id,
};
......
......@@ -561,7 +561,7 @@ static int blinkm_detect(struct i2c_client *client, struct i2c_board_info *info)
return -ENODEV;
}
strlcpy(info->type, "blinkm", I2C_NAME_SIZE);
strscpy(info->type, "blinkm", I2C_NAME_SIZE);
return 0;
}
......@@ -730,7 +730,7 @@ static struct i2c_driver blinkm_driver = {
.driver = {
.name = "blinkm",
},
.probe_new = blinkm_probe,
.probe = blinkm_probe,
.remove = blinkm_remove,
.id_table = blinkm_id,
.detect = blinkm_detect,
......
This diff is collapsed.
......@@ -13,6 +13,7 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
......@@ -77,6 +78,7 @@ static int create_gpio_led(const struct gpio_led *template,
struct fwnode_handle *fwnode, gpio_blink_set_t blink_set)
{
struct led_init_data init_data = {};
struct pinctrl *pinctrl;
int ret, state;
led_dat->cdev.default_trigger = template->default_trigger;
......@@ -119,6 +121,22 @@ static int create_gpio_led(const struct gpio_led *template,
&init_data);
}
if (ret)
return ret;
pinctrl = devm_pinctrl_get_select_default(led_dat->cdev.dev);
if (IS_ERR(pinctrl)) {
ret = PTR_ERR(pinctrl);
if (ret != -ENODEV) {
dev_warn(led_dat->cdev.dev,
"Failed to select %pOF pinctrl: %d\n",
to_of_node(fwnode), ret);
} else {
/* pinctrl-%d not present, not an error */
ret = 0;
}
}
return ret;
}
......
......@@ -602,7 +602,7 @@ static struct i2c_driver is31fl319x_driver = {
.name = "leds-is31fl319x",
.of_match_table = of_is31fl319x_match,
},
.probe_new = is31fl319x_probe,
.probe = is31fl319x_probe,
.id_table = is31fl319x_id,
};
......
......@@ -488,7 +488,7 @@ static struct i2c_driver is31fl32xx_driver = {
.name = "is31fl32xx",
.of_match_table = of_is31fl32xx_match,
},
.probe_new = is31fl32xx_probe,
.probe = is31fl32xx_probe,
.remove = is31fl32xx_remove,
.id_table = is31fl32xx_id,
};
......
......@@ -484,7 +484,7 @@ static const struct i2c_device_id lm3530_id[] = {
MODULE_DEVICE_TABLE(i2c, lm3530_id);
static struct i2c_driver lm3530_i2c_driver = {
.probe_new = lm3530_probe,
.probe = lm3530_probe,
.remove = lm3530_remove,
.id_table = lm3530_id,
.driver = {
......
......@@ -726,7 +726,7 @@ static const struct i2c_device_id lm3532_id[] = {
MODULE_DEVICE_TABLE(i2c, lm3532_id);
static struct i2c_driver lm3532_i2c_driver = {
.probe_new = lm3532_probe,
.probe = lm3532_probe,
.remove = lm3532_remove,
.id_table = lm3532_id,
.driver = {
......
......@@ -516,7 +516,7 @@ static struct i2c_driver lm355x_i2c_driver = {
.name = LM355x_NAME,
.pm = NULL,
},
.probe_new = lm355x_probe,
.probe = lm355x_probe,
.remove = lm355x_remove,
.id_table = lm355x_id,
};
......
......@@ -401,7 +401,7 @@ static struct i2c_driver lm3642_i2c_driver = {
.name = LM3642_NAME,
.pm = NULL,
},
.probe_new = lm3642_probe,
.probe = lm3642_probe,
.remove = lm3642_remove,
.id_table = lm3642_id,
};
......
......@@ -518,7 +518,7 @@ static struct i2c_driver lm3692x_driver = {
.name = "lm3692x",
.of_match_table = of_lm3692x_leds_match,
},
.probe_new = lm3692x_probe,
.probe = lm3692x_probe,
.remove = lm3692x_remove,
.id_table = lm3692x_id,
};
......
......@@ -376,7 +376,7 @@ static struct i2c_driver lm3697_driver = {
.name = "lm3697",
.of_match_table = of_lm3697_leds_match,
},
.probe_new = lm3697_probe,
.probe = lm3697_probe,
.remove = lm3697_remove,
.id_table = lm3697_id,
};
......
......@@ -427,7 +427,7 @@ static struct i2c_driver lp3944_driver = {
.driver = {
.name = "lp3944",
},
.probe_new = lp3944_probe,
.probe = lp3944_probe,
.remove = lp3944_remove,
.id_table = lp3944_id,
};
......
......@@ -273,7 +273,7 @@ static struct i2c_driver lp3952_i2c_driver = {
.driver = {
.name = LP3952_NAME,
},
.probe_new = lp3952_probe,
.probe = lp3952_probe,
.remove = lp3952_remove,
.id_table = lp3952_id,
};
......
......@@ -608,7 +608,7 @@ static struct i2c_driver lp50xx_driver = {
.name = "lp50xx",
.of_match_table = of_lp50xx_leds_match,
},
.probe_new = lp50xx_probe,
.probe = lp50xx_probe,
.remove = lp50xx_remove,
.id_table = lp50xx_id,
};
......
......@@ -58,14 +58,11 @@
/* CONFIG register */
#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */
#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */
#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */
#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */
#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */
#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */
#define LP5521_CP_MODE_MASK 0x18 /* Charge pump mode */
#define LP5521_CP_MODE_SHIFT 3
#define LP5521_R_TO_BATT 0x04 /* R out: 0 = CP, 1 = Vbat */
#define LP5521_CLK_INT 0x01 /* Internal clock */
#define LP5521_DEFAULT_CFG \
(LP5521_PWM_HF | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO)
#define LP5521_DEFAULT_CFG (LP5521_PWM_HF | LP5521_PWRSAVE_EN)
/* Status */
#define LP5521_EXT_CLK_USED 0x08
......@@ -310,6 +307,8 @@ static int lp5521_post_init_device(struct lp55xx_chip *chip)
if (!lp55xx_is_extclk_used(chip))
val |= LP5521_CLK_INT;
val |= (chip->pdata->charge_pump_mode << LP5521_CP_MODE_SHIFT) & LP5521_CP_MODE_MASK;
ret = lp55xx_write(chip, LP5521_REG_CONFIG, val);
if (ret)
return ret;
......@@ -608,7 +607,7 @@ static struct i2c_driver lp5521_driver = {
.name = "lp5521",
.of_match_table = of_match_ptr(of_lp5521_leds_match),
},
.probe_new = lp5521_probe,
.probe = lp5521_probe,
.remove = lp5521_remove,
.id_table = lp5521_id,
};
......
......@@ -57,8 +57,11 @@
#define LP5523_AUTO_INC 0x40
#define LP5523_PWR_SAVE 0x20
#define LP5523_PWM_PWR_SAVE 0x04
#define LP5523_CP_AUTO 0x18
#define LP5523_CP_MODE_MASK 0x18
#define LP5523_CP_MODE_SHIFT 3
#define LP5523_AUTO_CLK 0x02
#define LP5523_DEFAULT_CONFIG \
(LP5523_AUTO_INC | LP5523_PWR_SAVE | LP5523_AUTO_CLK | LP5523_PWM_PWR_SAVE)
#define LP5523_EN_LEDTEST 0x80
#define LP5523_LEDTEST_DONE 0x80
......@@ -125,6 +128,7 @@ static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current)
static int lp5523_post_init_device(struct lp55xx_chip *chip)
{
int ret;
int val;
ret = lp55xx_write(chip, LP5523_REG_ENABLE, LP5523_ENABLE);
if (ret)
......@@ -133,10 +137,10 @@ static int lp5523_post_init_device(struct lp55xx_chip *chip)
/* Chip startup time is 500 us, 1 - 2 ms gives some margin */
usleep_range(1000, 2000);
ret = lp55xx_write(chip, LP5523_REG_CONFIG,
LP5523_AUTO_INC | LP5523_PWR_SAVE |
LP5523_CP_AUTO | LP5523_AUTO_CLK |
LP5523_PWM_PWR_SAVE);
val = LP5523_DEFAULT_CONFIG;
val |= (chip->pdata->charge_pump_mode << LP5523_CP_MODE_SHIFT) & LP5523_CP_MODE_MASK;
ret = lp55xx_write(chip, LP5523_REG_CONFIG, val);
if (ret)
return ret;
......@@ -983,7 +987,7 @@ static struct i2c_driver lp5523_driver = {
.name = "lp5523x",
.of_match_table = of_match_ptr(of_lp5523_leds_match),
},
.probe_new = lp5523_probe,
.probe = lp5523_probe,
.remove = lp5523_remove,
.id_table = lp5523_id,
};
......
......@@ -603,7 +603,7 @@ static struct i2c_driver lp5562_driver = {
.name = "lp5562",
.of_match_table = of_match_ptr(of_lp5562_leds_match),
},
.probe_new = lp5562_probe,
.probe = lp5562_probe,
.remove = lp5562_remove,
.id_table = lp5562_id,
};
......
......@@ -18,6 +18,7 @@
#include <linux/platform_data/leds-lp55xx.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <dt-bindings/leds/leds-lp55xx.h>
#include "leds-lp55xx-common.h"
......@@ -691,6 +692,14 @@ struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
i++;
}
if (of_property_read_u32(np, "ti,charge-pump-mode", &pdata->charge_pump_mode))
pdata->charge_pump_mode = LP55XX_CP_AUTO;
if (pdata->charge_pump_mode > LP55XX_CP_AUTO) {
dev_err(dev, "invalid charge pump mode %d\n", pdata->charge_pump_mode);
return ERR_PTR(-EINVAL);
}
of_property_read_string(np, "label", &pdata->label);
of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
......
......@@ -53,10 +53,10 @@
#define LP8501_PWM_PSAVE BIT(7)
#define LP8501_AUTO_INC BIT(6)
#define LP8501_PWR_SAVE BIT(5)
#define LP8501_CP_AUTO 0x18
#define LP8501_CP_MODE_MASK 0x18
#define LP8501_CP_MODE_SHIFT 3
#define LP8501_INT_CLK BIT(0)
#define LP8501_DEFAULT_CFG \
(LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE | LP8501_CP_AUTO)
#define LP8501_DEFAULT_CFG (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE)
#define LP8501_REG_RESET 0x3D
#define LP8501_RESET 0xFF
......@@ -102,6 +102,8 @@ static int lp8501_post_init_device(struct lp55xx_chip *chip)
if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT)
val |= LP8501_INT_CLK;
val |= (chip->pdata->charge_pump_mode << LP8501_CP_MODE_SHIFT) & LP8501_CP_MODE_MASK;
ret = lp55xx_write(chip, LP8501_REG_CONFIG, val);
if (ret)
return ret;
......@@ -392,7 +394,7 @@ static struct i2c_driver lp8501_driver = {
.name = "lp8501",
.of_match_table = of_match_ptr(of_lp8501_leds_match),
},
.probe_new = lp8501_probe,
.probe = lp8501_probe,
.remove = lp8501_remove,
.id_table = lp8501_id,
};
......
......@@ -475,7 +475,7 @@ static struct i2c_driver lp8860_driver = {
.name = "lp8860",
.of_match_table = of_lp8860_leds_match,
},
.probe_new = lp8860_probe,
.probe = lp8860_probe,
.remove = lp8860_remove,
.id_table = lp8860_id,
};
......
This diff is collapsed.
......@@ -102,7 +102,7 @@ static struct i2c_driver pca9532_driver = {
.name = "leds-pca953x",
.of_match_table = of_match_ptr(of_pca9532_leds_match),
},
.probe_new = pca9532_probe,
.probe = pca9532_probe,
.remove = pca9532_remove,
.id_table = pca9532_id,
};
......
......@@ -668,7 +668,7 @@ static struct i2c_driver pca955x_driver = {
.name = "leds-pca955x",
.of_match_table = of_pca955x_match,
},
.probe_new = pca955x_probe,
.probe = pca955x_probe,
.id_table = pca955x_id,
};
......
......@@ -431,7 +431,7 @@ static struct i2c_driver pca963x_driver = {
.name = "leds-pca963x",
.of_match_table = of_pca963x_match,
},
.probe_new = pca963x_probe,
.probe = pca963x_probe,
.id_table = pca963x_id,
};
......
......@@ -98,7 +98,7 @@ static int spi_byte_probe(struct spi_device *spi)
return -ENOMEM;
of_property_read_string(child, "label", &name);
strlcpy(led->name, name, sizeof(led->name));
strscpy(led->name, name, sizeof(led->name));
led->spi = spi;
mutex_init(&led->mutex);
led->cdef = device_get_match_data(dev);
......
......@@ -808,7 +808,7 @@ static struct i2c_driver tca6507_driver = {
.name = "leds-tca6507",
.of_match_table = of_match_ptr(of_tca6507_leds_match),
},
.probe_new = tca6507_probe,
.probe = tca6507_probe,
.remove = tca6507_remove,
.id_table = tca6507_id,
};
......
......@@ -230,7 +230,7 @@ static struct i2c_driver tlc591xx_driver = {
.name = "tlc591xx",
.of_match_table = of_match_ptr(of_tlc591xx_leds_match),
},
.probe_new = tlc591xx_probe,
.probe = tlc591xx_probe,
.id_table = tlc591xx_id,
};
......
......@@ -271,7 +271,7 @@ static const struct i2c_device_id omnia_id[] = {
MODULE_DEVICE_TABLE(i2c, omnia_id);
static struct i2c_driver omnia_leds_driver = {
.probe_new = omnia_leds_probe,
.probe = omnia_leds_probe,
.remove = omnia_leds_remove,
.id_table = omnia_id,
.driver = {
......
......@@ -1173,8 +1173,10 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
i = 0;
for_each_available_child_of_node(np, child) {
ret = lpg_parse_channel(lpg, child, &led->channels[i]);
if (ret < 0)
if (ret < 0) {
of_node_put(child);
return ret;
}
info[i].color_index = led->channels[i]->color;
info[i].intensity = 0;
......@@ -1352,8 +1354,10 @@ static int lpg_probe(struct platform_device *pdev)
for_each_available_child_of_node(pdev->dev.of_node, np) {
ret = lpg_add_led(lpg, np);
if (ret)
if (ret) {
of_node_put(np);
return ret;
}
}
for (i = 0; i < lpg->num_channels; i++)
......@@ -1414,6 +1418,20 @@ static const struct lpg_data pm8994_lpg_data = {
},
};
/* PMI632 uses SDAM instead of LUT for pattern */
static const struct lpg_data pmi632_lpg_data = {
.triled_base = 0xd000,
.num_channels = 5,
.channels = (const struct lpg_channel_data[]) {
{ .base = 0xb300, .triled_mask = BIT(7) },
{ .base = 0xb400, .triled_mask = BIT(6) },
{ .base = 0xb500, .triled_mask = BIT(5) },
{ .base = 0xb600 },
{ .base = 0xb700 },
},
};
static const struct lpg_data pmi8994_lpg_data = {
.lut_base = 0xb000,
.lut_size = 24,
......@@ -1505,6 +1523,7 @@ static const struct of_device_id lpg_of_table[] = {
{ .compatible = "qcom,pm8916-pwm", .data = &pm8916_pwm_data },
{ .compatible = "qcom,pm8941-lpg", .data = &pm8941_lpg_data },
{ .compatible = "qcom,pm8994-lpg", .data = &pm8994_lpg_data },
{ .compatible = "qcom,pmi632-lpg", .data = &pmi632_lpg_data },
{ .compatible = "qcom,pmi8994-lpg", .data = &pmi8994_lpg_data },
{ .compatible = "qcom,pmi8998-lpg", .data = &pmi8998_lpg_data },
{ .compatible = "qcom,pmc8180c-lpg", .data = &pm8150l_lpg_data },
......
# SPDX-License-Identifier: GPL-2.0-only
config LEDS_SIEMENS_SIMATIC_IPC
tristate "LED driver for Siemens Simatic IPCs"
depends on LEDS_GPIO
depends on SIEMENS_SIMATIC_IPC
help
This option enables support for the LEDs of several Industrial PCs
from Siemens.
To compile this driver as a module, choose M here: the modules
will be called simatic-ipc-leds and simatic-ipc-leds-gpio.
To compile this driver as a module, choose M here: the module
will be called simatic-ipc-leds.
config LEDS_SIEMENS_SIMATIC_IPC_APOLLOLAKE
tristate "LED driver for Siemens Simatic IPCs based on Intel Apollo Lake GPIO"
depends on LEDS_GPIO
depends on PINCTRL_BROXTON
depends on SIEMENS_SIMATIC_IPC
default LEDS_SIEMENS_SIMATIC_IPC
help
This option enables support for the LEDs of several Industrial PCs
from Siemens based on Apollo Lake GPIO i.e. IPC127E.
To compile this driver as a module, choose M here: the module
will be called simatic-ipc-leds-gpio-apollolake.
config LEDS_SIEMENS_SIMATIC_IPC_F7188X
tristate "LED driver for Siemens Simatic IPCs based on Nuvoton GPIO"
depends on LEDS_GPIO
depends on GPIO_F7188X
depends on SIEMENS_SIMATIC_IPC
default LEDS_SIEMENS_SIMATIC_IPC
help
This option enables support for the LEDs of several Industrial PCs
from Siemens based on Nuvoton GPIO i.e. IPC227G.
To compile this driver as a module, choose M here: the module
will be called simatic-ipc-leds-gpio-f7188x.
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC) += simatic-ipc-leds.o
obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC) += simatic-ipc-leds-gpio.o
obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC) += simatic-ipc-leds.o
obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC_APOLLOLAKE) += simatic-ipc-leds-gpio-core.o simatic-ipc-leds-gpio-apollolake.o
obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC_F7188X) += simatic-ipc-leds-gpio-core.o simatic-ipc-leds-gpio-f7188x.o
// SPDX-License-Identifier: GPL-2.0
/*
* Siemens SIMATIC IPC driver for GPIO based LEDs
*
* Copyright (c) Siemens AG, 2023
*
* Author:
* Henning Schild <henning.schild@siemens.com>
*/
#include <linux/gpio/machine.h>
#include <linux/gpio/consumer.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_data/x86/simatic-ipc-base.h>
#include "simatic-ipc-leds-gpio.h"
static struct gpiod_lookup_table simatic_ipc_led_gpio_table = {
.dev_id = "leds-gpio",
.table = {
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 2, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 3, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 4, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 5, GPIO_ACTIVE_LOW),
{} /* Terminating entry */
},
};
static struct gpiod_lookup_table simatic_ipc_led_gpio_table_extra = {
.dev_id = NULL, /* Filled during initialization */
.table = {
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 56, NULL, 6, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 59, NULL, 7, GPIO_ACTIVE_HIGH),
{} /* Terminating entry */
},
};
static int simatic_ipc_leds_gpio_apollolake_probe(struct platform_device *pdev)
{
return simatic_ipc_leds_gpio_probe(pdev, &simatic_ipc_led_gpio_table,
&simatic_ipc_led_gpio_table_extra);
}
static int simatic_ipc_leds_gpio_apollolake_remove(struct platform_device *pdev)
{
return simatic_ipc_leds_gpio_remove(pdev, &simatic_ipc_led_gpio_table,
&simatic_ipc_led_gpio_table_extra);
}
static struct platform_driver simatic_ipc_led_gpio_apollolake_driver = {
.probe = simatic_ipc_leds_gpio_apollolake_probe,
.remove = simatic_ipc_leds_gpio_apollolake_remove,
.driver = {
.name = KBUILD_MODNAME,
},
};
module_platform_driver(simatic_ipc_led_gpio_apollolake_driver);
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" KBUILD_MODNAME);
MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core platform:apollolake-pinctrl");
MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");
......@@ -2,9 +2,9 @@
/*
* Siemens SIMATIC IPC driver for GPIO based LEDs
*
* Copyright (c) Siemens AG, 2022
* Copyright (c) Siemens AG, 2023
*
* Authors:
* Author:
* Henning Schild <henning.schild@siemens.com>
*/
......@@ -15,35 +15,9 @@
#include <linux/platform_device.h>
#include <linux/platform_data/x86/simatic-ipc-base.h>
static struct gpiod_lookup_table *simatic_ipc_led_gpio_table;
static struct gpiod_lookup_table simatic_ipc_led_gpio_table_127e = {
.dev_id = "leds-gpio",
.table = {
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 2, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 3, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 4, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 5, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 56, NULL, 6, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 59, NULL, 7, GPIO_ACTIVE_HIGH),
},
};
#include "simatic-ipc-leds-gpio.h"
static struct gpiod_lookup_table simatic_ipc_led_gpio_table_227g = {
.dev_id = "leds-gpio",
.table = {
GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 1, NULL, 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 2, NULL, 2, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 3, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 4, NULL, 4, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 5, NULL, 5, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-3", 6, NULL, 6, GPIO_ACTIVE_HIGH),
GPIO_LOOKUP_IDX("gpio-f7188x-3", 7, NULL, 7, GPIO_ACTIVE_HIGH),
}
};
static struct platform_device *simatic_leds_pdev;
static const struct gpio_led simatic_ipc_gpio_leds[] = {
{ .name = "red:" LED_FUNCTION_STATUS "-1" },
......@@ -59,39 +33,36 @@ static const struct gpio_led_platform_data simatic_ipc_gpio_leds_pdata = {
.leds = simatic_ipc_gpio_leds,
};
static struct platform_device *simatic_leds_pdev;
static int simatic_ipc_leds_gpio_remove(struct platform_device *pdev)
int simatic_ipc_leds_gpio_remove(struct platform_device *pdev,
struct gpiod_lookup_table *table,
struct gpiod_lookup_table *table_extra)
{
gpiod_remove_lookup_table(simatic_ipc_led_gpio_table);
gpiod_remove_lookup_table(table);
gpiod_remove_lookup_table(table_extra);
platform_device_unregister(simatic_leds_pdev);
return 0;
}
EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_remove);
static int simatic_ipc_leds_gpio_probe(struct platform_device *pdev)
int simatic_ipc_leds_gpio_probe(struct platform_device *pdev,
struct gpiod_lookup_table *table,
struct gpiod_lookup_table *table_extra)
{
const struct simatic_ipc_platform *plat = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
struct gpio_desc *gpiod;
int err;
switch (plat->devmode) {
case SIMATIC_IPC_DEVICE_127E:
if (!IS_ENABLED(CONFIG_PINCTRL_BROXTON))
return -ENODEV;
simatic_ipc_led_gpio_table = &simatic_ipc_led_gpio_table_127e;
break;
case SIMATIC_IPC_DEVICE_227G:
if (!IS_ENABLED(CONFIG_GPIO_F7188X))
return -ENODEV;
request_module("gpio-f7188x");
simatic_ipc_led_gpio_table = &simatic_ipc_led_gpio_table_227g;
break;
default:
return -ENODEV;
}
gpiod_add_lookup_table(simatic_ipc_led_gpio_table);
gpiod_add_lookup_table(table);
simatic_leds_pdev = platform_device_register_resndata(NULL,
"leds-gpio", PLATFORM_DEVID_NONE, NULL, 0,
&simatic_ipc_gpio_leds_pdata,
......@@ -101,8 +72,11 @@ static int simatic_ipc_leds_gpio_probe(struct platform_device *pdev)
goto out;
}
table_extra->dev_id = dev_name(dev);
gpiod_add_lookup_table(table_extra);
/* PM_BIOS_BOOT_N */
gpiod = gpiod_get_index(&simatic_leds_pdev->dev, NULL, 6, GPIOD_OUT_LOW);
gpiod = gpiod_get_index(dev, NULL, 6, GPIOD_OUT_LOW);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto out;
......@@ -110,7 +84,7 @@ static int simatic_ipc_leds_gpio_probe(struct platform_device *pdev)
gpiod_put(gpiod);
/* PM_WDT_OUT */
gpiod = gpiod_get_index(&simatic_leds_pdev->dev, NULL, 7, GPIOD_OUT_LOW);
gpiod = gpiod_get_index(dev, NULL, 7, GPIOD_OUT_LOW);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto out;
......@@ -119,21 +93,12 @@ static int simatic_ipc_leds_gpio_probe(struct platform_device *pdev)
return 0;
out:
simatic_ipc_leds_gpio_remove(pdev);
simatic_ipc_leds_gpio_remove(pdev, table, table_extra);
return err;
}
static struct platform_driver simatic_ipc_led_gpio_driver = {
.probe = simatic_ipc_leds_gpio_probe,
.remove = simatic_ipc_leds_gpio_remove,
.driver = {
.name = KBUILD_MODNAME,
}
};
module_platform_driver(simatic_ipc_led_gpio_driver);
EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_probe);
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" KBUILD_MODNAME);
MODULE_SOFTDEP("pre: platform:leds-gpio");
MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");
// SPDX-License-Identifier: GPL-2.0
/*
* Siemens SIMATIC IPC driver for GPIO based LEDs
*
* Copyright (c) Siemens AG, 2023
*
* Author:
* Henning Schild <henning.schild@siemens.com>
*/
#include <linux/gpio/machine.h>
#include <linux/gpio/consumer.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_data/x86/simatic-ipc-base.h>
#include "simatic-ipc-leds-gpio.h"
static struct gpiod_lookup_table simatic_ipc_led_gpio_table = {
.dev_id = "leds-gpio",
.table = {
GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 1, NULL, 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 2, NULL, 2, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 3, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 4, NULL, 4, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-f7188x-2", 5, NULL, 5, GPIO_ACTIVE_LOW),
{} /* Terminating entry */
},
};
static struct gpiod_lookup_table simatic_ipc_led_gpio_table_extra = {
.dev_id = NULL, /* Filled during initialization */
.table = {
GPIO_LOOKUP_IDX("gpio-f7188x-3", 6, NULL, 6, GPIO_ACTIVE_HIGH),
GPIO_LOOKUP_IDX("gpio-f7188x-3", 7, NULL, 7, GPIO_ACTIVE_HIGH),
{} /* Terminating entry */
},
};
static int simatic_ipc_leds_gpio_f7188x_probe(struct platform_device *pdev)
{
return simatic_ipc_leds_gpio_probe(pdev, &simatic_ipc_led_gpio_table,
&simatic_ipc_led_gpio_table_extra);
}
static int simatic_ipc_leds_gpio_f7188x_remove(struct platform_device *pdev)
{
return simatic_ipc_leds_gpio_remove(pdev, &simatic_ipc_led_gpio_table,
&simatic_ipc_led_gpio_table_extra);
}
static struct platform_driver simatic_ipc_led_gpio_driver = {
.probe = simatic_ipc_leds_gpio_f7188x_probe,
.remove = simatic_ipc_leds_gpio_f7188x_remove,
.driver = {
.name = KBUILD_MODNAME,
},
};
module_platform_driver(simatic_ipc_led_gpio_driver);
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" KBUILD_MODNAME);
MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core gpio_f7188x");
MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");
// SPDX-License-Identifier: GPL-2.0
/*
* Siemens SIMATIC IPC driver for GPIO based LEDs
*
* Copyright (c) Siemens AG, 2023
*
* Author:
* Henning Schild <henning.schild@siemens.com>
*/
#ifndef _SIMATIC_IPC_LEDS_GPIO_H
#define _SIMATIC_IPC_LEDS_GPIO_H
int simatic_ipc_leds_gpio_probe(struct platform_device *pdev,
struct gpiod_lookup_table *table,
struct gpiod_lookup_table *table_extra);
int simatic_ipc_leds_gpio_remove(struct platform_device *pdev,
struct gpiod_lookup_table *table,
struct gpiod_lookup_table *table_extra);
#endif /* _SIMATIC_IPC_LEDS_GPIO_H */
......@@ -126,7 +126,6 @@ static struct platform_driver simatic_ipc_led_driver = {
.name = KBUILD_MODNAME,
}
};
module_platform_driver(simatic_ipc_led_driver);
MODULE_LICENSE("GPL v2");
......
......@@ -19,16 +19,13 @@ DEFINE_LED_TRIGGER(ledtrig_disk_write);
void ledtrig_disk_activity(bool write)
{
unsigned long blink_delay = BLINK_DELAY;
led_trigger_blink_oneshot(ledtrig_disk,
&blink_delay, &blink_delay, 0);
led_trigger_blink_oneshot(ledtrig_disk, BLINK_DELAY, BLINK_DELAY, 0);
if (write)
led_trigger_blink_oneshot(ledtrig_disk_write,
&blink_delay, &blink_delay, 0);
BLINK_DELAY, BLINK_DELAY, 0);
else
led_trigger_blink_oneshot(ledtrig_disk_read,
&blink_delay, &blink_delay, 0);
BLINK_DELAY, BLINK_DELAY, 0);
}
EXPORT_SYMBOL(ledtrig_disk_activity);
......
......@@ -22,12 +22,8 @@ DEFINE_LED_TRIGGER(ledtrig_nand);
void ledtrig_mtd_activity(void)
{
unsigned long blink_delay = BLINK_DELAY;
led_trigger_blink_oneshot(ledtrig_mtd,
&blink_delay, &blink_delay, 0);
led_trigger_blink_oneshot(ledtrig_nand,
&blink_delay, &blink_delay, 0);
led_trigger_blink_oneshot(ledtrig_mtd, BLINK_DELAY, BLINK_DELAY, 0);
led_trigger_blink_oneshot(ledtrig_nand, BLINK_DELAY, BLINK_DELAY, 0);
}
EXPORT_SYMBOL(ledtrig_mtd_activity);
......
......@@ -462,8 +462,7 @@ static int netdev_trig_notify(struct notifier_block *nb,
get_device_state(trigger_data);
fallthrough;
case NETDEV_REGISTER:
if (trigger_data->net_dev)
dev_put(trigger_data->net_dev);
dev_put(trigger_data->net_dev);
dev_hold(dev);
trigger_data->net_dev = dev;
break;
......@@ -594,8 +593,7 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev)
cancel_delayed_work_sync(&trigger_data->work);
if (trigger_data->net_dev)
dev_put(trigger_data->net_dev);
dev_put(trigger_data->net_dev);
kfree(trigger_data);
}
......
......@@ -196,13 +196,10 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
void arcnet_led_event(struct net_device *dev, enum arcnet_led_event event)
{
struct arcnet_local *lp = netdev_priv(dev);
unsigned long led_delay = 350;
unsigned long tx_delay = 50;
switch (event) {
case ARCNET_LED_EVENT_RECON:
led_trigger_blink_oneshot(lp->recon_led_trig,
&led_delay, &led_delay, 0);
led_trigger_blink_oneshot(lp->recon_led_trig, 350, 350, 0);
break;
case ARCNET_LED_EVENT_OPEN:
led_trigger_event(lp->tx_led_trig, LED_OFF);
......@@ -213,8 +210,7 @@ void arcnet_led_event(struct net_device *dev, enum arcnet_led_event event)
led_trigger_event(lp->recon_led_trig, LED_OFF);
break;
case ARCNET_LED_EVENT_TX:
led_trigger_blink_oneshot(lp->tx_led_trig,
&tx_delay, &tx_delay, 0);
led_trigger_blink_oneshot(lp->tx_led_trig, 50, 50, 0);
break;
}
}
......
......@@ -68,9 +68,10 @@ static int register_platform_devices(u32 station_id)
}
if (ledmode != SIMATIC_IPC_DEVICE_NONE) {
if (ledmode == SIMATIC_IPC_DEVICE_127E ||
ledmode == SIMATIC_IPC_DEVICE_227G)
pdevname = KBUILD_MODNAME "_leds_gpio";
if (ledmode == SIMATIC_IPC_DEVICE_127E)
pdevname = KBUILD_MODNAME "_leds_gpio_apollolake";
if (ledmode == SIMATIC_IPC_DEVICE_227G)
pdevname = KBUILD_MODNAME "_leds_gpio_f7188x";
platform_data.devmode = ledmode;
ipc_led_platform_device =
platform_device_register_data(NULL,
......
......@@ -22,8 +22,6 @@
static void power_supply_update_bat_leds(struct power_supply *psy)
{
union power_supply_propval status;
unsigned long delay_on = 0;
unsigned long delay_off = 0;
if (power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
return;
......@@ -43,8 +41,7 @@ static void power_supply_update_bat_leds(struct power_supply *psy)
led_trigger_event(psy->charging_full_trig, LED_FULL);
led_trigger_event(psy->charging_trig, LED_FULL);
led_trigger_event(psy->full_trig, LED_OFF);
led_trigger_blink(psy->charging_blink_full_solid_trig,
&delay_on, &delay_off);
led_trigger_blink(psy->charging_blink_full_solid_trig, 0, 0);
break;
default:
led_trigger_event(psy->charging_full_trig, LED_OFF);
......
......@@ -14,8 +14,6 @@
#define BLINK_DELAY 30
static unsigned long usb_blink_delay = BLINK_DELAY;
DEFINE_LED_TRIGGER(ledtrig_usb_gadget);
DEFINE_LED_TRIGGER(ledtrig_usb_host);
......@@ -32,7 +30,7 @@ void usb_led_activity(enum usb_led_event ev)
break;
}
/* led_trigger_blink_oneshot() handles trig == NULL gracefully */
led_trigger_blink_oneshot(trig, &usb_blink_delay, &usb_blink_delay, 0);
led_trigger_blink_oneshot(trig, BLINK_DELAY, BLINK_DELAY, 0);
}
EXPORT_SYMBOL_GPL(usb_led_activity);
......
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
#ifndef _DT_BINDINGS_LEDS_LP55XX_H
#define _DT_BINDINGS_LEDS_LP55XX_H
#define LP55XX_CP_OFF 0
#define LP55XX_CP_BYPASS 1
#define LP55XX_CP_BOOST 2
#define LP55XX_CP_AUTO 3
#endif /* _DT_BINDINGS_LEDS_LP55XX_H */
......@@ -124,6 +124,10 @@ struct led_classdev {
#define LED_BLINK_INVERT 3
#define LED_BLINK_BRIGHTNESS_CHANGE 4
#define LED_BLINK_DISABLE 5
/* Brightness off also disables hw-blinking so it is a separate action */
#define LED_SET_BRIGHTNESS_OFF 6
#define LED_SET_BRIGHTNESS 7
#define LED_SET_BLINK 8
/* Set LED brightness level
* Must not sleep. Use brightness_set_blocking for drivers
......@@ -147,6 +151,10 @@ struct led_classdev {
* match the values specified exactly.
* Deactivate blinking again when the brightness is set to LED_OFF
* via the brightness_set() callback.
* For led_blink_set_nosleep() the LED core assumes that blink_set
* implementations, of drivers which do not use brightness_set_blocking,
* will not sleep. Therefor if brightness_set_blocking is not set
* this function must not sleep!
*/
int (*blink_set)(struct led_classdev *led_cdev,
unsigned long *delay_on,
......@@ -170,6 +178,8 @@ struct led_classdev {
struct work_struct set_brightness_work;
int delayed_set_value;
unsigned long delayed_delay_on;
unsigned long delayed_delay_off;
#ifdef CONFIG_LEDS_TRIGGERS
/* Protects the trigger data below */
......@@ -315,12 +325,27 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev,
* software blinking if there is no hardware blinking or if
* the LED refuses the passed values.
*
* This function may sleep!
*
* Note that if software blinking is active, simply calling
* led_cdev->brightness_set() will not stop the blinking,
* use led_set_brightness() instead.
*/
void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on,
unsigned long *delay_off);
/**
* led_blink_set_nosleep - set blinking, guaranteed to not sleep
* @led_cdev: the LED to start blinking
* @delay_on: the time it should be on (in ms)
* @delay_off: the time it should ble off (in ms)
*
* This function makes the LED blink and is guaranteed to not sleep. Otherwise
* this is the same as led_blink_set(), see led_blink_set() for details.
*/
void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on,
unsigned long delay_off);
/**
* led_blink_set_oneshot - do a oneshot software blink
* @led_cdev: the LED to start blinking
......@@ -334,6 +359,8 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on,
*
* If invert is set, led blinks for delay_off first, then for
* delay_on and leave the led on after the on-off cycle.
*
* This function is guaranteed not to sleep.
*/
void led_blink_set_oneshot(struct led_classdev *led_cdev,
unsigned long *delay_on, unsigned long *delay_off,
......@@ -476,11 +503,11 @@ void led_trigger_register_simple(const char *name,
struct led_trigger **trigger);
void led_trigger_unregister_simple(struct led_trigger *trigger);
void led_trigger_event(struct led_trigger *trigger, enum led_brightness event);
void led_trigger_blink(struct led_trigger *trigger, unsigned long *delay_on,
unsigned long *delay_off);
void led_trigger_blink(struct led_trigger *trigger, unsigned long delay_on,
unsigned long delay_off);
void led_trigger_blink_oneshot(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off,
unsigned long delay_on,
unsigned long delay_off,
int invert);
void led_trigger_set_default(struct led_classdev *led_cdev);
int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger);
......@@ -530,11 +557,11 @@ static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {}
static inline void led_trigger_event(struct led_trigger *trigger,
enum led_brightness event) {}
static inline void led_trigger_blink(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off) {}
unsigned long delay_on,
unsigned long delay_off) {}
static inline void led_trigger_blink_oneshot(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off,
unsigned long delay_on,
unsigned long delay_off,
int invert) {}
static inline void led_trigger_set_default(struct led_classdev *led_cdev) {}
static inline int led_trigger_set(struct led_classdev *led_cdev,
......
......@@ -73,6 +73,9 @@ struct lp55xx_platform_data {
/* Clock configuration */
u8 clock_mode;
/* Charge pump mode */
u32 charge_pump_mode;
/* optional enable GPIO */
struct gpio_desc *enable_gpiod;
......
......@@ -282,7 +282,7 @@ static void tpt_trig_timer(struct timer_list *t)
}
}
led_trigger_blink(&local->tpt_led, &on, &off);
led_trigger_blink(&local->tpt_led, on, off);
}
const char *
......
......@@ -13,22 +13,18 @@
static inline void ieee80211_led_rx(struct ieee80211_local *local)
{
#ifdef CONFIG_MAC80211_LEDS
unsigned long led_delay = MAC80211_BLINK_DELAY;
if (!atomic_read(&local->rx_led_active))
return;
led_trigger_blink_oneshot(&local->rx_led, &led_delay, &led_delay, 0);
led_trigger_blink_oneshot(&local->rx_led, MAC80211_BLINK_DELAY, MAC80211_BLINK_DELAY, 0);
#endif
}
static inline void ieee80211_led_tx(struct ieee80211_local *local)
{
#ifdef CONFIG_MAC80211_LEDS
unsigned long led_delay = MAC80211_BLINK_DELAY;
if (!atomic_read(&local->tx_led_active))
return;
led_trigger_blink_oneshot(&local->tx_led, &led_delay, &led_delay, 0);
led_trigger_blink_oneshot(&local->tx_led, MAC80211_BLINK_DELAY, MAC80211_BLINK_DELAY, 0);
#endif
}
......
......@@ -43,7 +43,6 @@ led_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_led_info *ledinfo = par->targinfo;
struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
unsigned long led_delay = XT_LED_BLINK_DELAY;
/*
* If "always blink" is enabled, and there's still some time until the
......@@ -52,7 +51,7 @@ led_tg(struct sk_buff *skb, const struct xt_action_param *par)
if ((ledinfo->delay > 0) && ledinfo->always_blink &&
timer_pending(&ledinternal->timer))
led_trigger_blink_oneshot(&ledinternal->netfilter_led_trigger,
&led_delay, &led_delay, 1);
XT_LED_BLINK_DELAY, XT_LED_BLINK_DELAY, 1);
else
led_trigger_event(&ledinternal->netfilter_led_trigger, LED_FULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment