2023-11-30 01:37:32

by Anjelique Melendez

[permalink] [raw]
Subject: [PATCH v7 0/7] Add support for LUT PPG

In certain PMICs, LUT pattern and LPG configuration is stored in SDAM
modules instead of LUT peripheral. This feature is called PPG.

This change series adds support for PPG. Thanks!
Changes since v6:
- Patch 2/7
- Removed required by constraint on PPG dt properties
Changes since v5:
- Patch 4/7
- Update logic so that multicolor led device triggers pattern
on all LEDs at the same time
- Update nitpicks from Lee
- Patch 5/7
- Update nitpicks from Lee
Changes since v4:
- Patch 3/7
- Get rid of r/w helpers
- Use regmap_read_poll_timeout() in qcom_pbs_wait_for_ack()
- Update error path in qcom_pbs_trigger_event()
- Fix reverse christmas tree
- Patch 4/7
- Get rid of r/w helpers
- Update variables to use "sdam" instead of "nvmem"
- Fix comments
- Fix reverse christmas tree
- Update lpg_pattern_set() logic
- Patch 5/7
- Removed sdam_lut_base from lpg_data
Changes since v3:
- Patch 4/7
- Fix function returns
- Move register definition to top of file
- Revert max_brightness and probe accidental changes
- Combine init_sdam() and parse_sdam()
- Change error prints in probe to use dev_err_probe
- Remove ppg_en variable
- Update when pbs triggers are set/cleared
- Patch 6/7
- Remove use of nvmem_count
- Move register definition to top of file
- Remove lpg_get_sdam_lut_idx()
Changes since v2:
- Patch 1/7
- Fix dt_binding_check error
- Rename binding file to match compatible
- Iclude SoC specific comptaibles
- Patch 2/7
- Update nvmem-names list
- Patch 3/7
- Update EXPORT_SYMBOL to EXPORT_SYMBOL_GPL
- Fix return/break logic in qcom_pbs_wait_for_ack()
- Update iterators to be int
- Add constants
- Fix function calls in qcom_pbs_trigger_event()
- Remove unnessary comments
- Return -EPROBE_DEFER from get_pbs_client_device()
Changes since v1:
- Patch 1/7
- Fix dt_binding_check errors
- Update binding description
- Path 2/7
- Fix dt_binding_check errors
- Update per variant constraints
- Update nvmem description
- Patch 3/7
- Update get_pbs_client_device()
- Drop use of printk
- Remove unused function

Anjelique Melendez (7):
dt-bindings: soc: qcom: Add qcom,pbs bindings
dt-bindings: leds: leds-qcom-lpg: Add support for LPG PPG
soc: qcom: add QCOM PBS driver
leds: rgb: leds-qcom-lpg: Add support for PPG through single SDAM
leds: rgb: leds-qcom-lpg: Update PMI632 lpg_data to support PPG
leds: rgb: leds-qcom-lpg: Include support for PPG with dedicated LUT
SDAM
leds: rgb: Update PM8350C lpg_data to support two-nvmem PPG Scheme

.../bindings/leds/leds-qcom-lpg.yaml | 82 ++++-
.../bindings/soc/qcom/qcom,pbs.yaml | 46 +++
drivers/leds/rgb/leds-qcom-lpg.c | 344 ++++++++++++++++--
drivers/soc/qcom/Kconfig | 9 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/qcom-pbs.c | 243 +++++++++++++
include/linux/soc/qcom/qcom-pbs.h | 30 ++
7 files changed, 726 insertions(+), 29 deletions(-)
create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,pbs.yaml
create mode 100644 drivers/soc/qcom/qcom-pbs.c
create mode 100644 include/linux/soc/qcom/qcom-pbs.h

--
2.41.0


2023-11-30 01:37:35

by Anjelique Melendez

[permalink] [raw]
Subject: [PATCH v7 2/7] dt-bindings: leds: leds-qcom-lpg: Add support for LPG PPG

Update leds-qcom-lpg binding to support LPG PPG.

Signed-off-by: Anjelique Melendez <[email protected]>
---
.../bindings/leds/leds-qcom-lpg.yaml | 82 ++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
index ea84ad426df1..6649ca2ec805 100644
--- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
+++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
@@ -11,7 +11,7 @@ maintainers:

description: >
The Qualcomm Light Pulse Generator consists of three different hardware blocks;
- a ramp generator with lookup table, the light pulse generator and a three
+ a ramp generator with lookup table (LUT), the light pulse generator and a three
channel current sink. These blocks are found in a wide range of Qualcomm PMICs.

properties:
@@ -63,6 +63,29 @@ properties:
- description: dtest line to attach
- description: flags for the attachment

+ nvmem:
+ description: >
+ This property is required for PMICs that supports PPG, which is when a
+ PMIC stores LPG per-channel data and pattern LUT in SDAM modules instead
+ of in a LUT peripheral. For PMICs, such as PM8350C, per-channel data
+ and pattern LUT is separated into 2 SDAM modules. In that case, phandles
+ to both SDAM modules need to be specified.
+ minItems: 1
+ maxItems: 2
+
+ nvmem-names:
+ minItems: 1
+ items:
+ - const: lpg_chan_sdam
+ - const: lut_sdam
+
+ qcom,pbs:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: >
+ Phandle of the Qualcomm Programmable Boot Sequencer node (PBS).
+ PBS node is used to trigger LPG pattern sequences for PMICs that support
+ single SDAM PPG.
+
multi-led:
type: object
$ref: leds-class-multicolor.yaml#
@@ -106,6 +129,32 @@ required:

