summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-17 08:28:25 -0600
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-17 08:28:25 -0600
commit75caf5940899a33165fb3d521492f3cd6b20c9a7 (patch)
treec35e9aef6d27c3befbf75574207cb722d0e4a106
parented56954cf5a8b7abb530676a073d14f9de661d69 (diff)
parent7cb092a0336c5770656c6742e7a7ce3042c8c44e (diff)
Merge tag 'leds-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds
Pull LED updates from Pavel Machek: "Lee Jones offered his help with maintaining LEDs, thanks a lot. Plus, there are some bugfixes as a bonus" * tag 'leds-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds: leds: MAINTAINERS: include dt-bindings headers leds: qcom,pm8058-led: Convert to DT schema leds: use sysfs_emit() to instead of scnprintf() leds: is31fl319x: Fix setting current limit for is31fl319{0,1,3} MAINTAINERS: Add additional co-maintainer to LEDs leds: lp5523: fix out-of-bounds bug in lp5523_selftest() dt-bindings: leds: Add 'cpuX' to 'linux,default-trigger' led: qcom-lpg: Fix sleeping in atomic leds: max8997: Don't error if there is no pdata leds: lp55xx: remove variable j leds-pca955x: Remove the unused function pca95xx_num_led_regs()
-rw-r--r--Documentation/devicetree/bindings/leds/common.yaml1
-rw-r--r--Documentation/devicetree/bindings/leds/leds-pm8058.txt67
-rw-r--r--Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml57
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml4
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/leds/leds-blinkm.c8
-rw-r--r--drivers/leds/leds-is31fl319x.c3
-rw-r--r--drivers/leds/leds-lm3533.c12
-rw-r--r--drivers/leds/leds-lp5521.c2
-rw-r--r--drivers/leds/leds-lp5523.c27
-rw-r--r--drivers/leds/leds-lp55xx-common.c7
-rw-r--r--drivers/leds/leds-max8997.c7
-rw-r--r--drivers/leds/leds-pca955x.c6
-rw-r--r--drivers/leds/rgb/leds-qcom-lpg.c18
-rw-r--r--drivers/leds/trigger/ledtrig-pattern.c2
15 files changed, 108 insertions, 115 deletions
diff --git a/Documentation/devicetree/bindings/leds/common.yaml b/Documentation/devicetree/bindings/leds/common.yaml
index 3c14a98430e1..f5c57a580078 100644
--- a/Documentation/devicetree/bindings/leds/common.yaml
+++ b/Documentation/devicetree/bindings/leds/common.yaml
@@ -100,6 +100,7 @@ properties:
- pattern
# LED is triggered by SD/MMC activity
- pattern: "^mmc[0-9]+$"
+ - pattern: "^cpu[0-9]*$"
led-pattern:
description: |
diff --git a/Documentation/devicetree/bindings/leds/leds-pm8058.txt b/Documentation/devicetree/bindings/leds/leds-pm8058.txt
deleted file mode 100644
index 89584c49aab2..000000000000
--- a/Documentation/devicetree/bindings/leds/leds-pm8058.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-Qualcomm PM8058 LED driver
-
-The Qualcomm PM8058 is a multi-functional device which contains
-an LED driver block for up to six LEDs: three normal LEDs, two
-"flash" LEDs and one "keypad backlight" LED. The names are
-quoted because sometimes these LED drivers are used for wildly
-different things than flash or keypad backlight: their names
-are more of a suggestion than a hard-wired usecase.
-
-Hardware-wise the different LEDs support slightly different
-output currents. The "flash" LEDs do not need to charge nor
-do they support external triggers. They are just powerful LED
-drivers.
-
-The LEDs appear as children to the PM8058 device, with the
-proper compatible string. For the PM8058 bindings see:
-mfd/qcom-pm8xxx.txt.
-
-Each LED is represented as a sub-node of the syscon device. Each
-node's name represents the name of the corresponding LED.
-
-LED sub-node properties:
-
-Required properties:
-- compatible: one of
- "qcom,pm8058-led" (for the normal LEDs at 0x131, 0x132 and 0x133)
- "qcom,pm8058-keypad-led" (for the "keypad" LED at 0x48)
- "qcom,pm8058-flash-led" (for the "flash" LEDs at 0x49 and 0xFB)
-
-Optional properties:
-- label: see Documentation/devicetree/bindings/leds/common.txt
-- default-state: see Documentation/devicetree/bindings/leds/common.txt
-- linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt
-
-Example:
-
-qcom,ssbi@500000 {
- pmicintc: pmic@0 {
- compatible = "qcom,pm8058";
- led@48 {
- compatible = "qcom,pm8058-keypad-led";
- reg = <0x48>;
- label = "pm8050:white:keypad";
- default-state = "off";
- };
- led@131 {
- compatible = "qcom,pm8058-led";
- reg = <0x131>;
- label = "pm8058:red";
- default-state = "off";
- };
- led@132 {
- compatible = "qcom,pm8058-led";
- reg = <0x132>;
- label = "pm8058:yellow";
- default-state = "off";
- linux,default-trigger = "mmc0";
- };
- led@133 {
- compatible = "qcom,pm8058-led";
- reg = <0x133>;
- label = "pm8058:green";
- default-state = "on";
- linux,default-trigger = "heartbeat";
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml b/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml
new file mode 100644
index 000000000000..fa03e73622d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/qcom,pm8058-led.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PM8058 PMIC LED
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+description: |
+ The Qualcomm PM8058 contains an LED block for up to six LEDs:: three normal
+ LEDs, two "flash" LEDs and one "keypad backlight" LED. The names are quoted
+ because sometimes these LED drivers are used for wildly different things than
+ flash or keypad backlight:: their names are more of a suggestion than a
+ hard-wired usecase.
+
+ Hardware-wise the different LEDs support slightly different output currents.
+ The "flash" LEDs do not need to charge nor do they support external triggers.
+ They are just powerful LED drivers.
+
+allOf:
+ - $ref: common.yaml#
+
+properties:
+ compatible:
+ enum:
+ - qcom,pm8058-led
+ - qcom,pm8058-keypad-led
+ - qcom,pm8058-flash-led
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/leds/common.h>
+
+ pmic {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@131 {
+ compatible = "qcom,pm8058-led";
+ reg = <0x131>;
+ label = "pm8058:red";
+ color = <LED_COLOR_ID_RED>;
+ default-state = "off";
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
index 61bd0b3ce02f..bd6e4aecfe2b 100644
--- a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
@@ -39,6 +39,10 @@ properties:
interrupt-controller: true
patternProperties:
+ "led@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/leds/qcom,pm8058-led.yaml#
+
"rtc@[0-9a-f]+$":
type: object
$ref: "../rtc/qcom-pm8xxx-rtc.yaml"
diff --git a/MAINTAINERS b/MAINTAINERS
index afe0d838b552..28cc7862a187 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11732,11 +11732,13 @@ F: scripts/leaking_addresses.pl
LED SUBSYSTEM
M: Pavel Machek <pavel@ucw.cz>
+M: Lee Jones <lee@kernel.org>
L: linux-leds@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
F: Documentation/devicetree/bindings/leds/
F: drivers/leds/
+F: include/dt-bindings/leds/
F: include/linux/leds.h
LEGACY EEPROM DRIVER
diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c
index 3fb6a2fdaefa..e19cc8a7b7ca 100644
--- a/drivers/leds/leds-blinkm.c
+++ b/drivers/leds/leds-blinkm.c
@@ -139,11 +139,11 @@ static ssize_t show_color_common(struct device *dev, char *buf, int color)
return ret;
switch (color) {
case RED:
- return scnprintf(buf, PAGE_SIZE, "%02X\n", data->red);
+ return sysfs_emit(buf, "%02X\n", data->red);
case GREEN:
- return scnprintf(buf, PAGE_SIZE, "%02X\n", data->green);
+ return sysfs_emit(buf, "%02X\n", data->green);
case BLUE:
- return scnprintf(buf, PAGE_SIZE, "%02X\n", data->blue);
+ return sysfs_emit(buf, "%02X\n", data->blue);
default:
return -EINVAL;
}
@@ -253,7 +253,7 @@ static DEVICE_ATTR_RW(blue);
static ssize_t test_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- return scnprintf(buf, PAGE_SIZE,
+ return sysfs_emit(buf,
"#Write into test to start test sequence!#\n");
}
diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
index 52b59b62f437..b2f4c4ec7c56 100644
--- a/drivers/leds/leds-is31fl319x.c
+++ b/drivers/leds/leds-is31fl319x.c
@@ -38,6 +38,7 @@
#define IS31FL3190_CURRENT_uA_MIN 5000
#define IS31FL3190_CURRENT_uA_DEFAULT 42000
#define IS31FL3190_CURRENT_uA_MAX 42000
+#define IS31FL3190_CURRENT_SHIFT 2
#define IS31FL3190_CURRENT_MASK GENMASK(4, 2)
#define IS31FL3190_CURRENT_5_mA 0x02
#define IS31FL3190_CURRENT_10_mA 0x01
@@ -553,7 +554,7 @@ static int is31fl319x_probe(struct i2c_client *client)
is31fl3196_db_to_gain(is31->audio_gain_db));
else
regmap_update_bits(is31->regmap, IS31FL3190_CURRENT, IS31FL3190_CURRENT_MASK,
- is31fl3190_microamp_to_cs(dev, aggregated_led_microamp));
+ is31fl3190_microamp_to_cs(dev, aggregated_led_microamp) << IS31FL3190_CURRENT_SHIFT);
for (i = 0; i < is31->cdef->num_leds; i++) {
struct is31fl319x_led *led = &is31->leds[i];
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index 43d5970d96aa..bcd414eb4724 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -314,7 +314,7 @@ static ssize_t show_id(struct device *dev,
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct lm3533_led *led = to_lm3533_led(led_cdev);
- return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
+ return sysfs_emit(buf, "%d\n", led->id);
}
/*
@@ -344,7 +344,7 @@ static ssize_t show_risefalltime(struct device *dev,
if (ret)
return ret;
- return scnprintf(buf, PAGE_SIZE, "%x\n", val);
+ return sysfs_emit(buf, "%x\n", val);
}
static ssize_t show_risetime(struct device *dev,
@@ -415,7 +415,7 @@ static ssize_t show_als_channel(struct device *dev,
channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
- return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
+ return sysfs_emit(buf, "%u\n", channel);
}
static ssize_t store_als_channel(struct device *dev,
@@ -465,7 +465,7 @@ static ssize_t show_als_en(struct device *dev,
enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
- return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
+ return sysfs_emit(buf, "%d\n", enable);
}
static ssize_t store_als_en(struct device *dev,
@@ -518,7 +518,7 @@ static ssize_t show_linear(struct device *dev,
else
linear = 0;
- return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
+ return sysfs_emit(buf, "%x\n", linear);
}
static ssize_t store_linear(struct device *dev,
@@ -564,7 +564,7 @@ static ssize_t show_pwm(struct device *dev,
if (ret)
return ret;
- return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+ return sysfs_emit(buf, "%u\n", val);
}
static ssize_t store_pwm(struct device *dev,
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 7ff20c260504..19478d9c19a7 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -469,7 +469,7 @@ static ssize_t lp5521_selftest(struct device *dev,
ret = lp5521_run_selftest(chip, buf);
mutex_unlock(&chip->lock);
- return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK");
+ return sysfs_emit(buf, "%s\n", ret ? "FAIL" : "OK");
}
/* device attributes */
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 369d40b0b65b..e08e3de1428d 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -581,8 +581,8 @@ static ssize_t lp5523_selftest(struct device *dev,
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
struct lp55xx_platform_data *pdata = chip->pdata;
- int i, ret, pos = 0;
- u8 status, adc, vdd;
+ int ret, pos = 0;
+ u8 status, adc, vdd, i;
mutex_lock(&chip->lock);
@@ -612,20 +612,21 @@ static ssize_t lp5523_selftest(struct device *dev,
vdd--; /* There may be some fluctuation in measurement */
- for (i = 0; i < LP5523_MAX_LEDS; i++) {
- /* Skip non-existing channels */
+ for (i = 0; i < pdata->num_channels; i++) {
+ /* Skip disabled channels */
if (pdata->led_config[i].led_current == 0)
continue;
/* Set default current */
- lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
+ lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
pdata->led_config[i].led_current);
- lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0xff);
+ lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
+ 0xff);
/* let current stabilize 2 - 4ms before measurements start */
usleep_range(2000, 4000);
lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL,
- LP5523_EN_LEDTEST | i);
+ LP5523_EN_LEDTEST | led->chan_nr);
/* ADC conversion time is 2.7 ms typically */
usleep_range(3000, 6000);
ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
@@ -633,20 +634,22 @@ static ssize_t lp5523_selftest(struct device *dev,
goto fail;
if (!(status & LP5523_LEDTEST_DONE))
- usleep_range(3000, 6000);/* Was not ready. Wait. */
+ usleep_range(3000, 6000); /* Was not ready. Wait. */
ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc);
if (ret < 0)
goto fail;
if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
- pos += sprintf(buf + pos, "LED %d FAIL\n", i);
+ pos += sprintf(buf + pos, "LED %d FAIL\n",
+ led->chan_nr);
- lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0x00);
+ lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
+ 0x00);
/* Restore current */
- lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
- led->led_current);
+ lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
+ led->led_current);
led++;
}
if (pos == 0)
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 9fdfc1b9a1a0..c1940964067a 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -88,7 +88,7 @@ static ssize_t led_current_show(struct device *dev,
{
struct lp55xx_led *led = dev_to_lp55xx_led(dev);
- return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
+ return sysfs_emit(buf, "%d\n", led->led_current);
}
static ssize_t led_current_store(struct device *dev,
@@ -121,7 +121,7 @@ static ssize_t max_current_show(struct device *dev,
{
struct lp55xx_led *led = dev_to_lp55xx_led(dev);
- return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
+ return sysfs_emit(buf, "%d\n", led->max_current);
}
static DEVICE_ATTR_RW(led_current);
@@ -166,7 +166,7 @@ static int lp55xx_init_led(struct lp55xx_led *led,
struct mc_subled *mc_led_info;
struct led_classdev *led_cdev;
char name[32];
- int i, j = 0;
+ int i;
int ret;
if (chan >= max_channel) {
@@ -201,7 +201,6 @@ static int lp55xx_init_led(struct lp55xx_led *led,
pdata->led_config[chan].color_id[i];
mc_led_info[i].channel =
pdata->led_config[chan].output_num[i];
- j++;
}
led->mc_cdev.subled_info = mc_led_info;
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
index c0bddb33888d..c8d7f55c9dec 100644
--- a/drivers/leds/leds-max8997.c
+++ b/drivers/leds/leds-max8997.c
@@ -238,11 +238,6 @@ static int max8997_led_probe(struct platform_device *pdev)
char name[20];
int ret = 0;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "no platform data\n");
- return -ENODEV;
- }
-
led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
if (led == NULL)
return -ENOMEM;
@@ -258,7 +253,7 @@ static int max8997_led_probe(struct platform_device *pdev)
led->iodev = iodev;
/* initialize mode and brightness according to platform_data */
- if (pdata->led_pdata) {
+ if (pdata && pdata->led_pdata) {
u8 mode = 0, brightness = 0;
mode = pdata->led_pdata->mode[led->id];
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 81aaf21212d7..33ec4543fb4f 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -145,12 +145,6 @@ static inline int pca95xx_num_input_regs(int bits)
return (bits + 7) / 8;
}
-/* 4 bits per LED selector register */
-static inline int pca95xx_num_led_regs(int bits)
-{
- return (bits + 3) / 4;
-}
-
/*
* Return an LED selector register value based on an existing one, with
* the appropriate 2-bit state value set for the given LED number (0-3).
diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
index 02f51cc61837..c1a56259226f 100644
--- a/drivers/leds/rgb/leds-qcom-lpg.c
+++ b/drivers/leds/rgb/leds-qcom-lpg.c
@@ -602,8 +602,8 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
lpg_lut_sync(lpg, lut_mask);
}
-static void lpg_brightness_single_set(struct led_classdev *cdev,
- enum led_brightness value)
+static int lpg_brightness_single_set(struct led_classdev *cdev,
+ enum led_brightness value)
{
struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
struct mc_subled info;
@@ -614,10 +614,12 @@ static void lpg_brightness_single_set(struct led_classdev *cdev,
lpg_brightness_set(led, cdev, &info);
mutex_unlock(&led->lpg->lock);
+
+ return 0;
}
-static void lpg_brightness_mc_set(struct led_classdev *cdev,
- enum led_brightness value)
+static int lpg_brightness_mc_set(struct led_classdev *cdev,
+ enum led_brightness value)
{
struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
@@ -628,6 +630,8 @@ static void lpg_brightness_mc_set(struct led_classdev *cdev,
lpg_brightness_set(led, cdev, mc->subled_info);
mutex_unlock(&led->lpg->lock);
+
+ return 0;
}
static int lpg_blink_set(struct lpg_led *led,
@@ -1118,7 +1122,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
led->mcdev.num_colors = num_channels;
cdev = &led->mcdev.led_cdev;
- cdev->brightness_set = lpg_brightness_mc_set;
+ 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 */
@@ -1132,7 +1136,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
return ret;
cdev = &led->cdev;
- cdev->brightness_set = lpg_brightness_single_set;
+ 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 */
@@ -1151,7 +1155,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
else
cdev->brightness = LED_OFF;
- cdev->brightness_set(cdev, cdev->brightness);
+ cdev->brightness_set_blocking(cdev, cdev->brightness);
init_data.fwnode = of_fwnode_handle(np);
diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c
index 43a265dc4696..885ca63f383f 100644
--- a/drivers/leds/trigger/ledtrig-pattern.c
+++ b/drivers/leds/trigger/ledtrig-pattern.c
@@ -155,7 +155,7 @@ static ssize_t repeat_show(struct device *dev, struct device_attribute *attr,
mutex_unlock(&data->lock);
- return scnprintf(buf, PAGE_SIZE, "%d\n", repeat);
+ return sysfs_emit(buf, "%d\n", repeat);
}
static ssize_t repeat_store(struct device *dev, struct device_attribute *attr,