Skip to content

Commit

Permalink
KProfiles: Upstream to v5.0.0
Browse files Browse the repository at this point in the history
* 'main' of https://github.com/dakkshesh07/kprofiles:
  kp: version: Bump to 5.0.0
  kp: kp_set_mode: Avoid unnecessary checks for arguments
  kp: kp_set_mode(): Handle invalid mode arguments
  kp: reformat with clang-format
  kp: Make (kp_mode > 3) statement as unlikely
  kp: Make kp_mode an unsigned int type variable
  README: Document about Mi DRM notifier support
  kp: Add auto kprofiles support for MI DRM Notifier
  kp: Simplify notifier callback for MSM_DRM and FB notifiers
  Kprofiles: Cleanup and consolidate
  kp: version: bump to 4.0.2
  kp: make auto_kprofiles __read_mostly
  README: Add a missing slash
  kp: make default mode number configurable via defconfig
  kp: Kconfig: Re-indent and rephrase some bits
  README: small typo fix-up
  • Loading branch information
cyberknight777 committed Dec 30, 2022
2 parents 4784c39 + 0671422 commit 3f2e265
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 78 deletions.
52 changes: 34 additions & 18 deletions drivers/misc/kprofiles/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,29 @@ config KPROFILES
tristate "Kprofiles Kernel Module"
default y
help
This allows you to regulate in-kernel activities in a profile-oriented manner.
it creates a sysfs node which can be used to change profiles via userspace,
It provides 4 profile modes, (Disabled, Battery, Balanced, Performance)
This allows you to regulate in-kernel activities in a profile-oriented manner.
It creates a sysfs node which can be used to change profiles via userspace.
It provides 4 profile modes: Disabled, Battery, Balanced and Performance.

The former can be used to disable/enable or tune kernel activities
according to a profile mode. Check the README.md for more info.
The former can be used to disable/enable or tune kernel activities according
to a profile mode. Check the README.md for more information.

It's safe to say Y here, as the driver isn't very demanding
and is only used when developer uses the exported API functions
in an another driver.
It's safe to say Y here, as the driver isn't very demanding and is only
used when developer uses the exported API functions in an another driver.

if KPROFILES

config DEFAULT_KP_MODE
int "Default mode number for kp_mode"
range 0 3
default 0
help
Kprofiles will activate this mode during boot-up.

config AUTO_KPROFILES
bool
help
Selected if either of the Auto Kprofiles option is enabled.
This option is selected if one of the Auto Kprofiles options is enabled.

choice
prompt "Auto Kprofiles support"
Expand All @@ -33,25 +39,35 @@ config AUTO_KPROFILES_MSM_DRM
depends on DRM_MSM
select AUTO_KPROFILES
help
Select this to enable Kprofile's automatic mode changer via msm_drm_notifier.
When this option is enabled Kprofiles will automatically switch to
battery mode when device screen turns off and switch back
to previously active mode when the device wakes up.
Select this to enable Kprofile's automatic mode changer via msm_drm_notifier.
When this option is enabled, Kprofiles will automatically switch to battery
mode when device screen turns off and will switch back to previously active
mode when the device wakes up.

config AUTO_KPROFILES_MI_DRM
bool "Auto Kprofiles using mi_drm_notifier"
depends on !DRM_MSM
select AUTO_KPROFILES
help
Select this to enable Kprofile's automatic mode changer via mi_drm_notifier.
When this option is enabled, Kprofiles will automatically switch to battery
mode when device screen turns off and will switch back to previously active
mode when the device wakes up.

config AUTO_KPROFILES_FB
bool "Auto Kprofiles using fb_notifier"
depends on FB
select AUTO_KPROFILES
help
Select this to enable Kprofile's automatic mode changer via fb_notifier.
When this option is enabled Kprofiles will automatically switch to
battery mode when device screen turns off and switch back
to previously active mode when the device wakes up.
Select this to enable Kprofile's automatic mode changer via fb_notifier.
When this option is enabled, Kprofiles will automatically switch to
battery mode when device screen turns off and will switch back to
previously active mode when the device wakes up.

config AUTO_KPROFILES_NONE
bool "None"
help
Select this to build Kprofiles without auto Kprofiles.
Select this to build Kprofiles without auto Kprofiles.

endchoice

Expand Down
6 changes: 3 additions & 3 deletions drivers/misc/kprofiles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Kprofiles is a simple Linux kernel module that can be used to regulate in-kernel
| Balanced | 2 |
| Performance | 3 |