additionalProperties: false

+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,pmi632-lpg
+ then:
+ properties:
+ nvmem:
+ maxItems: 1
+ nvmem-names:
+ maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,pm8350c-pwm
+ - qcom,pm8550-pwm
+ then:
+ properties:
+ nvmem:
+ minItems: 2
+ nvmem-names:
+ minItems: 2
+
examples:
- |
#include <dt-bindings/leds/common.h>
@@ -191,4 +240,35 @@ examples:
compatible = "qcom,pm8916-pwm";
#pwm-cells = <2>;
};
+ - |
+ #include <dt-bindings/leds/common.h>
+
+ led-controller {
+ compatible = "qcom,pmi632-lpg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #pwm-cells = <2>;
+ nvmem-names = "lpg_chan_sdam";
+ nvmem = <&pmi632_sdam_7>;
+ qcom,pbs = <&pmi632_pbs_client3>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ label = "red";
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "green";
+ };
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_BLUE>;
+ label = "blue";
+ };
+ };
+
...
--
2.41.0

2023-11-30 01:37:36

by Anjelique Melendez

[permalink] [raw]
Subject: [PATCH v7 7/7] leds: rgb: Update PM8350C lpg_data to support two-nvmem PPG Scheme

Update the pm8350c lpg_data struct so that pm8350c devices are treated as
PWM devices that support two-nvmem PPG scheme.

