diff options
author | Álvaro Fernández Rojas <noltari@gmail.com> | 2021-08-21 10:54:34 +0200 |
---|---|---|
committer | Álvaro Fernández Rojas <noltari@gmail.com> | 2021-08-21 19:07:07 +0200 |
commit | 8299d1f057439f94c6a4412e2e5c5082b82a30c9 (patch) | |
tree | 1bf678d61f11f7394493be464c7876e496f7faed /target/linux/bcm27xx/patches-5.10/950-0297-leds-Add-the-actpwr-trigger.patch | |
parent | 33b6885975ce376ff075362b7f0890326043111b (diff) | |
download | upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.gz upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.bz2 upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.zip |
bcm27xx: add kernel 5.10 support
Rebased RPi foundation patches on linux 5.10.59, removed applied and reverted
patches, wireless patches and defconfig patches.
bcm2708: boot tested on RPi B+ v1.2
bcm2709: boot tested on RPi 4B v1.1 4G
bcm2711: boot tested on RPi 4B v1.1 4G
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0297-leds-Add-the-actpwr-trigger.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0297-leds-Add-the-actpwr-trigger.patch | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0297-leds-Add-the-actpwr-trigger.patch b/target/linux/bcm27xx/patches-5.10/950-0297-leds-Add-the-actpwr-trigger.patch new file mode 100644 index 0000000000..2b1257526f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.10/950-0297-leds-Add-the-actpwr-trigger.patch @@ -0,0 +1,235 @@ +From 136ae921cea7e7a189ee99d126253631f880ded0 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 13 Jul 2020 10:33:19 +0100 +Subject: [PATCH] leds: Add the actpwr trigger + +The actpwr trigger is a meta trigger that cycles between an inverted +mmc0 and default-on. It is written in a way that could fairly easily +be generalised to support alternative sets of source triggers. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/leds/trigger/Kconfig | 11 ++ + drivers/leds/trigger/Makefile | 1 + + drivers/leds/trigger/ledtrig-actpwr.c | 190 ++++++++++++++++++++++++++ + 3 files changed, 202 insertions(+) + create mode 100644 drivers/leds/trigger/ledtrig-actpwr.c + +--- a/drivers/leds/trigger/Kconfig ++++ b/drivers/leds/trigger/Kconfig +@@ -151,4 +151,15 @@ config LEDS_TRIGGER_AUDIO + the audio mute and mic-mute changes. + If unsure, say N + ++config LEDS_TRIGGER_ACTPWR ++ tristate "ACT/PWR Input Trigger" ++ depends on LEDS_TRIGGERS ++ help ++ This trigger is intended for platforms that have one software- ++ controllable LED and no dedicated activity or power LEDs, hence the ++ need to make the one LED perform both functions. It cycles between ++ default-on and an inverted mmc0 every 500ms, guaranteeing that it is ++ on for at least half of the time. ++ If unsure, say N. ++ + endif # LEDS_TRIGGERS +--- a/drivers/leds/trigger/Makefile ++++ b/drivers/leds/trigger/Makefile +@@ -16,3 +16,4 @@ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledt + obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o + obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o + obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o ++obj-$(CONFIG_LEDS_TRIGGER_ACTPWR) += ledtrig-actpwr.o +--- /dev/null ++++ b/drivers/leds/trigger/ledtrig-actpwr.c +@@ -0,0 +1,190 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Activity/power trigger ++ * ++ * Copyright (C) 2020 Raspberry Pi (Trading) Ltd. ++ * ++ * Based on Atsushi Nemoto's ledtrig-heartbeat.c, although there may be ++ * nothing left of the original now. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/timer.h> ++#include <linux/leds.h> ++#include "../leds.h" ++ ++enum { ++ TRIG_ACT, ++ TRIG_PWR, ++ ++ TRIG_COUNT ++}; ++ ++struct actpwr_trig_src { ++ const char *name; ++ int interval; ++ bool invert; ++}; ++ ++struct actpwr_vled { ++ struct led_classdev cdev; ++ struct actpwr_trig_data *parent; ++ enum led_brightness value; ++ unsigned int interval; ++ bool invert; ++}; ++ ++struct actpwr_trig_data { ++ struct led_trigger trig; ++ struct actpwr_vled virt_leds[TRIG_COUNT]; ++ struct actpwr_vled *active; ++ struct timer_list timer; ++ int next_active; ++}; ++ ++static int actpwr_trig_activate(struct led_classdev *led_cdev); ++static void actpwr_trig_deactivate(struct led_classdev *led_cdev); ++ ++static const struct actpwr_trig_src actpwr_trig_sources[TRIG_COUNT] = { ++ [TRIG_ACT] = { "mmc0", 500, true }, ++ [TRIG_PWR] = { "default-on", 500, false }, ++}; ++ ++static struct actpwr_trig_data actpwr_data = { ++ { ++ .name = "actpwr", ++ .activate = actpwr_trig_activate, ++ .deactivate = actpwr_trig_deactivate, ++ } ++}; ++ ++static void actpwr_brightness_set(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ struct actpwr_vled *vled = container_of(led_cdev, struct actpwr_vled, ++ cdev); ++ struct actpwr_trig_data *trig = vled->parent; ++ ++ if (vled->invert) ++ value = !value; ++ vled->value = value; ++ ++ if (vled == trig->active) ++ led_trigger_event(&trig->trig, value); ++} ++ ++static int actpwr_brightness_set_blocking(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ actpwr_brightness_set(led_cdev, value); ++ return 0; ++} ++ ++static enum led_brightness actpwr_brightness_get(struct led_classdev *led_cdev) ++{ ++ struct actpwr_vled *vled = container_of(led_cdev, struct actpwr_vled, ++ cdev); ++ ++ return vled->value; ++} ++ ++static void actpwr_trig_cycle(struct timer_list *t) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ struct actpwr_vled *active; ++ ++ active = &trig->virt_leds[trig->next_active]; ++ trig->active = active; ++ trig->next_active = (trig->next_active + 1) % TRIG_COUNT; ++ ++ led_trigger_event(&trig->trig, active->value); ++ ++ mod_timer(&trig->timer, jiffies + msecs_to_jiffies(active->interval)); ++} ++ ++static int actpwr_trig_activate(struct led_classdev *led_cdev) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ ++ /* Start the timer if this is the first LED */ ++ if (!trig->active) ++ actpwr_trig_cycle(&trig->timer); ++ else ++ led_set_brightness_nosleep(led_cdev, trig->active->value); ++ ++ return 0; ++} ++ ++static void actpwr_trig_deactivate(struct led_classdev *led_cdev) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ ++ if (list_empty(&trig->trig.led_cdevs)) { ++ del_timer_sync(&trig->timer); ++ trig->active = NULL; ++ } ++} ++ ++static int __init actpwr_trig_init(void) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ int ret = 0; ++ int i; ++ ++ timer_setup(&trig->timer, actpwr_trig_cycle, 0); ++ ++ /* Register one "LED" for each source trigger */ ++ for (i = 0; i < TRIG_COUNT; i++) ++ { ++ struct actpwr_vled *vled = &trig->virt_leds[i]; ++ struct led_classdev *cdev = &vled->cdev; ++ const struct actpwr_trig_src *src = &actpwr_trig_sources[i]; ++ ++ vled->parent = trig; ++ vled->interval = src->interval; ++ vled->invert = src->invert; ++ cdev->name = src->name; ++ cdev->brightness_set = actpwr_brightness_set; ++ cdev->brightness_set_blocking = actpwr_brightness_set_blocking; ++ cdev->brightness_get = actpwr_brightness_get; ++ cdev->default_trigger = src->name; ++ ret = led_classdev_register(NULL, cdev); ++ if (ret) ++ goto error_classdev; ++ } ++ ++ ret = led_trigger_register(&trig->trig); ++ if (ret) ++ goto error_classdev; ++ ++ return 0; ++ ++error_classdev: ++ while (i > 0) ++ { ++ i--; ++ led_classdev_unregister(&trig->virt_leds[i].cdev); ++ } ++ ++ return ret; ++} ++ ++static void __exit actpwr_trig_exit(void) ++{ ++ int i; ++ ++ led_trigger_unregister(&actpwr_data.trig); ++ for (i = 0; i < TRIG_COUNT; i++) ++ { ++ led_classdev_unregister(&actpwr_data.virt_leds[i].cdev); ++ } ++} ++ ++module_init(actpwr_trig_init); ++module_exit(actpwr_trig_exit); ++ ++MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>"); ++MODULE_DESCRIPTION("ACT/PWR LED trigger"); ++MODULE_LICENSE("GPL v2"); |