From 8f886de18a39d714989a74bfb1f96da4b4263772 Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 1 Feb 2018 08:10:34 +0000 Subject: [PATCH 1/7] leds: leds-mlxcpld: Allow compilation for 32 bit arch It makes leds-mlxcpld available for 32 bit architecture. Signed-off-by: Vadim Pasternak Reported-by: Jiri Pirko Signed-off-by: Jacek Anaszewski --- drivers/leds/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 3e763d2a0cb3..fe52436a7db0 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -688,7 +688,7 @@ config LEDS_PM8058 config LEDS_MLXCPLD tristate "LED support for the Mellanox boards" - depends on X86_64 && DMI + depends on X86 && DMI depends on LEDS_CLASS help This option enabled support for the LEDs on the Mellanox From 6204f03d3f5428254ecb6c6e813a7244c8707346 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 1 Feb 2018 21:26:34 +0100 Subject: [PATCH 2/7] leds: Clarify supported chips by LM355x driver Clarify which controllers are supported by which driver. Reported-by: Andy Shevchenko Signed-off-by: Pavel Machek Signed-off-by: Jacek Anaszewski --- drivers/leds/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index fe52436a7db0..a3fdf83b8ff9 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -69,7 +69,7 @@ config LEDS_APU module will be called leds-apu. config LEDS_AS3645A - tristate "AS3645A LED flash controller support" + tristate "AS3645A and LM3555 LED flash controllers support" depends on I2C && LEDS_CLASS_FLASH depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS help @@ -594,12 +594,12 @@ config LEDS_MAX8997 MAXIM MAX8997 PMIC. config LEDS_LM355x - tristate "LED support for LM355x Chips, LM3554 and LM3556" + tristate "LED support for LM3554 and LM3556 chips" depends on LEDS_CLASS && I2C select REGMAP_I2C help - This option enables support for LEDs connected to LM355x. - LM355x includes Torch, Flash and Indicator functions. + This option enables support for LEDs connected to LM3554 + and LM3556. It includes Torch, Flash and Indicator functions. config LEDS_OT200 tristate "LED support for the Bachmann OT200" From 54b6c127240bd4b3023b6f8cbff898050356e5a1 Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 15 Feb 2018 18:11:37 +0000 Subject: [PATCH 3/7] leds: fix Kconfig text for MLXCPLD, SYSCON, MC13783, NETXBIG It fixes grammatical errors in Kconfig file for LEDS_SYSCON, LEDS_MLXCPLD, LEDS_MC13783, LEDS_NETXBIG. Signed-off-by: Vadim Pasternak Signed-off-by: Jacek Anaszewski --- drivers/leds/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a3fdf83b8ff9..4b95aeda2c01 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -521,7 +521,7 @@ config LEDS_MC13783 depends on LEDS_CLASS depends on MFD_MC13XXX help - This option enable support for on-chip LED drivers found + This option enables support for on-chip LED drivers found on Freescale Semiconductor MC13783/MC13892/MC34708 PMIC. config LEDS_NS2 @@ -544,7 +544,7 @@ config LEDS_NETXBIG depends on MACH_KIRKWOOD default y help - This option enable support for LEDs found on the LaCie 2Big + This option enables support for LEDs found on the LaCie 2Big and 5Big Network v2 boards. The LEDs are wired to a CPLD and are controlled through a GPIO extension bus. @@ -674,7 +674,7 @@ config LEDS_SYSCON depends on MFD_SYSCON depends on OF help - This option enabled support for the LEDs on syscon type + This option enables support for the LEDs on syscon type devices. This will only work with device tree enabled devices. @@ -691,8 +691,8 @@ config LEDS_MLXCPLD depends on X86 && DMI depends on LEDS_CLASS help - This option enabled support for the LEDs on the Mellanox - boards. Say Y to enabled these. + This option enables support for the LEDs on the Mellanox + boards. Say Y to enable these. config LEDS_USER tristate "Userspace LED support" From 386570d76f2f25a347a7118fa54315d56b46e7be Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 15 Feb 2018 23:37:50 +0000 Subject: [PATCH 4/7] leds: add driver for support Mellanox regmap LEDs for BMC and x86 platform Driver obtains LED devices according to system configuration and creates devices in form: "devicename:color:function", like The full path is to be: /sys/class/leds/mlxreg\:status\:amber/brightness After timer trigger activation: echo timer > /sys/class/leds/mlxreg\:status\:amber/trigger Attributes for LED blinking will appaer in sysfs infrastructure: /sys/class/leds/mlxreg\:status\:amber/delay_off /sys/class/leds/mlxreg\:status\:amber/delay_on LED setting is controlled through the on-board programmable devices, which exports its register map. This device could be attached to any bus type, for which register mapping is supported. Signed-off-by: Vadim Pasternak Acked-by: Pavel Machek Signed-off-by: Jacek Anaszewski --- MAINTAINERS | 1 + drivers/leds/Kconfig | 9 ++ drivers/leds/Makefile | 1 + drivers/leds/leds-mlxreg.c | 281 +++++++++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+) create mode 100644 drivers/leds/leds-mlxreg.c diff --git a/MAINTAINERS b/MAINTAINERS index 3bdc260e36b7..e458da68948f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9003,6 +9003,7 @@ M: Vadim Pasternak L: linux-leds@vger.kernel.org S: Supported F: drivers/leds/leds-mlxcpld.c +F: drivers/leds/leds-mlxreg.c F: Documentation/leds/leds-mlxcpld.txt MELLANOX PLATFORM DRIVER diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 4b95aeda2c01..2c896c0e69e1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -694,6 +694,15 @@ config LEDS_MLXCPLD This option enables support for the LEDs on the Mellanox boards. Say Y to enable these. +config LEDS_MLXREG + tristate "LED support for the Mellanox switches management control" + depends on LEDS_CLASS + help + This option enables support for the LEDs on the Mellanox Ethernet and + InfiniBand switches. The driver can be activated by the platform device + device add call. Say Y to enable these. To compile this driver as a + module, choose 'M' here: the module will be called leds-mlxreg. + config LEDS_USER tristate "Userspace LED support" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 987884a5b9a5..91eca81cae82 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_LEDS_IS31FL319X) += leds-is31fl319x.o obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o +obj-$(CONFIG_LEDS_MLXREG) += leds-mlxreg.o obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c new file mode 100644 index 000000000000..1ee48cb21df9 --- /dev/null +++ b/drivers/leds/leds-mlxreg.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// +// Copyright (c) 2018 Mellanox Technologies. All rights reserved. +// Copyright (c) 2018 Vadim Pasternak + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Codes for LEDs. */ +#define MLXREG_LED_OFFSET_BLINK_3HZ 0x01 /* Offset from solid: 3Hz blink */ +#define MLXREG_LED_OFFSET_BLINK_6HZ 0x02 /* Offset from solid: 6Hz blink */ +#define MLXREG_LED_IS_OFF 0x00 /* Off */ +#define MLXREG_LED_RED_SOLID 0x05 /* Solid red */ +#define MLXREG_LED_GREEN_SOLID 0x0D /* Solid green */ +#define MLXREG_LED_AMBER_SOLID 0x09 /* Solid amber */ +#define MLXREG_LED_BLINK_3HZ 167 /* ~167 msec off/on - HW support */ +#define MLXREG_LED_BLINK_6HZ 83 /* ~83 msec off/on - HW support */ + +/** + * struct mlxreg_led_data - led control data: + * + * @data: led configuration data; + * @led_classdev: led class data; + * @base_color: base led color (other colors have constant offset from base); + * @led_data: led data; + * @data_parent: pointer to private device control data of parent; + */ +struct mlxreg_led_data { + struct mlxreg_core_data *data; + struct led_classdev led_cdev; + u8 base_color; + void *data_parent; + char led_cdev_name[MLXREG_CORE_LABEL_MAX_SIZE]; +}; + +#define cdev_to_priv(c) container_of(c, struct mlxreg_led_data, led_cdev) + +/** + * struct mlxreg_led_priv_data - platform private data: + * + * @pdev: platform device; + * @pdata: platform data; + * @access_lock: mutex for attribute IO access; + */ +struct mlxreg_led_priv_data { + struct platform_device *pdev; + struct mlxreg_core_platform_data *pdata; + struct mutex access_lock; /* protect IO operations */ +}; + +static int +mlxreg_led_store_hw(struct mlxreg_led_data *led_data, u8 vset) +{ + struct mlxreg_led_priv_data *priv = led_data->data_parent; + struct mlxreg_core_platform_data *led_pdata = priv->pdata; + struct mlxreg_core_data *data = led_data->data; + u32 regval; + u32 nib; + int ret; + + /* + * Each LED is controlled through low or high nibble of the relevant + * register byte. Register offset is specified by off parameter. + * Parameter vset provides color code: 0x0 for off, 0x5 for solid red, + * 0x6 for 3Hz blink red, 0xd for solid green, 0xe for 3Hz blink + * green. + * Parameter mask specifies which nibble is used for specific LED: mask + * 0xf0 - lower nibble is to be used (bits from 0 to 3), mask 0x0f - + * higher nibble (bits from 4 to 7). + */ + mutex_lock(&priv->access_lock); + + ret = regmap_read(led_pdata->regmap, data->reg, ®val); + if (ret) + goto access_error; + + nib = (ror32(data->mask, data->bit) == 0xf0) ? rol32(vset, data->bit) : + rol32(vset, data->bit + 4); + regval = (regval & data->mask) | nib; + + ret = regmap_write(led_pdata->regmap, data->reg, regval); + +access_error: + mutex_unlock(&priv->access_lock); + + return ret; +} + +static enum led_brightness +mlxreg_led_get_hw(struct mlxreg_led_data *led_data) +{ + struct mlxreg_led_priv_data *priv = led_data->data_parent; + struct mlxreg_core_platform_data *led_pdata = priv->pdata; + struct mlxreg_core_data *data = led_data->data; + u32 regval; + int err; + + /* + * Each LED is controlled through low or high nibble of the relevant + * register byte. Register offset is specified by off parameter. + * Parameter vset provides color code: 0x0 for off, 0x5 for solid red, + * 0x6 for 3Hz blink red, 0xd for solid green, 0xe for 3Hz blink + * green. + * Parameter mask specifies which nibble is used for specific LED: mask + * 0xf0 - lower nibble is to be used (bits from 0 to 3), mask 0x0f - + * higher nibble (bits from 4 to 7). + */ + err = regmap_read(led_pdata->regmap, data->reg, ®val); + if (err < 0) { + dev_warn(led_data->led_cdev.dev, "Failed to get current brightness, error: %d\n", + err); + /* Assume the LED is OFF */ + return LED_OFF; + } + + regval = regval & ~data->mask; + regval = (ror32(data->mask, data->bit) == 0xf0) ? ror32(regval, + data->bit) : ror32(regval, data->bit + 4); + if (regval >= led_data->base_color && + regval <= (led_data->base_color + MLXREG_LED_OFFSET_BLINK_6HZ)) + return LED_FULL; + + return LED_OFF; +} + +static int +mlxreg_led_brightness_set(struct led_classdev *cled, enum led_brightness value) +{ + struct mlxreg_led_data *led_data = cdev_to_priv(cled); + + if (value) + return mlxreg_led_store_hw(led_data, led_data->base_color); + else + return mlxreg_led_store_hw(led_data, MLXREG_LED_IS_OFF); +} + +static enum led_brightness +mlxreg_led_brightness_get(struct led_classdev *cled) +{ + struct mlxreg_led_data *led_data = cdev_to_priv(cled); + + return mlxreg_led_get_hw(led_data); +} + +static int +mlxreg_led_blink_set(struct led_classdev *cled, unsigned long *delay_on, + unsigned long *delay_off) +{ + struct mlxreg_led_data *led_data = cdev_to_priv(cled); + int err; + + /* + * HW supports two types of blinking: full (6Hz) and half (3Hz). + * For delay on/off zero LED is setting to solid color. For others + * combination blinking is to be controlled by the software timer. + */ + if (!(*delay_on == 0 && *delay_off == 0) && + !(*delay_on == MLXREG_LED_BLINK_3HZ && + *delay_off == MLXREG_LED_BLINK_3HZ) && + !(*delay_on == MLXREG_LED_BLINK_6HZ && + *delay_off == MLXREG_LED_BLINK_6HZ)) + return -EINVAL; + + if (*delay_on == MLXREG_LED_BLINK_6HZ) + err = mlxreg_led_store_hw(led_data, led_data->base_color + + MLXREG_LED_OFFSET_BLINK_6HZ); + else if (*delay_on == MLXREG_LED_BLINK_3HZ) + err = mlxreg_led_store_hw(led_data, led_data->base_color + + MLXREG_LED_OFFSET_BLINK_3HZ); + else + err = mlxreg_led_store_hw(led_data, led_data->base_color); + + return err; +} + +static int mlxreg_led_config(struct mlxreg_led_priv_data *priv) +{ + struct mlxreg_core_platform_data *led_pdata = priv->pdata; + struct mlxreg_core_data *data = led_pdata->data; + struct mlxreg_led_data *led_data; + struct led_classdev *led_cdev; + enum led_brightness brightness; + int i; + int err; + + for (i = 0; i < led_pdata->counter; i++, data++) { + led_data = devm_kzalloc(&priv->pdev->dev, sizeof(*led_data), + GFP_KERNEL); + if (!led_data) + return -ENOMEM; + + led_cdev = &led_data->led_cdev; + led_data->data_parent = priv; + if (strstr(data->label, "red") || + strstr(data->label, "orange")) { + brightness = LED_OFF; + led_data->base_color = MLXREG_LED_RED_SOLID; + } else if (strstr(data->label, "amber")) { + brightness = LED_OFF; + led_data->base_color = MLXREG_LED_AMBER_SOLID; + } else { + brightness = LED_OFF; + led_data->base_color = MLXREG_LED_GREEN_SOLID; + } + sprintf(led_data->led_cdev_name, "%s:%s", "mlxreg", + data->label); + led_cdev->name = led_data->led_cdev_name; + led_cdev->brightness = brightness; + led_cdev->max_brightness = LED_ON; + led_cdev->brightness_set_blocking = + mlxreg_led_brightness_set; + led_cdev->brightness_get = mlxreg_led_brightness_get; + led_cdev->blink_set = mlxreg_led_blink_set; + led_cdev->flags = LED_CORE_SUSPENDRESUME; + led_data->data = data; + err = devm_led_classdev_register(&priv->pdev->dev, led_cdev); + if (err) + return err; + + if (led_cdev->brightness) + mlxreg_led_brightness_set(led_cdev, + led_cdev->brightness); + dev_info(led_cdev->dev, "label: %s, mask: 0x%02x, offset:0x%02x\n", + data->label, data->mask, data->reg); + } + + return 0; +} + +static int mlxreg_led_probe(struct platform_device *pdev) +{ + struct mlxreg_core_platform_data *led_pdata; + struct mlxreg_led_priv_data *priv; + + led_pdata = dev_get_platdata(&pdev->dev); + if (!led_pdata) { + dev_err(&pdev->dev, "Failed to get platform data.\n"); + return -EINVAL; + } + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mutex_init(&priv->access_lock); + priv->pdev = pdev; + priv->pdata = led_pdata; + + return mlxreg_led_config(priv); +} + +static int mlxreg_led_remove(struct platform_device *pdev) +{ + struct mlxreg_led_priv_data *priv = dev_get_drvdata(&pdev->dev); + + mutex_destroy(&priv->access_lock); + + return 0; +} + +static struct platform_driver mlxreg_led_driver = { + .driver = { + .name = "leds-mlxreg", + }, + .probe = mlxreg_led_probe, + .remove = mlxreg_led_remove, +}; + +module_platform_driver(mlxreg_led_driver); + +MODULE_AUTHOR("Vadim Pasternak "); +MODULE_DESCRIPTION("Mellanox LED regmap driver"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_ALIAS("platform:leds-mlxreg"); From 2dd1ea5b8a492121dc7cb3cb2bc17c22415260e6 Mon Sep 17 00:00:00 2001 From: Timothy Redaelli Date: Thu, 15 Feb 2018 11:21:36 +0100 Subject: [PATCH 5/7] leds: Add more product/board names for PC Engines APU2 PC Engines "legacy" coreboot 4.0.8 changed the product/board name from "APU2" to "apu2". PC Engines "mainline" coreboot uses, instead, "PC Engines apu2" as product/board name. This commit adds the 2 variants ("apu2" and "PC Engines apu2") of product/board name to be compatible with all the APU2 BIOSes. Fixes: 3faee9423ce0 ("leds: Add driver for PC Engines APU/APU2 LEDs") Signed-off-by: Timothy Redaelli Acked-by: Pavel Machek Signed-off-by: Jacek Anaszewski --- drivers/leds/leds-apu.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/leds/leds-apu.c b/drivers/leds/leds-apu.c index 74820aab9497..311e98b1823f 100644 --- a/drivers/leds/leds-apu.c +++ b/drivers/leds/leds-apu.c @@ -110,6 +110,7 @@ static const struct dmi_system_id apu_led_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "APU") } }, + /* PC Engines APU2 with "Legacy" bios < 4.0.8 */ { .ident = "apu2", .matches = { @@ -117,6 +118,22 @@ static const struct dmi_system_id apu_led_dmi_table[] __initconst = { DMI_MATCH(DMI_BOARD_NAME, "APU2") } }, + /* PC Engines APU2 with "Legacy" bios >= 4.0.8 */ + { + .ident = "apu2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"), + DMI_MATCH(DMI_BOARD_NAME, "apu2") + } + }, + /* PC Engines APU2 with "Mainline" bios */ + { + .ident = "apu2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"), + DMI_MATCH(DMI_BOARD_NAME, "PC Engines apu2") + } + }, {} }; MODULE_DEVICE_TABLE(dmi, apu_led_dmi_table); @@ -211,7 +228,9 @@ static int __init apu_led_probe(struct platform_device *pdev) apu_led->platform = APU1_LED_PLATFORM; apu_led->num_led_instances = ARRAY_SIZE(apu1_led_profile); apu_led->iosize = APU1_IOSIZE; - } else if (dmi_match(DMI_BOARD_NAME, "APU2")) { + } else if (dmi_match(DMI_BOARD_NAME, "APU2") || + dmi_match(DMI_BOARD_NAME, "apu2") || + dmi_match(DMI_BOARD_NAME, "PC Engines apu2")) { apu_led->profile = apu2_led_profile; apu_led->platform = APU2_LED_PLATFORM; apu_led->num_led_instances = ARRAY_SIZE(apu2_led_profile); @@ -237,7 +256,10 @@ static int __init apu_led_init(void) pr_err("No PC Engines board detected\n"); return -ENODEV; } - if (!(dmi_match(DMI_PRODUCT_NAME, "APU") || dmi_match(DMI_PRODUCT_NAME, "APU2"))) { + if (!(dmi_match(DMI_PRODUCT_NAME, "APU") || + dmi_match(DMI_PRODUCT_NAME, "APU2") || + dmi_match(DMI_PRODUCT_NAME, "apu2") || + dmi_match(DMI_PRODUCT_NAME, "PC Engines apu2"))) { pr_err("Unknown PC Engines board: %s\n", dmi_get_system_info(DMI_PRODUCT_NAME)); return -ENODEV; From d1ed7c558612630ce4c48e440a6fdd8d4785f6a3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 24 Feb 2018 23:45:56 +0100 Subject: [PATCH 6/7] leds: Extends disk trigger for reads and writes This adds two new disk triggers for triggering on reads and writes respectively, named "disk-read" and "disk-write". The use case comes from working on the D-Link DNS-313 NAS box. This features an RGB LED for disk activity. with these two triggers I can couple the green LED to read activity and the red LED to write activity, which gives the appropriate user feedback about what is happening on the disk. When tested it gave exactly the feedback desired. The in-kernel interface is simply changed to pass a bool indicating if the activity is write activity and update each trigger (and the composite "disk-activity" trigger) depending on what is passed in. Signed-off-by: Linus Walleij Reviewed-by: Bartlomiej Zolnierkiewicz Acked-by: Pavel Machek Acked-by: Tejun Heo Acked-by: David S. Miller Signed-off-by: Jacek Anaszewski --- drivers/ata/libata-core.c | 2 +- drivers/ide/ide-disk.c | 2 +- drivers/leds/trigger/ledtrig-disk.c | 12 +++++++++++- include/linux/leds.h | 4 ++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3c09122bf038..fa75de6abbf1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5219,7 +5219,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; /* Trigger the LED (if available) */ - ledtrig_disk_activity(); + ledtrig_disk_activity(!!(qc->tf.flags & ATA_TFLAG_WRITE)); /* XXX: New EH and old EH use different mechanisms to * synchronize EH with regular execution path. diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 188d1b03715d..67bc72d78fbf 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -187,7 +187,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); BUG_ON(blk_rq_is_passthrough(rq)); - ledtrig_disk_activity(); + ledtrig_disk_activity(rq_data_dir(rq) == WRITE); pr_debug("%s: %sing: block=%llu, sectors=%u\n", drive->name, rq_data_dir(rq) == READ ? "read" : "writ", diff --git a/drivers/leds/trigger/ledtrig-disk.c b/drivers/leds/trigger/ledtrig-disk.c index cd525b4125eb..9816b0d60270 100644 --- a/drivers/leds/trigger/ledtrig-disk.c +++ b/drivers/leds/trigger/ledtrig-disk.c @@ -18,9 +18,11 @@ #define BLINK_DELAY 30 DEFINE_LED_TRIGGER(ledtrig_disk); +DEFINE_LED_TRIGGER(ledtrig_disk_read); +DEFINE_LED_TRIGGER(ledtrig_disk_write); DEFINE_LED_TRIGGER(ledtrig_ide); -void ledtrig_disk_activity(void) +void ledtrig_disk_activity(bool write) { unsigned long blink_delay = BLINK_DELAY; @@ -28,12 +30,20 @@ void ledtrig_disk_activity(void) &blink_delay, &blink_delay, 0); led_trigger_blink_oneshot(ledtrig_ide, &blink_delay, &blink_delay, 0); + if (write) + led_trigger_blink_oneshot(ledtrig_disk_write, + &blink_delay, &blink_delay, 0); + else + led_trigger_blink_oneshot(ledtrig_disk_read, + &blink_delay, &blink_delay, 0); } EXPORT_SYMBOL(ledtrig_disk_activity); static int __init ledtrig_disk_init(void) { led_trigger_register_simple("disk-activity", &ledtrig_disk); + led_trigger_register_simple("disk-read", &ledtrig_disk_read); + led_trigger_register_simple("disk-write", &ledtrig_disk_write); led_trigger_register_simple("ide-disk", &ledtrig_ide); return 0; diff --git a/include/linux/leds.h b/include/linux/leds.h index 5579c64c8fd6..b7e82550e655 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -346,9 +346,9 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) /* Trigger specific functions */ #ifdef CONFIG_LEDS_TRIGGER_DISK -extern void ledtrig_disk_activity(void); +extern void ledtrig_disk_activity(bool write); #else -static inline void ledtrig_disk_activity(void) {} +static inline void ledtrig_disk_activity(bool write) {} #endif #ifdef CONFIG_LEDS_TRIGGER_MTD From 92d7ec1d71e351f11ba503369eb78225510cfcc7 Mon Sep 17 00:00:00 2001 From: Hans Ulli Kroll Date: Mon, 5 Mar 2018 18:09:10 +0100 Subject: [PATCH 7/7] leds: Fix wrong dmi_match on PC Engines APU LEDs BIOS on APU board doesn't expose board_name property, and thus we have to rely on the product_name instead. Signed-off-by: Hans Ulli Kroll Signed-off-by: Jacek Anaszewski --- drivers/leds/leds-apu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/leds-apu.c b/drivers/leds/leds-apu.c index 311e98b1823f..90eeedcbf371 100644 --- a/drivers/leds/leds-apu.c +++ b/drivers/leds/leds-apu.c @@ -223,7 +223,7 @@ static int __init apu_led_probe(struct platform_device *pdev) apu_led->pdev = pdev; - if (dmi_match(DMI_BOARD_NAME, "APU")) { + if (dmi_match(DMI_PRODUCT_NAME, "APU")) { apu_led->profile = apu1_led_profile; apu_led->platform = APU1_LED_PLATFORM; apu_led->num_led_instances = ARRAY_SIZE(apu1_led_profile);