Signed-off-by: Anjelique Melendez <[email protected]>
Reviewed-by: Lee Jones <[email protected]>
---
drivers/leds/rgb/leds-qcom-lpg.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
index 471b5b3e22ea..0cb079e6e2e6 100644
--- a/drivers/leds/rgb/leds-qcom-lpg.c
+++ b/drivers/leds/rgb/leds-qcom-lpg.c
@@ -1780,11 +1780,13 @@ static const struct lpg_data pm8150l_lpg_data = {
static const struct lpg_data pm8350c_pwm_data = {
.triled_base = 0xef00,

+ .lut_size = 122,
+
.num_channels = 4,
.channels = (const struct lpg_channel_data[]) {
- { .base = 0xe800, .triled_mask = BIT(7) },
- { .base = 0xe900, .triled_mask = BIT(6) },
- { .base = 0xea00, .triled_mask = BIT(5) },
+ { .base = 0xe800, .triled_mask = BIT(7), .sdam_offset = 0x48 },
+ { .base = 0xe900, .triled_mask = BIT(6), .sdam_offset = 0x56 },
+ { .base = 0xea00, .triled_mask = BIT(5), .sdam_offset = 0x64 },
{ .base = 0xeb00 },
},
};
--
2.41.0

2023-11-30 01:37:37

by Anjelique Melendez

[permalink] [raw]
Subject: [PATCH v7 4/7] leds: rgb: leds-qcom-lpg: Add support for PPG through single SDAM

In some PMICs like pmi632, the pattern look up table (LUT) and LPG
configuration is stored in a single SDAM module instead of LUT
peripheral. This feature is called PPG. PPG uses Qualcomm Programmable
Boot Sequencer (PBS) inorder to trigger pattern sequences for PMICs.

Signed-off-by: Anjelique Melendez <[email protected]>
Tested-by: Luca Weiss <[email protected]>
---
drivers/leds/rgb/leds-qcom-lpg.c | 264 ++++++++++++++++++++++++++++---
1 file changed, 242 insertions(+), 22 deletions(-)

diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
index 68d82a682bf6..a3e4adffb8df 100644
--- a/drivers/leds/rgb/leds-qcom-lpg.c
+++ b/drivers/leds/rgb/leds-qcom-lpg.c
@@ -8,11 +8,13 @@
#include <linux/bitfield.h>
#include <linux/led-class-multicolor.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/slab.h>
+#include <linux/soc/qcom/qcom-pbs.h>

#define LPG_SUBTYPE_REG 0x05
#define LPG_SUBTYPE_LPG 0x2
@@ -39,6 +41,8 @@
#define PWM_SEC_ACCESS_REG 0xd0
#define PWM_DTEST_REG(x) (0xe2 + (x) - 1)

+#define SDAM_REG_PBS_SEQ_EN 0x42
+
#define TRI_LED_SRC_SEL 0x45
#define TRI_LED_EN_CTL 0x46
#define TRI_LED_ATC_CTL 0x47
@@ -48,9 +52,25 @@

#define LPG_RESOLUTION_9BIT BIT(9)
#define LPG_RESOLUTION_15BIT BIT(15)
+#define PPG_MAX_LED_BRIGHTNESS 255
+
#define LPG_MAX_M 7
#define LPG_MAX_PREDIV 6

+#define DEFAULT_TICK_DURATION_US 7800
+#define RAMP_STEP_DURATION(x) (((x) * 1000 / DEFAULT_TICK_DURATION_US) & 0xff)
+
+/* LPG common config settings for PPG */
+#define SDAM_REG_RAMP_STEP_DURATION 0x47
+#define SDAM_LPG_SDAM_LUT_PATTERN_OFFSET 0x80
+
+/* LPG per channel config settings for PPG */
+#define SDAM_LUT_EN_OFFSET 0x0
+#define SDAM_PATTERN_CONFIG_OFFSET 0x1
+#define SDAM_END_INDEX_OFFSET 0x3
+#define SDAM_START_INDEX_OFFSET 0x4
+#define SDAM_PBS_SCRATCH_LUT_COUNTER_OFFSET 0x6
+
struct lpg_channel;
struct lpg_data;

@@ -64,6 +84,9 @@ struct lpg_data;
* @lut_base: base address of the LUT block (optional)
* @lut_size: number of entries in the LUT block
* @lut_bitmap: allocation bitmap for LUT entries
+ * @pbs_dev: PBS device
+ * @lpg_chan_sdam: LPG SDAM peripheral device
+ * @pbs_en_bitmap: bitmap for tracking PBS triggers
* @triled_base: base address of the TRILED block (optional)
* @triled_src: power-source for the TRILED
* @triled_has_atc_ctl: true if there is TRI_LED_ATC_CTL register
@@ -85,6 +108,10 @@ struct lpg {
u32 lut_size;
unsigned long *lut_bitmap;

+ struct pbs_dev *pbs_dev;
+ struct nvmem_device *lpg_chan_sdam;
+ unsigned long pbs_en_bitmap;
+
u32 triled_base;
u32 triled_src;
bool triled_has_atc_ctl;
@@ -101,6 +128,7 @@ struct lpg {
* @triled_mask: mask in TRILED to enable this channel
* @lut_mask: mask in LUT to start pattern generator for this channel
* @subtype: PMIC hardware block subtype
+ * @sdam_offset: channel offset in LPG SDAM
* @in_use: channel is exposed to LED framework
* @color: color of the LED attached to this channel
* @dtest_line: DTEST line for output, or 0 if disabled
@@ -129,6 +157,7 @@ struct lpg_channel {
unsigned int triled_mask;
unsigned int lut_mask;
unsigned int subtype;
+ u32 sdam_offset;

bool in_use;

@@ -178,10 +207,12 @@ struct lpg_led {

/**
* struct lpg_channel_data - per channel initialization data
+ * @sdam_offset: Channel offset in LPG SDAM
* @base: base address for PWM channel registers
* @triled_mask: bitmask for controlling this channel in TRILED
*/
struct lpg_channel_data {
+ unsigned int sdam_offset;
unsigned int base;
u8 triled_mask;
};
@@ -206,6 +237,52 @@ struct lpg_data {
const struct lpg_channel_data *channels;
};

+#define PBS_SW_TRIG_BIT BIT(0)
+
+static int lpg_clear_pbs_trigger(struct lpg *lpg, unsigned int lut_mask)
+{
+ u8 val = 0;
+ int rc;
+
+ lpg->pbs_en_bitmap &= (~lut_mask);
+ if (!lpg->pbs_en_bitmap) {
+ rc = nvmem_device_write(lpg->lpg_chan_sdam, SDAM_REG_PBS_SEQ_EN, 1, &val);
+ if (rc < 0)
+ return rc;
+ }
+
+ return 0;
+}
+
+static int lpg_set_pbs_trigger(struct lpg *lpg, unsigned int lut_mask)
+{
+ u8 val = PBS_SW_TRIG_BIT;
+ int rc;
+
+ if (!lpg->pbs_en_bitmap) {
+ rc = nvmem_device_write(lpg->lpg_chan_sdam, SDAM_REG_PBS_SEQ_EN, 1, &val);
+ if (rc < 0)
+ return rc;
+
+ rc = qcom_pbs_trigger_event(lpg->pbs_dev, val);
+ if (rc < 0)
+ return rc;
+ }
+ lpg->pbs_en_bitmap |= lut_mask;
+
+ return 0;
+}
+
+static int lpg_sdam_configure_triggers(struct lpg_channel *chan, u8 set_trig)
+{
+ u32 addr = SDAM_LUT_EN_OFFSET + chan->sdam_offset;
+
+ if (!chan->lpg->lpg_chan_sdam)
+ return 0;
+
+ return nvmem_device_write(chan->lpg->lpg_chan_sdam, addr, 1, &set_trig);
+}
+
static int triled_set(struct lpg *lpg, unsigned int mask, unsigned int enable)
{
/* Skip if we don't have a triled block */
@@ -216,6 +293,40 @@ static int triled_set(struct lpg *lpg, unsigned int mask, unsigned int enable)
mask, enable);
}

+static int lpg_lut_store_sdam(struct lpg *lpg, struct led_pattern *pattern,
+ size_t len, unsigned int *lo_idx, unsigned int *hi_idx)
+{
+ unsigned int idx;
+ u8 brightness;
+ int i, rc;
+ u16 addr;
+
+ if (len > lpg->lut_size) {
+ dev_err(lpg->dev, "Pattern length (%zu) exceeds maximum pattern length (%d)\n",
+ len, lpg->lut_size);
+ return -EINVAL;
+ }
+
+ idx = bitmap_find_next_zero_area(lpg->lut_bitmap, lpg->lut_size, 0, len, 0);
+ if (idx >= lpg->lut_size)
+ return -ENOSPC;
+
+ for (i = 0; i < len; i++) {
+ brightness = pattern[i].brightness;
+ addr = SDAM_LPG_SDAM_LUT_PATTERN_OFFSET + i + idx;
+ rc = nvmem_device_write(lpg->lpg_chan_sdam, addr, 1, &brightness);
+ if (rc < 0)
+ return rc;
+ }
+
+ bitmap_set(lpg->lut_bitmap, idx, len);
+
+ *lo_idx = idx;
+ *hi_idx = idx + len - 1;
+
+ return 0;
+}
+
static int lpg_lut_store(struct lpg *lpg, struct led_pattern *pattern,
size_t len, unsigned int *lo_idx, unsigned int *hi_idx)
{
@@ -256,6 +367,9 @@ static void lpg_lut_free(struct lpg *lpg, unsigned int lo_idx, unsigned int hi_i

static int lpg_lut_sync(struct lpg *lpg, unsigned int mask)
{
+ if (!lpg->lut_base)
+ return 0;
+
return regmap_write(lpg->map, lpg->lut_base + RAMP_CONTROL_REG, mask);
}

@@ -462,6 +576,28 @@ static void lpg_apply_pwm_value(struct lpg_channel *chan)
#define LPG_PATTERN_CONFIG_PAUSE_HI BIT(1)
#define LPG_PATTERN_CONFIG_PAUSE_LO BIT(0)

+static void lpg_sdam_apply_lut_control(struct lpg_channel *chan)
+{
+ struct nvmem_device *lpg_chan_sdam = chan->lpg->lpg_chan_sdam;
+ unsigned int lo_idx = chan->pattern_lo_idx;
+ unsigned int hi_idx = chan->pattern_hi_idx;
+ u8 val = 0, conf = 0;
+
+ if (!chan->ramp_enabled || chan->pattern_lo_idx == chan->pattern_hi_idx)
+ return;
+
+ if (!chan->ramp_oneshot)
+ conf |= LPG_PATTERN_CONFIG_REPEAT;
+
+ nvmem_device_write(lpg_chan_sdam, SDAM_PBS_SCRATCH_LUT_COUNTER_OFFSET + chan->sdam_offset, 1, &val);
+ nvmem_device_write(lpg_chan_sdam, SDAM_PATTERN_CONFIG_OFFSET + chan->sdam_offset, 1, &conf);
+ nvmem_device_write(lpg_chan_sdam, SDAM_END_INDEX_OFFSET + chan->sdam_offset, 1, &hi_idx);
+ nvmem_device_write(lpg_chan_sdam, SDAM_START_INDEX_OFFSET + chan->sdam_offset, 1, &lo_idx);
+
+ val = RAMP_STEP_DURATION(chan->ramp_tick_ms);
+ nvmem_device_write(lpg_chan_sdam, SDAM_REG_RAMP_STEP_DURATION, 1, &val);
+}
+
static void lpg_apply_lut_control(struct lpg_channel *chan)
{
struct lpg *lpg = chan->lpg;
@@ -597,7 +733,10 @@ static void lpg_apply(struct lpg_channel *chan)
lpg_apply_pwm_value(chan);
lpg_apply_control(chan);
lpg_apply_sync(chan);
- lpg_apply_lut_control(chan);
+ if (chan->lpg->lpg_chan_sdam)
+ lpg_sdam_apply_lut_control(chan);
+ else
+ lpg_apply_lut_control(chan);
lpg_enable_glitch(chan);
}

@@ -622,6 +761,7 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
chan->ramp_enabled = false;
} else if (chan->pattern_lo_idx != chan->pattern_hi_idx) {
lpg_calc_freq(chan, NSEC_PER_MSEC);
+ lpg_sdam_configure_triggers(chan, 1);

chan->enabled = true;
chan->ramp_enabled = true;
@@ -649,8 +789,10 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
triled_set(lpg, triled_mask, triled_enabled);

/* Trigger start of ramp generator(s) */
- if (lut_mask)
+ if (lut_mask) {
lpg_lut_sync(lpg, lut_mask);
+ lpg_set_pbs_trigger(lpg, lut_mask);
+ }
}

static int lpg_brightness_single_set(struct led_classdev *cdev,
@@ -836,18 +978,23 @@ static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern,
* If the specified pattern is a palindrome the ping pong mode is
* enabled. In this scenario the delta_t of the middle entry (i.e. the
* last in the programmed pattern) determines the "high pause".
+ *
+ * SDAM-based devices do not support "ping-pong", "low pause" or "high pause"
*/

/* Detect palindromes and use "ping pong" to reduce LUT usage */
- for (i = 0; i < len / 2; i++) {
- brightness_a = pattern[i].brightness;
- brightness_b = pattern[len - i - 1].brightness;
-
- if (brightness_a != brightness_b) {
- ping_pong = false;
- break;
+ if (lpg->lut_base) {
+ for (i = 0; i < len / 2; i++) {
+ brightness_a = pattern[i].brightness;
+ brightness_b = pattern[len - i - 1].brightness;
+
+ if (brightness_a != brightness_b) {
+ ping_pong = false;
+ break;
+ }
}
- }
+ } else
+ ping_pong = false;

/* The pattern length to be written to the LUT */
if (ping_pong)
@@ -875,12 +1022,26 @@ static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern,
if (delta_t >= BIT(9))
goto out_free_pattern;

- /* Find "low pause" and "high pause" in the pattern */
- lo_pause = pattern[0].delta_t;
- hi_pause = pattern[actual_len - 1].delta_t;
+ /*
+ * Find "low pause" and "high pause" in the pattern in the LUT case.
+ * SDAM-based devices require equal duration of all steps
+ */
+ if (lpg->lut_base) {
+ lo_pause = pattern[0].delta_t;
+ hi_pause = pattern[actual_len - 1].delta_t;
+ } else {
+ if (delta_t != pattern[0].delta_t || delta_t != pattern[actual_len - 1].delta_t)
+ goto out_free_pattern;
+ }
+

mutex_lock(&lpg->lock);
- ret = lpg_lut_store(lpg, pattern, actual_len, &lo_idx, &hi_idx);
+
+ if (lpg->lut_base)
+ ret = lpg_lut_store(lpg, pattern, actual_len, &lo_idx, &hi_idx);
+ else
+ ret = lpg_lut_store_sdam(lpg, pattern, actual_len, &lo_idx, &hi_idx);
+
if (ret < 0)
goto out_unlock;

@@ -928,7 +1089,12 @@ static int lpg_pattern_mc_set(struct led_classdev *cdev,
{
struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
- int ret;
+ unsigned int triled_mask = 0;
+ int ret, i;
+
+ for (i = 0; i < led->num_channels; i++)
+ triled_mask |= led->channels[i]->triled_mask;
+ triled_set(led->lpg, triled_mask, 0);

ret = lpg_pattern_set(led, pattern, len, repeat);
if (ret < 0)
@@ -953,6 +1119,8 @@ static int lpg_pattern_clear(struct lpg_led *led)

for (i = 0; i < led->num_channels; i++) {
chan = led->channels[i];
+ lpg_sdam_configure_triggers(chan, 0);
+ lpg_clear_pbs_trigger(chan->lpg, chan->lut_mask);
chan->pattern_lo_idx = 0;
chan->pattern_hi_idx = 0;
}
@@ -1187,8 +1355,8 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
cdev->brightness_set_blocking = lpg_brightness_mc_set;
cdev->blink_set = lpg_blink_mc_set;

- /* Register pattern accessors only if we have a LUT block */
- if (lpg->lut_base) {
+ /* Register pattern accessors if we have a LUT block or when using PPG */
+ if (lpg->lut_base || lpg->lpg_chan_sdam) {
cdev->pattern_set = lpg_pattern_mc_set;
cdev->pattern_clear = lpg_pattern_mc_clear;
}
@@ -1201,15 +1369,19 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
cdev->brightness_set_blocking = lpg_brightness_single_set;
cdev->blink_set = lpg_blink_single_set;

- /* Register pattern accessors only if we have a LUT block */
- if (lpg->lut_base) {
+ /* Register pattern accessors if we have a LUT block or when using PPG */
+ if (lpg->lut_base || lpg->lpg_chan_sdam) {
cdev->pattern_set = lpg_pattern_single_set;
cdev->pattern_clear = lpg_pattern_single_clear;
}
}

cdev->default_trigger = of_get_property(np, "linux,default-trigger", NULL);
- cdev->max_brightness = LPG_RESOLUTION_9BIT - 1;
+
+ if (lpg->lpg_chan_sdam)
+ cdev->max_brightness = PPG_MAX_LED_BRIGHTNESS;
+ else
+ cdev->max_brightness = LPG_RESOLUTION_9BIT - 1;

if (!of_property_read_string(np, "default-state", &state) &&
!strcmp(state, "on"))
@@ -1250,6 +1422,7 @@ static int lpg_init_channels(struct lpg *lpg)
chan->base = data->channels[i].base;
chan->triled_mask = data->channels[i].triled_mask;
chan->lut_mask = BIT(i);
+ chan->sdam_offset = data->channels[i].sdam_offset;

regmap_read(lpg->map, chan->base + LPG_SUBTYPE_REG, &chan->subtype);
}
@@ -1296,11 +1469,12 @@ static int lpg_init_lut(struct lpg *lpg)
{
const struct lpg_data *data = lpg->data;

- if (!data->lut_base)
+ if (!data->lut_size)
return 0;

- lpg->lut_base = data->lut_base;
lpg->lut_size = data->lut_size;
+ if (data->lut_base)
+ lpg->lut_base = data->lut_base;

lpg->lut_bitmap = devm_bitmap_zalloc(lpg->dev, lpg->lut_size, GFP_KERNEL);
if (!lpg->lut_bitmap)
@@ -1309,6 +1483,48 @@ static int lpg_init_lut(struct lpg *lpg)
return 0;
}

+static int lpg_init_sdam(struct lpg *lpg)
+{
+ int i, sdam_count, rc;
+ u8 val = 0;
+
+ sdam_count = of_property_count_strings(lpg->dev->of_node, "nvmem-names");
+ if (sdam_count <= 0)
+ return 0;
+
+ /* Get the SDAM device for LPG/LUT config */
+ lpg->lpg_chan_sdam = devm_nvmem_device_get(lpg->dev, "lpg_chan_sdam");
+ if (IS_ERR(lpg->lpg_chan_sdam))
+ return dev_err_probe(lpg->dev, PTR_ERR(lpg->lpg_chan_sdam),
+ "Failed to get LPG chan SDAM device\n");
+
+ lpg->pbs_dev = get_pbs_client_device(lpg->dev);
+ if (IS_ERR(lpg->pbs_dev))
+ return dev_err_probe(lpg->dev, PTR_ERR(lpg->pbs_dev),
+ "Failed to get PBS client device\n");
+
+ for (i = 0; i < lpg->num_channels; i++) {
+ struct lpg_channel *chan = &lpg->channels[i];
+
+ if (chan->sdam_offset) {
+ rc = nvmem_device_write(lpg->lpg_chan_sdam,
+ SDAM_PBS_SCRATCH_LUT_COUNTER_OFFSET + chan->sdam_offset, 1, &val);
+ if (rc < 0)
+ return rc;
+
+ rc = lpg_sdam_configure_triggers(chan, 0);
+ if (rc < 0)
+ return rc;
+
+ rc = lpg_clear_pbs_trigger(chan->lpg, chan->lut_mask);
+ if (rc < 0)
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
static int lpg_probe(struct platform_device *pdev)
{
struct device_node *np;
@@ -1345,6 +1561,10 @@ static int lpg_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

+ ret = lpg_init_sdam(lpg);
+ if (ret < 0)
+ return ret;
+
ret = lpg_init_lut(lpg);
if (ret < 0)
return ret;
--
2.41.0

2023-11-30 08:30:26

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v7 2/7] dt-bindings: leds: leds-qcom-lpg: Add support for LPG PPG

On 30/11/2023 02:36, Anjelique Melendez wrote:
> Update leds-qcom-lpg binding to support LPG PPG.
>
> Signed-off-by: Anjelique Melendez <[email protected]>
> ---

Reviewed-by: Krzysztof Kozlowski <[email protected]>

Best regards,
Krzysztof

2023-11-30 14:22:54

by Dan Carpenter

[permalink] [raw]
Subject: Re: [PATCH v7 4/7] leds: rgb: leds-qcom-lpg: Add support for PPG through single SDAM

Hi Anjelique,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Anjelique-Melendez/dt-bindings-soc-qcom-Add-qcom-pbs-bindings/20231130-094701
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20231130013615.14287-5-quic_amelende%40quicinc.com
patch subject: [PATCH v7 4/7] leds: rgb: leds-qcom-lpg: Add support for PPG through single SDAM
config: csky-randconfig-r071-20231130 (https://download.01.org/0day-ci/archive/20231130/[email protected]/config)
compiler: csky-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20231130/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Reported-by: Dan Carpenter <[email protected]>
| Closes: https://lore.kernel.org/r/[email protected]/

smatch warnings:
drivers/leds/rgb/leds-qcom-lpg.c:1055 lpg_pattern_set() error: uninitialized symbol 'lo_pause'.
drivers/leds/rgb/leds-qcom-lpg.c:1056 lpg_pattern_set() error: uninitialized symbol 'hi_pause'.

vim +/lo_pause +1055 drivers/leds/rgb/leds-qcom-lpg.c

e98a860f65428a Bjorn Andersson 2022-05-23 904 static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern,
24e2d05d1b6898 Bjorn Andersson 2022-03-03 905 u32 len, int repeat)
24e2d05d1b6898 Bjorn Andersson 2022-03-03 906 {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 907 struct lpg_channel *chan;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 908 struct lpg *lpg = led->lpg;
e98a860f65428a Bjorn Andersson 2022-05-23 909 struct led_pattern *pattern;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 910 unsigned int brightness_a;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 911 unsigned int brightness_b;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 912 unsigned int actual_len;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 913 unsigned int hi_pause;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 914 unsigned int lo_pause;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 915 unsigned int delta_t;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 916 unsigned int lo_idx;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 917 unsigned int hi_idx;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 918 unsigned int i;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 919 bool ping_pong = true;
e98a860f65428a Bjorn Andersson 2022-05-23 920 int ret = -EINVAL;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 921
24e2d05d1b6898 Bjorn Andersson 2022-03-03 922 /* Hardware only support oneshot or indefinite loops */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 923 if (repeat != -1 && repeat != 1)
24e2d05d1b6898 Bjorn Andersson 2022-03-03 924 return -EINVAL;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 925
e98a860f65428a Bjorn Andersson 2022-05-23 926 /*
e98a860f65428a Bjorn Andersson 2022-05-23 927 * The standardized leds-trigger-pattern format defines that the
e98a860f65428a Bjorn Andersson 2022-05-23 928 * brightness of the LED follows a linear transition from one entry
e98a860f65428a Bjorn Andersson 2022-05-23 929 * in the pattern to the next, over the given delta_t time. It
e98a860f65428a Bjorn Andersson 2022-05-23 930 * describes that the way to perform instant transitions a zero-length
e98a860f65428a Bjorn Andersson 2022-05-23 931 * entry should be added following a pattern entry.
e98a860f65428a Bjorn Andersson 2022-05-23 932 *
e98a860f65428a Bjorn Andersson 2022-05-23 933 * The LPG hardware is only able to perform the latter (no linear
e98a860f65428a Bjorn Andersson 2022-05-23 934 * transitions), so require each entry in the pattern to be followed by
e98a860f65428a Bjorn Andersson 2022-05-23 935 * a zero-length transition.
e98a860f65428a Bjorn Andersson 2022-05-23 936 */
e98a860f65428a Bjorn Andersson 2022-05-23 937 if (len % 2)
e98a860f65428a Bjorn Andersson 2022-05-23 938 return -EINVAL;
e98a860f65428a Bjorn Andersson 2022-05-23 939
e98a860f65428a Bjorn Andersson 2022-05-23 940 pattern = kcalloc(len / 2, sizeof(*pattern), GFP_KERNEL);
e98a860f65428a Bjorn Andersson 2022-05-23 941 if (!pattern)
e98a860f65428a Bjorn Andersson 2022-05-23 942 return -ENOMEM;
e98a860f65428a Bjorn Andersson 2022-05-23 943
e98a860f65428a Bjorn Andersson 2022-05-23 944 for (i = 0; i < len; i += 2) {
e98a860f65428a Bjorn Andersson 2022-05-23 945 if (led_pattern[i].brightness != led_pattern[i + 1].brightness)
e98a860f65428a Bjorn Andersson 2022-05-23 946 goto out_free_pattern;
e98a860f65428a Bjorn Andersson 2022-05-23 947 if (led_pattern[i + 1].delta_t != 0)
e98a860f65428a Bjorn Andersson 2022-05-23 948 goto out_free_pattern;
e98a860f65428a Bjorn Andersson 2022-05-23 949
e98a860f65428a Bjorn Andersson 2022-05-23 950 pattern[i / 2].brightness = led_pattern[i].brightness;
e98a860f65428a Bjorn Andersson 2022-05-23 951 pattern[i / 2].delta_t = led_pattern[i].delta_t;
e98a860f65428a Bjorn Andersson 2022-05-23 952 }
e98a860f65428a Bjorn Andersson 2022-05-23 953
e98a860f65428a Bjorn Andersson 2022-05-23 954 len /= 2;
e98a860f65428a Bjorn Andersson 2022-05-23 955
24e2d05d1b6898 Bjorn Andersson 2022-03-03 956 /*
24e2d05d1b6898 Bjorn Andersson 2022-03-03 957 * Specifying a pattern of length 1 causes the hardware to iterate
24e2d05d1b6898 Bjorn Andersson 2022-03-03 958 * through the entire LUT, so prohibit this.
24e2d05d1b6898 Bjorn Andersson 2022-03-03 959 */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 960 if (len < 2)
e98a860f65428a Bjorn Andersson 2022-05-23 961 goto out_free_pattern;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 962
24e2d05d1b6898 Bjorn Andersson 2022-03-03 963 /*
24e2d05d1b6898 Bjorn Andersson 2022-03-03 964 * The LPG plays patterns with at a fixed pace, a "low pause" can be
24e2d05d1b6898 Bjorn Andersson 2022-03-03 965 * used to stretch the first delay of the pattern and a "high pause"
24e2d05d1b6898 Bjorn Andersson 2022-03-03 966 * the last one.
24e2d05d1b6898 Bjorn Andersson 2022-03-03 967 *
24e2d05d1b6898 Bjorn Andersson 2022-03-03 968 * In order to save space the pattern can be played in "ping pong"
24e2d05d1b6898 Bjorn Andersson 2022-03-03 969 * mode, in which the pattern is first played forward, then "high
24e2d05d1b6898 Bjorn Andersson 2022-03-03 970 * pause" is applied, then the pattern is played backwards and finally
24e2d05d1b6898 Bjorn Andersson 2022-03-03 971 * the "low pause" is applied.
24e2d05d1b6898 Bjorn Andersson 2022-03-03 972 *
24e2d05d1b6898 Bjorn Andersson 2022-03-03 973 * The middle elements of the pattern are used to determine delta_t and
24e2d05d1b6898 Bjorn Andersson 2022-03-03 974 * the "low pause" and "high pause" multipliers are derrived from this.
24e2d05d1b6898 Bjorn Andersson 2022-03-03 975 *
24e2d05d1b6898 Bjorn Andersson 2022-03-03 976 * The first element in the pattern is used to determine "low pause".
24e2d05d1b6898 Bjorn Andersson 2022-03-03 977 *
24e2d05d1b6898 Bjorn Andersson 2022-03-03 978 * If the specified pattern is a palindrome the ping pong mode is
24e2d05d1b6898 Bjorn Andersson 2022-03-03 979 * enabled. In this scenario the delta_t of the middle entry (i.e. the
24e2d05d1b6898 Bjorn Andersson 2022-03-03 980 * last in the programmed pattern) determines the "high pause".
05c1d2a258599b Anjelique Melendez 2023-11-29 981 *
05c1d2a258599b Anjelique Melendez 2023-11-29 982 * SDAM-based devices do not support "ping-pong", "low pause" or "high pause"
24e2d05d1b6898 Bjorn Andersson 2022-03-03 983 */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 984
24e2d05d1b6898 Bjorn Andersson 2022-03-03 985 /* Detect palindromes and use "ping pong" to reduce LUT usage */
05c1d2a258599b Anjelique Melendez 2023-11-29 986 if (lpg->lut_base) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 987 for (i = 0; i < len / 2; i++) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 988 brightness_a = pattern[i].brightness;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 989 brightness_b = pattern[len - i - 1].brightness;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 990
24e2d05d1b6898 Bjorn Andersson 2022-03-03 991 if (brightness_a != brightness_b) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 992 ping_pong = false;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 993 break;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 994 }
24e2d05d1b6898 Bjorn Andersson 2022-03-03 995 }
05c1d2a258599b Anjelique Melendez 2023-11-29 996 } else
05c1d2a258599b Anjelique Melendez 2023-11-29 997 ping_pong = false;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 998
24e2d05d1b6898 Bjorn Andersson 2022-03-03 999 /* The pattern length to be written to the LUT */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1000 if (ping_pong)
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1001 actual_len = (len + 1) / 2;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1002 else
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1003 actual_len = len;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1004
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1005 /*
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1006 * Validate that all delta_t in the pattern are the same, with the
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1007 * exception of the middle element in case of ping_pong.
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1008 */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1009 delta_t = pattern[1].delta_t;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1010 for (i = 2; i < len; i++) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1011 if (pattern[i].delta_t != delta_t) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1012 /*
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1013 * Allow last entry in the full or shortened pattern to
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1014 * specify hi pause. Reject other variations.
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1015 */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1016 if (i != actual_len - 1)
e98a860f65428a Bjorn Andersson 2022-05-23 1017 goto out_free_pattern;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1018 }
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1019 }
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1020
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1021 /* LPG_RAMP_DURATION_REG is a 9bit */
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1022 if (delta_t >= BIT(9))
e98a860f65428a Bjorn Andersson 2022-05-23 1023 goto out_free_pattern;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1024
05c1d2a258599b Anjelique Melendez 2023-11-29 1025 /*
05c1d2a258599b Anjelique Melendez 2023-11-29 1026 * Find "low pause" and "high pause" in the pattern in the LUT case.
05c1d2a258599b Anjelique Melendez 2023-11-29 1027 * SDAM-based devices require equal duration of all steps
05c1d2a258599b Anjelique Melendez 2023-11-29 1028 */
05c1d2a258599b Anjelique Melendez 2023-11-29 1029 if (lpg->lut_base) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1030 lo_pause = pattern[0].delta_t;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1031 hi_pause = pattern[actual_len - 1].delta_t;
05c1d2a258599b Anjelique Melendez 2023-11-29 1032 } else {
05c1d2a258599b Anjelique Melendez 2023-11-29 1033 if (delta_t != pattern[0].delta_t || delta_t != pattern[actual_len - 1].delta_t)
05c1d2a258599b Anjelique Melendez 2023-11-29 1034 goto out_free_pattern;

lo_pause and hi_pause are not set on this else path

05c1d2a258599b Anjelique Melendez 2023-11-29 1035 }
05c1d2a258599b Anjelique Melendez 2023-11-29 1036
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1037
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1038 mutex_lock(&lpg->lock);
05c1d2a258599b Anjelique Melendez 2023-11-29 1039
05c1d2a258599b Anjelique Melendez 2023-11-29 1040 if (lpg->lut_base)
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1041 ret = lpg_lut_store(lpg, pattern, actual_len, &lo_idx, &hi_idx);
05c1d2a258599b Anjelique Melendez 2023-11-29 1042 else
05c1d2a258599b Anjelique Melendez 2023-11-29 1043 ret = lpg_lut_store_sdam(lpg, pattern, actual_len, &lo_idx, &hi_idx);
05c1d2a258599b Anjelique Melendez 2023-11-29 1044
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1045 if (ret < 0)
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1046 goto out_unlock;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1047
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1048 for (i = 0; i < led->num_channels; i++) {
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1049 chan = led->channels[i];
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1050
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1051 chan->ramp_tick_ms = delta_t;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1052 chan->ramp_ping_pong = ping_pong;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1053 chan->ramp_oneshot = repeat != -1;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1054
24e2d05d1b6898 Bjorn Andersson 2022-03-03 @1055 chan->ramp_lo_pause_ms = lo_pause;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 @1056 chan->ramp_hi_pause_ms = hi_pause;
^^^^^^^^

24e2d05d1b6898 Bjorn Andersson 2022-03-03 1057
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1058 chan->pattern_lo_idx = lo_idx;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1059 chan->pattern_hi_idx = hi_idx;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1060 }
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1061
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1062 out_unlock:
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1063 mutex_unlock(&lpg->lock);
e98a860f65428a Bjorn Andersson 2022-05-23 1064 out_free_pattern:
e98a860f65428a Bjorn Andersson 2022-05-23 1065 kfree(pattern);
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1066
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1067 return ret;
24e2d05d1b6898 Bjorn Andersson 2022-03-03 1068 }

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2023-12-07 14:26:47

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH v7 4/7] leds: rgb: leds-qcom-lpg: Add support for PPG through single SDAM

On Thu, 30 Nov 2023, Dan Carpenter wrote:

> Hi Anjelique,
>
> kernel test robot noticed the following build warnings:
>
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Anjelique-Melendez/dt-bindings-soc-qcom-Add-qcom-pbs-bindings/20231130-094701
> base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> patch link: https://lore.kernel.org/r/20231130013615.14287-5-quic_amelende%40quicinc.com
> patch subject: [PATCH v7 4/7] leds: rgb: leds-qcom-lpg: Add support for PPG through single SDAM
> config: csky-randconfig-r071-20231130 (https://download.01.org/0day-ci/archive/20231130/[email protected]/config)
> compiler: csky-linux-gcc (GCC) 13.2.0
> reproduce: (https://download.01.org/0day-ci/archive/20231130/[email protected]/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <[email protected]>
> | Reported-by: Dan Carpenter <[email protected]>
> | Closes: https://lore.kernel.org/r/[email protected]/
>
> smatch warnings:
> drivers/leds/rgb/leds-qcom-lpg.c:1055 lpg_pattern_set() error: uninitialized symbol 'lo_pause'.
> drivers/leds/rgb/leds-qcom-lpg.c:1056 lpg_pattern_set() error: uninitialized symbol 'hi_pause'.

FYI, I'll not review this set until these are fixed.

--
Lee Jones [李琼斯]