Furthermore, Kprofiles provides automatic profile changer (auto Kprofiles), which uses `FB notifier` or `MSM DRM notifier` to enforce battery profile mode when the device's screen goes off and switches back to previously active mode when the device wakes up. Users can disable or enable this feature at runtime without recompiling the kernel by changing the bool value in `/sys/module/kprofiles/parameters/auto_kprofiles`
Furthermore, Kprofiles provides automatic profile changer (auto Kprofiles), which uses `FB notifier`, `MSM DRM notifier` or `MI DRM notifier` to enforce battery profile mode when the device's screen goes off and switches back to previously active mode when the device wakes up. Users can disable or enable this feature at runtime without recompiling the kernel by changing the bool value in `/sys/module/kprofiles/parameters/auto_kprofiles`

Kprofiles additionally has API functions for switching profiles in response to any in-kernel event. For further information, please see the table of [Available APIs](#available-apis)

Expand All @@ -46,11 +46,11 @@ source "drivers/misc/echo/Kconfig"
endmenu
```

3. Modify =drivers/misc/Makefile=
3. Modify `drivers/misc/Makefile`

```diff
obj-$(CONFIG_GENWQE) += genwqe/
+obj-$(CONFIG_KPROFILES) += kprofiles
+obj-$(CONFIG_KPROFILES) += kprofiles/
obj-$(CONFIG_ECHO) += echo/
```

Expand Down
146 changes: 90 additions & 56 deletions drivers/misc/kprofiles/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,39 @@
#include <linux/moduleparam.h>
#ifdef CONFIG_AUTO_KPROFILES_MSM_DRM
#include <linux/msm_drm_notify.h>
#elif defined(CONFIG_AUTO_KPROFILES_MI_DRM)
#include <drm/drm_notifier_mi.h>
#elif defined(CONFIG_AUTO_KPROFILES_FB)
#include <linux/fb.h>
#endif
#include "version.h"

static int kp_mode = 1;
module_param(kp_mode, int, 0664);
#ifdef CONFIG_AUTO_KPROFILES_MSM_DRM
#define KP_EVENT_BLANK MSM_DRM_EVENT_BLANK
#define KP_BLANK_POWERDOWN MSM_DRM_BLANK_POWERDOWN
#define KP_BLANK_UNBLANK MSM_DRM_BLANK_UNBLANK
#elif defined(CONFIG_AUTO_KPROFILES_MI_DRM)
#define KP_EVENT_BLANK MI_DRM_EVENT_BLANK
#define KP_BLANK_POWERDOWN MI_DRM_BLANK_POWERDOWN
#define KP_BLANK_UNBLANK MI_DRM_BLANK_UNBLANK
#elif defined(CONFIG_AUTO_KPROFILES_FB)
#define KP_EVENT_BLANK FB_EVENT_BLANK
#define KP_BLANK_POWERDOWN FB_BLANK_POWERDOWN
#define KP_BLANK_UNBLANK FB_BLANK_UNBLANK
#endif

static unsigned int kp_override_mode;
static bool kp_override = false;

static bool auto_kprofiles = true;
module_param(auto_kprofiles, bool, 0664);

#ifdef CONFIG_AUTO_KPROFILES
static bool screen_on = true;
#endif

static bool auto_kprofiles __read_mostly = true;
module_param(auto_kprofiles, bool, 0664);

static unsigned int kp_mode = CONFIG_DEFAULT_KP_MODE;
module_param(kp_mode, int, 0664);

DEFINE_MUTEX(kplock);

/*
Expand All @@ -42,13 +57,20 @@ void kp_set_mode_rollback(unsigned int level, unsigned int duration_ms)
return;
#endif

mutex_lock(&kplock);
if (level && duration_ms && auto_kprofiles) {
kp_override_mode = level;
kp_override = true;
msleep(duration_ms);
kp_override = false;
if (!auto_kprofiles)
return;

if (unlikely(level > 3)) {
pr_err("%s: Invalid mode requested, Skipping mode change",
__func__);
return;
}

mutex_lock(&kplock);
kp_override_mode = level;
kp_override = true;
msleep(duration_ms);
kp_override = false;
mutex_unlock(&kplock);
}

Expand All @@ -67,7 +89,13 @@ void kp_set_mode(unsigned int level)
return;
#endif

if (level && auto_kprofiles)
if (unlikely(level > 3)) {
pr_err("%s: Invalid mode requested, Skipping mode change",
__func__);
return;
}

if (auto_kprofiles)
kp_mode = level;
}

Expand Down Expand Up @@ -101,7 +129,7 @@ int kp_active_mode(void)
if (kp_override)
return kp_override_mode;

if (kp_mode > 3) {
if (unlikely(kp_mode > 3)) {
kp_mode = 0;
pr_info("Invalid value passed, falling back to level 0\n");
}
Expand All @@ -117,93 +145,99 @@ static inline int kp_notifier_callback(struct notifier_block *self,
{
#ifdef CONFIG_AUTO_KPROFILES_MSM_DRM
struct msm_drm_notifier *evdata = data;
int *blank;

if (event != MSM_DRM_EVENT_BLANK)
goto out;

if (!evdata || !evdata->data || evdata->id != MSM_DRM_PRIMARY_DISPLAY)
goto out;

blank = evdata->data;
switch (*blank) {
case MSM_DRM_BLANK_POWERDOWN:
if (!screen_on)
break;
screen_on = false;
break;
case MSM_DRM_BLANK_UNBLANK:
if (screen_on)
break;
screen_on = true;
break;
}
#elif defined(CONFIG_AUTO_KPROFILES_MI_DRM)
struct mi_drm_notifier *evdata = data;
#elif defined(CONFIG_AUTO_KPROFILES_FB)
struct fb_event *evdata = data;
#endif
int *blank;

if (event != FB_EVENT_BLANK)
goto out;
if (event != KP_EVENT_BLANK
#ifdef CONFIG_AUTO_KPROFILES_MSM_DRM
|| !evdata || !evdata->data || evdata->id != MSM_DRM_PRIMARY_DISPLAY
#endif
)
return NOTIFY_OK;

blank = evdata->data;
switch (*blank) {
case FB_BLANK_POWERDOWN:
case KP_BLANK_POWERDOWN:
if (!screen_on)
break;
screen_on = false;
break;
case FB_BLANK_UNBLANK:
case KP_BLANK_UNBLANK:
if (screen_on)
break;
screen_on = true;
break;
}
#endif

out:
return NOTIFY_OK;
}

static struct notifier_block kp_notifier_block = {
.notifier_call = kp_notifier_callback,
};

#endif

static int __init kp_init(void)
static int kprofiles_register_notifier(void)
{
int ret = 0;

#ifdef CONFIG_AUTO_KPROFILES_MSM_DRM
ret = msm_drm_register_client(&kp_notifier_block);
if (ret) {
pr_err("Failed to register msm_drm notifier, err: %d\n", ret);
msm_drm_unregister_client(&kp_notifier_block);
}
#elif defined(CONFIG_AUTO_KPROFILES_MI_DRM)
ret = mi_drm_register_client(&kp_notifier_block);
#elif defined(CONFIG_AUTO_KPROFILES_FB)
ret = fb_register_client(&kp_notifier_block);
if (ret) {
pr_err("Failed to register fb notifier, err: %d\n", ret);
fb_unregister_client(&kp_notifier_block);
}
#endif
pr_info("Kprofiles " KPROFILES_VERSION
" loaded. Visit https://github.com/dakkshesh07/Kprofiles/blob/main/README.md for information.\n");
pr_info("Copyright (C) 2021-2022 Dakkshesh <dakkshesh5@gmail.com>.\n");

return ret;
}

static void __exit kp_exit(void)
static void kprofiles_unregister_notifier(void)
{
#ifdef CONFIG_AUTO_KPROFILES_MSM_DRM
msm_drm_unregister_client(&kp_notifier_block);
#elif defined(CONFIG_AUTO_KPROFILES_MI_DRM)
mi_drm_unregister_client(&kp_notifier_block);
#elif defined(CONFIG_AUTO_KPROFILES_FB)
fb_unregister_client(&kp_notifier_block);
#endif
}

#else
static inline int kprofiles_register_notifier(void)
{
return 0;
}
static inline void kprofiles_unregister_notifier(void)
{
}
#endif

static int __init kp_init(void)
{
int ret = 0;

ret = kprofiles_register_notifier();
if (ret)
pr_err("Failed to register notifier, err: %d\n", ret);

pr_info("Kprofiles " KPROFILES_VERSION
" loaded. Visit https://github.com/dakkshesh07/Kprofiles/blob/main/README.md for information.\n");
pr_info("Copyright (C) 2021-2022 Dakkshesh <dakkshesh5@gmail.com>.\n");

return ret;
}
module_init(kp_init);

static void __exit kp_exit(void)
{
kprofiles_unregister_notifier();
}
module_exit(kp_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("KernelSpace Profiles");
MODULE_AUTHOR("Dakkshesh <dakkshesh5@gmail.com>");
Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/kprofiles/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
*/

#ifndef KPROFILES_VERSION
#define KPROFILES_VERSION "4.0.1"
#define KPROFILES_VERSION "5.0.0"
#endif

0 comments on commit 3f2e265

Please sign in to comment.