diff options
| -rw-r--r-- | drivers/soc/qcom/Makefile | 1 | ||||
| -rw-r--r-- | drivers/soc/qcom/msm_rtb-hotplug.c | 55 |
2 files changed, 56 insertions, 0 deletions
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 2f98740e2120..9b98aa0b0631 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -77,3 +77,4 @@ obj-$(CONFIG_MSM_BOOT_STATS) += boot_stats.o obj-$(CONFIG_MSM_AVTIMER) += avtimer.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_kryo.o obj-$(CONFIG_MSM_KERNEL_PROTECT) += kernel_protect.o +obj-$(CONFIG_MSM_RTB) += msm_rtb-hotplug.o diff --git a/drivers/soc/qcom/msm_rtb-hotplug.c b/drivers/soc/qcom/msm_rtb-hotplug.c new file mode 100644 index 000000000000..be12592955ff --- /dev/null +++ b/drivers/soc/qcom/msm_rtb-hotplug.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/cpu.h> +#include <linux/notifier.h> +#include <linux/msm_rtb.h> + +#define CPU_SHIFT 0 +#define CPU_MASK 0xF +#define CPU_OF(n) (((n) & CPU_MASK) << CPU_SHIFT) +#define CPUSET_SHIFT 4 +#define CPUSET_MASK 0xFFFF +#define CPUSET_OF(n) (((n) & CPUSET_MASK) << CPUSET_SHIFT) + +static int hotplug_rtb_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + /* + * Bits [19:4] of the data are the online mask, lower 4 bits are the + * cpu number that is being changed. Additionally, changes to the + * online_mask that will be done by the current hotplug will be made + * even though they aren't necessarily in the online mask yet. + * + * XXX: This design is limited to supporting at most 16 cpus + */ + unsigned long this_cpumask = CPUSET_OF(1 << (unsigned long)hcpu); + unsigned long cpumask = CPUSET_OF(cpumask_bits(cpu_online_mask)[0]); + unsigned long cpudata = CPU_OF((unsigned long)hcpu) | cpumask; + + switch (action & (~CPU_TASKS_FROZEN)) { + case CPU_STARTING: + uncached_logk(LOGK_HOTPLUG, (void *)(cpudata | this_cpumask)); + break; + case CPU_DYING: + uncached_logk(LOGK_HOTPLUG, (void *)(cpudata & ~this_cpumask)); + break; + default: + break; + } + + return NOTIFY_OK; +} +static struct notifier_block hotplug_rtb_notifier = { + .notifier_call = hotplug_rtb_callback, +}; + +static int __init init_hotplug_rtb(void) +{ + return register_hotcpu_notifier(&hotplug_rtb_notifier); +} +early_initcall(init_hotplug_rtb); |
