[Q] Nexus 4, Kitkat, android NDK can't access bluetooth - Android Q&A, Help & Troubleshooting

Hello
fellow developers,
I'm trying to access bluetooth trough ndk on kitkat, but keep getting errors. Sample code I'm using.
Code:
int fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
if (fd < -1)
{
sprintf(buff, "socket(...) error: %s", strerror(errno));
return (*aEnv)->NewStringUTF(aEnv, buff);
}
int opt = 0;
if (setsockopt(fd, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0)
{
close(fd);
sprintf(buff, "setsockopt(...) error: %s", strerror(errno));
return (*aEnv)->NewStringUTF(aEnv, buff);
}
const char* bdaddr_src = (*aEnv)->GetStringUTFChars(aEnv, aSrc, 0);
const char* bdaddr_dst = (*aEnv)->GetStringUTFChars(aEnv, aDst, 0);
struct sockaddr_l2 addr;
memset(&addr, 0x00, sizeof(addr));
addr.l2_family = AF_BLUETOOTH;
str2ba(bdaddr_src, &addr.l2_bdaddr);
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
memset(&addr, 0x00, sizeof(addr));
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(CTRL);
str2ba(bdaddr_dst, &addr.l2_bdaddr);
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
close(fd);
sprintf(buff, "src: %s\ndst %s\nconnect(...) error: %s", bdaddr_src, bdaddr_dst, strerror(errno));
return (*aEnv)->NewStringUTF(aEnv, buff);
}
(*aEnv)->ReleaseStringUTFChars(aEnv, aSrc, bdaddr_src);
(*aEnv)->ReleaseStringUTFChars(aEnv, aDst, bdaddr_dst);
This works on my HTC Desire Z with android 2.3, but on Nexus 4 I'm getting an "No route to host" on connect(...). I understand that, bluez which I'm trying to use was replaced by bluedroid, but I've compiled bluez from source and included in my app.
Am I being denied access to bluetooth device for some reason, or will bluez not work that way? Can I create a hci connection with bluedroid?
Both my devices are rooted, should I request root privileges somehow?
Thanks in advance, any help is appreciated.
P.s.
Sixaxis works on my Nexus 4, so there's got to be a way.

Related

Help Needed :: Recompiling Xperia X8 Kernel (Eclair)

Hi..
This is my first post & thread in XDA-Dev, pardon me if i break any rules...
Just tell what i could do to mend the situation and I'll gladly comply.
Intro
Here's what's been bugging me for the past few days.
I'm trying to recompile Sony Ericsson source code archived as x10_x10mini_X10minipro_x8_eclair_2.1.A.0.435.tar.gz to enable a few features :
Swap support
Ad-Hoc wifi
I followed the tutorial on Android Central (http://forum.androidcentral.com/htc-hero-rooting-roms-hacks/8072-how-build-your-own-kernel-package-source.html) except that I'm using SE's kernel codes rather than HTC's.
My Environment
Ubuntu 10.10 over VirtualBox over Windows 7
Using compiler in the Android Toolchain (gcc-4.4.0)
Folders Structure
~/android/source/ : Contain SE Kernel Sources
~/myandroid/ : Contain everything that you should get when you repo git://android.git.kernel.org/platform/manifest.git
Settings
hit export ARCH=arm
hit export CROSS_COMPILE=arm-eabi-
hit export PATH=$PATH:~/myandroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
for .config, i used the one from 1.6 as latter version of SE phones does not have /proc/config.gz
What I did
First, i compiled the kernel using the default settings, it completes successfully.
I make clean
When i run make menuconfig I changed
General Setup --> [*] Support for paging of anonymous memory (swap)
System Type --> MSM Board Selection --> [ ] MSM7x27 Mimmi (deselect)
System Type --> MSM Board Selection --> [*] MSM7x27 Shakira (select)
I run make
I was thrown error below.
The Pain In The A$$
Code:
[FONT="Fixedsys"][COLOR="YellowGreen"] CC lib/radix-tree.o
CC lib/ratelimit.o
CC lib/rbtree.o
CC lib/reciprocal_div.o
CC lib/rwsem-spinlock.o
CC lib/sha1.o
CC lib/show_mem.o
CC lib/string.o
CC lib/vsprintf.o
AR lib/lib.a
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/linux/compile.h
UPD include/linux/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1[/COLOR]
[COLOR="Red"]arch/arm/mach-msm/built-in.o: In function `shakira_gpio_event_matrix_func':
/home/android/android/sources/kernel/arch/arm/mach-msm/board-shakira-keypad.c:90: undefined reference to `semc_gpio_event_matrix_func'
make: *** [.tmp_vmlinux1] Error 1[/COLOR][/FONT]
I did some regex on all files in the SE directory and sub-directory, looking for any mentioning of semc_gpio_event_matrix_func, there are 5 files that has it, namely...
/home/android/android/sources/kernel/arch/arm/mach-msm/board-mimmi-keypad.c
/home/android/android/sources/kernel/arch/arm/mach-msm/board-robyn-keypad.c
/home/android/android/sources/kernel/arch/arm/mach-msm/board-shakira-keypad.c
/home/android/android/sources/kernel/drivers/misc/semc/gpio_matrix/semc_gpio_matrix.c
/home/android/android/sources/kernel/include/linux/semc/gpio_event.h
Files with silver color is irrelevant, as I'm building the X8. I assume it's safe to ignore them.
my username on the ubuntu is also android, hence the .../android/android/....
Please help me troubleshoot this...
So nice to see someone dev the kernel and I`'m sorry to say I can't help but i'm interested how you wan't to flash the kernel. Isn't it locked by SE to flash a custom kerneL?
I think they give you something so you can use it.
Sent from my Sony Ericsson X8
There should be some way because SE gives us kexec tool even in retail firmware...
Sent from my E15i using XDA App
Asdoos said:
So nice to see someone dev the kernel and I`'m sorry to say I can't help but i'm interested how you wan't to flash the kernel. Isn't it locked by SE to flash a custom kerneL?
Click to expand...
Click to collapse
well if i can't load the whole kernel into the phone, at least i could push custom patched wpa_supplicant.
if it's really impossible, at this date, to use custom ROM on X8 why would then people are toying with the Floyo port?
For now, I'd be happy to just solve patching wpa_supplicant. But since I'm already into this, why not get it done with.
So now there's 3 files that are involved.
herein, are those 3 files, underneath each of which are the files that it #includes and their respective location in the filesystem.
to be honest, i was only looking to play with the config files when i started this.
i've never compiled project this big (i did, but that was looong time ago, and it went without a hitch).
for the past 2 years i only programmed Arduino on C, and occasionally PHPs. So i rarely have to deal much with header files. Also some recreational cracking utilising assembly.
there was a few other errors before this one actually. But it was easily solved by changing <xxxxxx.x> to "xxxxxx.x"
so guys please, please help me.
/home/android/android/sources/kernel/arch/arm/mach-msm/board-shakira-keypad.c
#include <linux/platform_device.h>
location : /home/android/android/sources/kernel/include/linux/platform_device.h​
#include <linux/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/gpio_event.h​
#include <linux/semc/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/semc/gpio_event.h​
#include "board-delta-keypad.h"
location : /home/android/android/sources/kernel/arch/arm/mach-msm/board-delta-keypad.h​
#include <mach/semc_rpc_server_handset.h>
location : /home/android/android/sources/kernel/arch/arm/mach-msm/include/mach/semc_rpc_server_handset.h​
#include <asm/mach-types.h>
location : /home/android/android/sources/kernel/include/asm/mach-types.h​
#include <linux/gpio.h>
location : /home/android/android/sources/kernel/include/linux/gpio.h​
/home/android/android/sources/kernel/drivers/misc/semc/gpio_matrix/semc_gpio_matrix.c
#include <linux/kernel.h>
location : /home/android/android/sources/kernel/include/linux/​
#include <linux/gpio.h>
location : /home/android/android/sources/kernel/include/linux/​
#include <linux/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/​
#include <linux/hrtimer.h>
location : /home/android/android/sources/kernel/include/linux/​
#include <linux/interrupt.h>
location : /home/android/android/sources/kernel/include/linux/​
#include <linux/wakelock.h>
location : /home/android/android/sources/kernel/include/linux/​
/home/android/android/sources/kernel/include/linux/semc/gpio_event.h
#include <linux/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/​
#include <linux/input.h>
location : /home/android/android/sources/kernel/include/linux/​
see anything?
I would assume any files with the word keypad are referring to the mini10 pro's slide out keyboard. Your x8 doesn't have one so try and remove from the build process.
Either way the bootloader is locked so I'm not really sure how you will push this onto the phone in the first place.
If you do succeed let us know.
Edit: gpio and wakelock events are probably directed to the hardware switch when the keyboard is opened or closed.
Sent from my Sony Ericsson X8 using XDA App
biglama said:
I would assume any files with the word keypad are referring to the mini10 pro's slide out keyboard. Your x8 doesn't have one so try and remove from the build process.
Either way the bootloader is locked so I'm not really sure how you will push this onto the phone in the first place.
If you do succeed let us know.
Edit: gpio and wakelock events are probably directed to the hardware switch when the keyboard is opened or closed.
Sent from my Sony Ericsson X8 using XDA App
Click to expand...
Click to collapse
in board-shakira-keypad.c, the keys that it governs are the volume up/down, cameray, back, menu and home keys. nothing more, nothing less.
so i'm pretty sure it is for x8.
I'll post the content of the file later.
undefined reference to `semc_gpio_event_matrix_func'
Click to expand...
Click to collapse
can you just look in semc_gpio_matrix.c and add a prototype for that function into board-shakira-keypad.c if it's not provided in any of the other headers.
Source - semc_gpio_matrix.c
as said, the source files...
semc_gpio_matrix.c
Code:
/* drivers/misc/semc/gpio_matrix/gpio_matrix.c
*
* Copyright (C) 2010 Sony Ericsson Mobile Communications AB
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Based upon kernel/drivers/input/misc/gpio_matrix.c
*/
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/gpio_event.h>
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/wakelock.h>
struct gpio_kp {
struct gpio_event_input_devs *input_devs;
struct gpio_event_matrix_info *keypad_info;
struct hrtimer timer;
struct wake_lock wake_lock;
int current_output;
unsigned int use_irq:1;
unsigned int key_state_changed:1;
unsigned int last_key_state_changed:1;
unsigned int some_keys_pressed:2;
unsigned long keys_pressed[0];
};
static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
{
struct gpio_event_matrix_info *mi = kp->keypad_info;
int key_index = out * mi->ninputs + in;
unsigned short keyentry = mi->keymap[key_index];
unsigned short keycode = keyentry & MATRIX_KEY_MASK;
unsigned short dev = keyentry >> MATRIX_CODE_BITS;
if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) {
if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
"cleared\n", keycode, out, in,
mi->output_gpios[out], mi->input_gpios[in]);
__clear_bit(key_index, kp->keys_pressed);
} else {
if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
"not cleared\n", keycode, out, in,
mi->output_gpios[out], mi->input_gpios[in]);
}
}
static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
{
int rv = 0;
int key_index;
key_index = out * kp->keypad_info->ninputs + in;
while (out < kp->keypad_info->noutputs) {
if (test_bit(key_index, kp->keys_pressed)) {
rv = 1;
clear_phantom_key(kp, out, in);
}
key_index += kp->keypad_info->ninputs;
out++;
}
return rv;
}
static void remove_phantom_keys(struct gpio_kp *kp)
{
int out, in, inp;
int key_index;
if (kp->some_keys_pressed < 3)
return;
for (out = 0; out < kp->keypad_info->noutputs; out++) {
inp = -1;
key_index = out * kp->keypad_info->ninputs;
for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
if (test_bit(key_index, kp->keys_pressed)) {
if (inp == -1) {
inp = in;
continue;
}
if (inp >= 0) {
if (!restore_keys_for_input(kp, out + 1,
inp))
break;
clear_phantom_key(kp, out, inp);
inp = -2;
}
restore_keys_for_input(kp, out, in);
}
}
}
}
static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
{
struct gpio_event_matrix_info *mi = kp->keypad_info;
int pressed = test_bit(key_index, kp->keys_pressed);
unsigned short keyentry = mi->keymap[key_index];
unsigned short keycode = keyentry & MATRIX_KEY_MASK;
unsigned short dev = keyentry >> MATRIX_CODE_BITS;
if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) {
if (keycode == KEY_RESERVED) {
if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
pr_info("gpiomatrix: unmapped key, %d-%d "
"(%d-%d) changed to %d\n",
out, in, mi->output_gpios[out],
mi->input_gpios[in], pressed);
} else {
if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
"changed to %d\n", keycode,
out, in, mi->output_gpios[out],
mi->input_gpios[in], pressed);
if (mi->info.event)
mi->info.event(kp->input_devs, &mi->info, NULL, dev, 0,
keycode, pressed);
else
input_report_key(kp->input_devs->dev[dev], keycode, pressed);
}
}
}
static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
{
int out, in;
int key_index;
int gpio;
struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
struct gpio_event_matrix_info *mi = kp->keypad_info;
unsigned gpio_keypad_flags = mi->flags;
unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
out = kp->current_output;
if (out == mi->noutputs) {
out = 0;
kp->last_key_state_changed = kp->key_state_changed;
kp->key_state_changed = 0;
kp->some_keys_pressed = 0;
} else {
key_index = out * mi->ninputs;
for (in = 0; in < mi->ninputs; in++, key_index++) {
gpio = mi->input_gpios[in];
if (gpio_get_value(gpio) ^ !polarity) {
if (kp->some_keys_pressed < 3)
kp->some_keys_pressed++;
kp->key_state_changed |= !__test_and_set_bit(
key_index, kp->keys_pressed);
} else
kp->key_state_changed |= __test_and_clear_bit(
key_index, kp->keys_pressed);
}
gpio = mi->output_gpios[out];
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(gpio, !polarity);
else
gpio_direction_input(gpio);
out++;
}
kp->current_output = out;
if (out < mi->noutputs) {
gpio = mi->output_gpios[out];
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(gpio, polarity);
else
gpio_direction_output(gpio, polarity);
hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
if (kp->key_state_changed) {
hrtimer_start(&kp->timer, mi->debounce_delay,
HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
kp->key_state_changed = kp->last_key_state_changed;
}
if (kp->key_state_changed) {
if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
remove_phantom_keys(kp);
key_index = 0;
for (out = 0; out < mi->noutputs; out++)
for (in = 0; in < mi->ninputs; in++, key_index++)
report_key(kp, key_index, out, in);
}
if (!kp->use_irq || kp->some_keys_pressed) {
hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
/* No keys are pressed, reenable interrupt */
for (out = 0; out < mi->noutputs; out++) {
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(mi->output_gpios[out], polarity);
else
gpio_direction_output(mi->output_gpios[out], polarity);
}
for (in = 0; in < mi->ninputs; in++)
enable_irq(gpio_to_irq(mi->input_gpios[in]));
wake_unlock(&kp->wake_lock);
return HRTIMER_NORESTART;
}
static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
{
int i;
struct gpio_kp *kp = dev_id;
struct gpio_event_matrix_info *mi = kp->keypad_info;
unsigned gpio_keypad_flags = mi->flags;
if (!kp->use_irq) /* ignore interrupt while registering the handler */
return IRQ_HANDLED;
for (i = 0; i < mi->ninputs; i++)
disable_irq(gpio_to_irq(mi->input_gpios[i]));
for (i = 0; i < mi->noutputs; i++) {
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(mi->output_gpios[i],
!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
else
gpio_direction_input(mi->output_gpios[i]);
}
wake_lock(&kp->wake_lock);
hrtimer_start(&kp->timer, ktime_set(0, 10000), HRTIMER_MODE_REL);
return IRQ_HANDLED;
}
static int gpio_keypad_request_irqs(struct gpio_kp *kp)
{
int i;
int err;
unsigned int irq;
unsigned long request_flags;
struct gpio_event_matrix_info *mi = kp->keypad_info;
switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
default:
request_flags = IRQF_TRIGGER_FALLING;
break;
case GPIOKPF_ACTIVE_HIGH:
request_flags = IRQF_TRIGGER_RISING;
break;
case GPIOKPF_LEVEL_TRIGGERED_IRQ:
request_flags = IRQF_TRIGGER_LOW;
break;
case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
request_flags = IRQF_TRIGGER_HIGH;
break;
}
for (i = 0; i < mi->ninputs; i++) {
err = irq = gpio_to_irq(mi->input_gpios[i]);
if (err < 0)
goto err_gpio_get_irq_num_failed;
err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
"gpio_kp", kp);
if (err) {
pr_err("gpiomatrix: request_irq failed for input %d, "
"irq %d\n", mi->input_gpios[i], irq);
goto err_request_irq_failed;
}
disable_irq(irq);
}
return 0;
for (i = mi->noutputs - 1; i >= 0; i--) {
free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
err_request_irq_failed:
err_gpio_get_irq_num_failed:
;
}
return err;
}
int semc_gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
struct gpio_event_info *info, void **data, int func)
{
int i;
int err;
int key_count;
struct gpio_kp *kp;
struct gpio_event_matrix_info *mi;
mi = container_of(info, struct gpio_event_matrix_info, info);
if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
/* TODO: disable scanning */
return 0;
}
if (func == GPIO_EVENT_FUNC_INIT) {
if (mi->keymap == NULL ||
mi->input_gpios == NULL ||
mi->output_gpios == NULL) {
err = -ENODEV;
pr_err("gpiomatrix: Incomplete pdata\n");
goto err_invalid_platform_data;
}
key_count = mi->ninputs * mi->noutputs;
*data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
BITS_TO_LONGS(key_count), GFP_KERNEL);
if (kp == NULL) {
err = -ENOMEM;
pr_err("gpiomatrix: Failed to allocate private data\n");
goto err_kp_alloc_failed;
}
kp->input_devs = input_devs;
kp->keypad_info = mi;
for (i = 0; i < key_count; i++) {
unsigned short keyentry = mi->keymap[i];
unsigned short keycode = keyentry & MATRIX_KEY_MASK;
unsigned short dev = keyentry >> MATRIX_CODE_BITS;
if (dev >= input_devs->count) {
pr_err("gpiomatrix: bad device index %d >= "
"%d for key code %d\n",
dev, input_devs->count, keycode);
err = -EINVAL;
goto err_bad_keymap;
}
if (keycode && keycode <= KEY_MAX)
input_set_capability(input_devs->dev[dev],
EV_KEY, keycode);
}
for (i = 0; i < mi->noutputs; i++) {
if (gpio_cansleep(mi->output_gpios[i])) {
pr_err("gpiomatrix: unsupported output gpio %d,"
" can sleep\n", mi->output_gpios[i]);
err = -EINVAL;
goto err_request_output_gpio_failed;
}
err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
if (err) {
pr_err("gpiomatrix: gpio_request failed for "
"output %d\n", mi->output_gpios[i]);
goto err_request_output_gpio_failed;
}
if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
err = gpio_direction_output(mi->output_gpios[i],
!(mi->flags & GPIOKPF_ACTIVE_HIGH));
else
err = gpio_direction_input(mi->output_gpios[i]);
if (err) {
pr_err("gpiomatrix: gpio_configure failed for "
"output %d\n", mi->output_gpios[i]);
goto err_output_gpio_configure_failed;
}
}
for (i = 0; i < mi->ninputs; i++) {
err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
if (err) {
pr_err("gpiomatrix: gpio_request failed for "
"input %d\n", mi->input_gpios[i]);
goto err_request_input_gpio_failed;
}
err = gpio_direction_input(mi->input_gpios[i]);
if (err) {
pr_err("gpiomatrix: gpio_direction_input failed"
" for input %d\n", mi->input_gpios[i]);
goto err_gpio_direction_input_failed;
}
}
kp->current_output = mi->noutputs;
kp->key_state_changed = 1;
hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
kp->timer.function = gpio_keypad_timer_func;
wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp");
err = gpio_keypad_request_irqs(kp);
kp->use_irq = err == 0;
pr_info("SEMC GPIO Matrix Keypad Driver: Start keypad matrix for "
"%s%s in %s mode\n", input_devs->dev[0]->name,
(input_devs->count > 1) ? "..." : "",
kp->use_irq ? "interrupt" : "polling");
if (kp->use_irq)
wake_lock(&kp->wake_lock);
hrtimer_start(&kp->timer, ktime_set(0, 10000),
HRTIMER_MODE_REL);
return 0;
}
err = 0;
kp = *data;
if (kp->use_irq)
for (i = mi->noutputs - 1; i >= 0; i--)
free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
hrtimer_cancel(&kp->timer);
wake_lock_destroy(&kp->wake_lock);
for (i = mi->noutputs - 1; i >= 0; i--) {
err_gpio_direction_input_failed:
gpio_free(mi->input_gpios[i]);
err_request_input_gpio_failed:
;
}
for (i = mi->noutputs - 1; i >= 0; i--) {
err_output_gpio_configure_failed:
gpio_free(mi->output_gpios[i]);
err_request_output_gpio_failed:
;
}
err_bad_keymap:
kfree(kp);
err_kp_alloc_failed:
err_invalid_platform_data:
return err;
}
Source - board-shakira-keypad.c & linux/semc/gpio_event.h
board-shakira-keypad.c
the scandalous line 90 is highlighted in red.
Code:
/*
* Copyright (C) 2009 SEMC
* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
* Author: Daniel Nygren <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/platform_device.h>
#include <linux/gpio_event.h>
#include <linux/semc/gpio_event.h>
#include "board-delta-keypad.h"
#include <mach/semc_rpc_server_handset.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
#define DBG(X)
static unsigned int keypad_row_gpios[] = { 31 };
static unsigned int keypad_col_gpios[] = { 36, 37, 38, 39, 40, 41 };
static atomic_t driver_up_and_running = ATOMIC_INIT(0);
static struct gpio_event_input_devs *kbd_input_dev;
#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(keypad_col_gpios) + (col))
static const unsigned short keypad_keymap_shakira[ARRAY_SIZE(keypad_col_gpios) *
ARRAY_SIZE(keypad_row_gpios)] = {
[KEYMAP_INDEX(0, 0)] = KEY_BACK, /* Left */
[KEYMAP_INDEX(0, 1)] = KEY_HOME, /* Middle */
[KEYMAP_INDEX(0, 2)] = KEY_MENU, /* Right */
[KEYMAP_INDEX(0, 3)] = KEY_VOLUMEUP,
[KEYMAP_INDEX(0, 4)] = KEY_VOLUMEDOWN,
[KEYMAP_INDEX(0, 5)] = KEY_CAMERA, /* Camera Snap */
};
static const unsigned short wakeup_inputs[ARRAY_SIZE(keypad_col_gpios)] = {
0,
1, /* KEY_HOME */
0,
1, /* KEY_VOLUMEUP */
1, /* KEY_VOLUMEDOWN */
0,
};
static unsigned short w_enabled_inputs[ARRAY_SIZE(keypad_col_gpios)];
static void configure_wakeup_inputs(const unsigned short *wi)
{
int i;
for (i = 0; i < ARRAY_SIZE(keypad_col_gpios); i++) {
if (w_enabled_inputs[i] == wi[i])
continue;
if (set_irq_wake(gpio_to_irq(keypad_col_gpios[i]), wi[i])) {
printk(KERN_ERR "%s: set_irq_wake failed for GPIO %d\n",
__func__, keypad_col_gpios[i]);
} else {
DBG(printk(KERN_DEBUG
"%s: set_irq_wake=%d for GPIO %d\n",
__func__, wi[i], keypad_col_gpios[i]);)
w_enabled_inputs[i] = wi[i];
}
}
}
static int shakira_gpio_event_matrix_func(
struct gpio_event_input_devs *input_devs,
struct gpio_event_info *info,
void **data, int func)
{
if (func == GPIO_EVENT_FUNC_INIT) {
struct input_dev *input_dev = input_devs->dev[0];
kbd_input_dev = input_devs;
input_set_capability(input_dev, EV_KEY, KEY_POWER);
input_set_capability(input_dev, EV_KEY, KEY_END);
atomic_set(&driver_up_and_running, 1);
}
if (func == GPIO_EVENT_FUNC_UNINIT)
atomic_set(&driver_up_and_running, 0);
configure_wakeup_inputs(wakeup_inputs);
return [COLOR="Red"]semc_gpio_event_matrix_func(input_devs, info, data, func)[/COLOR];
}
/* Shakira keypad platform device information */
static struct gpio_event_matrix_info shakira_keypad_matrix_info = {
.info.func = shakira_gpio_event_matrix_func,
.keymap = keypad_keymap_shakira,
.output_gpios = keypad_row_gpios,
.input_gpios = keypad_col_gpios,
.noutputs = ARRAY_SIZE(keypad_row_gpios),
.ninputs = ARRAY_SIZE(keypad_col_gpios),
.settle_time.tv.nsec = 0,
.poll_time.tv.nsec = 20 * NSEC_PER_MSEC,
.flags = GPIOKPF_LEVEL_TRIGGERED_IRQ |
GPIOKPF_PRINT_UNMAPPED_KEYS
};
static struct gpio_event_info *shakira_keypad_info[] = {
&shakira_keypad_matrix_info.info
};
static struct gpio_event_platform_data shakira_keypad_data = {
.name = "shakira_keypad",
.info = shakira_keypad_info,
.info_count = ARRAY_SIZE(shakira_keypad_info)
};
struct platform_device keypad_device_shakira = {
.name = GPIO_EVENT_DEV_NAME,
.id = -1,
.dev = {
.platform_data = &shakira_keypad_data,
},
};
struct platform_device *get_keypad_device_delta(void)
{
return &keypad_device_shakira;
}
void keypad_rpc_key_callback(uint32_t key, uint32_t event)
{
if (!atomic_read(&driver_up_and_running)) {
DBG(printk(KERN_DEBUG "%s: Power key ignored, driver"
" not ready\n", __func__));
return;
}
switch (key) {
case HS_PWR_K:
key = KEY_POWER;
break;
case HS_END_K:
key = KEY_END;
break;
default:
return;
}
DBG(printk(KERN_DEBUG "%s: reporting key (code %d, value %d)\n",
__func__, key, event != HS_REL_K);)
input_report_key(kbd_input_dev->dev[0], key, event != HS_REL_K);
}
gpio_event.h
Code:
#ifndef _SEMC_GPIO_EVENT_H_
#define _SEMC_GPIO_EVENT_H_
#include <linux/gpio_event.h>
#include <linux/input.h>
int semc_gpio_event_matrix_func(struct gpio_event_input_devs *input_dev,
struct gpio_event_info *info, void **data, int func);
int semc_gpio_event_input_func(struct gpio_event_input_devs *input_dev,
struct gpio_event_info *info, void **data, int func);
#endif /*_SEMC_GPIO_EVENT_H_*/
ivorh said:
can you just look in semc_gpio_matrix.c and add a prototype for that function into board-shakira-keypad.c if it's not provided in any of the other headers.
Click to expand...
Click to collapse
Seems like linux/semc/gpio_event.h already declared the prototype. That's all that it does.
i think i know the culprit....
board-shakira-keypad.c calls semc/gpio_event.h to declare the prototype.
but nowhere in those two files have the function actually defined.
The only file that have the function defined, semc_gpio_matrix.c, is not called by any other file.
How come SonyEricsson release such source files? is this not the final set that they use to compile the binaries on our phones?
My question now :
is it okay if i edit board-shakira-keypad.c into something like this :
Code:
#include <linux/platform_device.h>
#include <linux/gpio_event.h>
#include <linux/semc/gpio_event.h>
[COLOR="Red"][B]#include "../../../drivers/misc/semc/gpio_matrix/semc_gpio_matrix.c"[/B][/COLOR]
#include "board-delta-keypad.h"
#include <mach/semc_rpc_server_handset.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
compilation success this way.
however should i tell the compiler/makefile to find the symbol in the object file of semc_gpio_matrix.c instead?
there's no object file in the folder that contains semc_gpio_matrix.c, except for built-in.o. What should i do?
how about putting a line on top:
extern int semc_gpio_event_matrix_func(struct gpio_event_input_devs *input_dev,
struct gpio_event_info *info, void **data, int func);
And modify the makefile to compile and link the semc_gpio_matrix.c and it object file.
i_hate_sonyericsson said:
if it's really impossible, at this date, to use custom ROM on X8 why would then people are toying with the Floyo port?
Click to expand...
Click to collapse
Rom <> kernel. What they're doing is all BUT the kernel. Making drivers and libraries run on SEMC supplied kernel. I don't know much about low-level on the phone, but it's not like the google dev phones. The bootloader is very different. My guess is it's more like old SEMC phones. The google dev phones boot more like a pc. This is why there's no tether support on these ROMs.
There's tools for flashing files to the device, so I guess if you're able to make compatible files you'll get the kernel in there. Maybe have a word with the creators of the x10flash tool.
Simple!!!!
Asdoos said:
So nice to see someone dev the kernel and I`'m sorry to say I can't help but i'm interested how you wan't to flash the kernel. Isn't it locked by SE to flash a custom kerneL?
Click to expand...
Click to collapse
The answer is so simple...convert the kernel to .sin, then flash it with bin4ry's flasher
Nobody has try this.
Rename sin to img make changes img to sin flash
Sent from my X8
If that was so simple then multitouch would be the first thing done to the phone... Sin files are signed and hashed, if you change them signature becomes invalid and phone won't accept the file...
Sent from my X8, so sorry for gramatical inaccuracy
i think i took the wrong approach in learning system development for android....
i think i should have started via the kitchen section to better and easier understand the low level inner working of the system..
plus, for someone that comes from the Windows world still got much to learn about how things work in Linux world.

[Q] How to use multi-threaded class in bootanimation?

Hi Droid-expert
For stock bootanimation in JB, there is a single threaded animation process/class inside. If I'd like to implement the power-on sound/tune as well. What's the best programming scheme/model it could be?
So far, by my understanding, I did something in BootAnimation.cpp in the following:
Did I do wrong? The handset boots up, it shows the animation first, and then the sound is played.
However, in a normal AOS adb shell session, try to run bootanimation, and it works fine (I mean both animation and sound are played at the same time)
Does the init is multi-threaded?
Anthony
class PlayerListener: public MediaPlayerListener, public Thread
{
public:
PlayerListener(): Thread(false), mp(NULL) {}
~PlayerListener() { delete mp; mp = NULL; }
virtual void notify(int, int, int, const Parcel *) {}
virtual bool threadLoop();
virtual status_t readyToRun();
private:
MediaPlayer* mp;
};
// ----------------------------------------------------------------------
bool PlayerListener::threadLoop()
{
if (mp != NULL)
mp->start();
sleep(100);
requestExit();
return false;
}
status_t PlayerListener::readyToRun()
{
int index = 7;
audio_devices_t device;
bool r;
mp = new MediaPlayer();
mp->setListener(this);
if (mp->setDataSource(SYSTEM_BOOTANIMATION_SOUND_FILE, NULL) == NO_ERROR) {
mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
mp->prepare();
mp->setLooping(false);
}
// AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index);
device = AudioSystem::getDevicesForStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
r = AudioSystem::setStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, index, device);
r = AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index, device);
if (index != 0) {
mp->seekTo(0);
// mp->start();
}
return NO_ERROR;
}
bool BootAnimation::threadLoop()
{
bool r;
sp<PlayerListener> player = new PlayerListener();
player->run("BootAnimatedMelody", PRIORITY_AUDIO);
if (mAndroidAnimation) {
r = android();
} else {
r = movie();
}

[Q] My research on rooting Blade Apex 2

Hello XDA, i have been looking for a way to root the ZTE Blade Apex2 from Orange Spain (also known as Orange Hi 4G), and i found some interesting things about how the system manages the partitions and how the OTA update is done.
Packed inside Recovery.img in /etc/recovery.fstab we can read this:
Code:
# mount point fstype device [device2] [length=]
/dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,barrier=1 wait
/dev/block/platform/msm_sdcc.1/by-name/cache /cache ext4 noatime,nosuid,nodev,barrier=1,data=ordered wait,check
As you can see, the property BARRIER is enabled on all the mountpoints "interesting" to be accesed, so we CANT remount this mountpoints.
So i changed my mind to look for another way to try to make the trick, and unexpectedly, i found a nice glitch on the way how the official updater does the ota update process.
I decrypted the app itself from the decompyleandroid web, and got surprised.
The first thing called my attention is that the reboot on recovery to install the ota update, DONT check the signature of the file, its done by the otaupdater itself, so, we can try a replace file trick to change the target file.
Another interesting thing i found, is in the otaupdater, found this interesting piece of code:
Code:
[HIDE]package com.orange.authentication.utunneling.ttg;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class TtgX509TrustManager
implements X509TrustManager
{
private static final String KEYSTORE = "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";
[B][I][SIZE="3"][COLOR="Red"]private static final char PASSPHRASE[] = "orange".toCharArray();[/COLOR][/SIZE][/I][/B]
private X509TrustManager mTrustManager;
public TtgX509TrustManager(boolean flag)
throws GeneralSecurityException, IOException
{
if (flag)
{
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(newInputStream(decodeBase64("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")), PASSPHRASE);
TrustManagerFactory trustmanagerfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustmanagerfactory.init(keystore);
javax.net.ssl.TrustManager atrustmanager[] = trustmanagerfactory.getTrustManagers();
if (atrustmanager == null || atrustmanager.length != 1 || !(atrustmanager[0] instanceof X509TrustManager))
{
throw new IllegalArgumentException("Invalid keystore");
}
mTrustManager = (X509TrustManager)atrustmanager[0];
}
}
private static ByteBuffer decodeBase64(String s)
{
ByteBuffer bytebuffer = ByteBuffer.allocate((6 * s.length()) / 8);
int i = 0;
int j = 0;
for (int k = 0; k < s.length(); k++)
{
int l = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(s.charAt(k));
if (l == -1)
{
continue;
}
i = l | i << 6;
for (j += 6; j >= 8;)
{
j -= 8;
bytebuffer.put((byte)(i >> j));
}
}
bytebuffer.flip();
return bytebuffer;
}
private static InputStream newInputStream(ByteBuffer bytebuffer)
{
return new InputStream(bytebuffer) {
final ByteBuffer val$buffer;
public int read()
throws IOException
{
this;
JVM INSTR monitorenter ;
boolean flag = buffer.hasRemaining();
if (flag) goto _L2; else goto _L1
_L1:
byte byte1 = -1;
_L4:
this;
JVM INSTR monitorexit ;
return byte1;
_L2:
byte byte0 = buffer.get();
byte1 = byte0;
if (true) goto _L4; else goto _L3
_L3:
Exception exception;
exception;
throw exception;
}
public int read(byte abyte0[], int i, int j)
throws IOException
{
this;
JVM INSTR monitorenter ;
int k;
k = Math.min(j, buffer.remaining());
buffer.get(abyte0, i, k);
this;
JVM INSTR monitorexit ;
return k;
Exception exception;
exception;
throw exception;
}
{
buffer = bytebuffer;
super();
}
};
}
public void checkClientTrusted(X509Certificate ax509certificate[], String s)
throws CertificateException
{
if (mTrustManager != null)
{
mTrustManager.checkClientTrusted(ax509certificate, s);
}
}
public void checkServerTrusted(X509Certificate ax509certificate[], String s)
throws CertificateException
{
if (mTrustManager != null)
{
mTrustManager.checkServerTrusted(ax509certificate, s);
}
}
public X509Certificate[] getAcceptedIssuers()
{
if (mTrustManager != null)
{
return mTrustManager.getAcceptedIssuers();
} else
{
return new X509Certificate[0];
}
}
}[/HIDE]
Orange is so kind to provide us not only the certificate, but the key itself
Im uploading the sources of the otaupdater application that Orange is using on our Blade Apex2 aka Orange Hi 4G.
P.S. This phone allows us to upgrade and downgrade all the times needed, so dont hesitate to ask, just booting on recovery menu lets me flash previous firmware versions.
Hopes any developer find some time to take a look on it, im ready to test anything.

Kernel Sysfs Param Storage function - Get calling parameter

So, I hate to ask because I'm sure this is really simple...
I have this function that is storing a sysfs value. To save space, I have 4 different parameters sharing the function as it's basically the same function for each. I'd like to check which parameter is calling the function so that I can perform some checks depending on the parameter (ie, that each is in a logical order compared to it's neighboring values). How would I get the name of parameter that called it?
https://gist.github.com/yoinx/6a3ff00945f3ec1db230
embedded to avoid the link:
Code:
/* Frequency limit storage */
static int set_freq_limit(const char *val, const struct kernel_param *kp)
{
int ret = 0;
int i, cnt;
int valid = 0;
struct cpufreq_policy *policy;
static struct cpufreq_frequency_table *tbl = NULL;
ret = kstrtouint(val, 10, &i);
if (ret)
return -EINVAL;
policy = cpufreq_cpu_get(0);
tbl = cpufreq_frequency_get_table(0);
for (cnt = 0; (tbl[cnt].frequency != CPUFREQ_TABLE_END); cnt++) {
if (cnt > 0)
if (tbl[cnt].frequency == i)
valid = 1;
}
if (!valid)
return -EINVAL;
ret = param_set_int(val, kp);
return ret;
}
static struct kernel_param_ops freq_limit_ops = {
.set = set_freq_limit,
.get = param_get_int,
};
module_param_cb(freq_hell, &freq_limit_ops, &FREQ_HELL, 0644);
module_param_cb(freq_very_hot, &freq_limit_ops, &FREQ_VERY_HOT, 0644);
module_param_cb(freq_hot, &freq_limit_ops, &FREQ_HOT, 0644);
module_param_cb(freq_warm, &freq_limit_ops, &FREQ_WARM, 0644);
I could go even more sloppy and just duplicate this function repeatedly... But I'd rather not.
I thought kp would hold the kernel parameter... but it's a structure, not a variable... So I'm not positive what value in the structure would hold the name.
Thanks for the help.
Edit:
Would it be kp->name?
Ok, so not sure why it wouldn't work for me the other day... Which is what lead me to this post.
It was indeed kp->name, like I expected it to be. When I was trying to test it in a printk, it was causing a kernel panic though. Whatever, it worked now.
It prints out as module.param, just in case this helps anyone in the future.
*Edit*
Here's how I ended up doing this. Again, in case it helps anyone in the future.
Code:
/* Frequency limit storage */
static int set_freq_limit(const char *val, const struct kernel_param *kp)
{
int ret = 0;
int i, cnt;
int valid = 0;
struct cpufreq_policy *policy;
static struct cpufreq_frequency_table *tbl = NULL;
ret = kstrtouint(val, 10, &i);
if (ret)
return -EINVAL;
policy = cpufreq_cpu_get(0);
tbl = cpufreq_frequency_get_table(0);
for (cnt = 0; (tbl[cnt].frequency != CPUFREQ_TABLE_END); cnt++) {
if (cnt > 0)
if (tbl[cnt].frequency == i)
valid = 1;
}
if (!valid)
return -EINVAL;
/* Perform some sanity checks on the values that we're storing
* to make sure that they're scaling linearly */
if (strcmp( kp->name, "msm_thermal.freq_warm") == 0 && i <= FREQ_HOT)
return -EINVAL;
if ( strcmp( kp->name, "msm_thermal.freq_hot") == 0 && ( i >= FREQ_WARM || i <= FREQ_VERY_HOT ))
return -EINVAL;
if ( strcmp( kp->name, "msm_thermal.freq_very_hot") == 0 && ( i >= FREQ_HOT || i <= FREQ_HELL ))
return -EINVAL;
if ( strcmp( kp->name, "msm_thermal.freq_hell") == 0 && i >= FREQ_VERY_HOT )
return -EINVAL;
/* End Sanity Checks */
ret = param_set_int(val, kp);
return ret;
}
static struct kernel_param_ops freq_limit_ops = {
.set = set_freq_limit,
.get = param_get_int,
};
module_param_cb(freq_hell, &freq_limit_ops, &FREQ_HELL, 0644);
module_param_cb(freq_very_hot, &freq_limit_ops, &FREQ_VERY_HOT, 0644);
module_param_cb(freq_hot, &freq_limit_ops, &FREQ_HOT, 0644);
module_param_cb(freq_warm, &freq_limit_ops, &FREQ_WARM, 0644);

Trouble compiling Thunderplug hotplug

I am trying to add Thundeplug to my hotplug. Heres the code and error.
Code:
/* Copyright (c) 2015, Varun Chitre <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A simple hotplugging driver.
* Compatible from dual core CPUs to Octa Core CPUs
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/lcd_notify.h>
#include <linux/cpufreq.h>
#include "thunderplug.h"
#define DEBUG 0
#define THUNDERPLUG "thunderplug"
#define DRIVER_VERSION 5
#define DRIVER_SUBVER 0
#define DEFAULT_CPU_LOAD_THRESHOLD (65)
#define MIN_CPU_LOAD_THRESHOLD (10)
#define HOTPLUG_ENABLED (0)
#define DEFAULT_HOTPLUG_STYLE HOTPLUG_SCHED
#define DEFAULT_SCHED_MODE BALANCED
#define DEF_SAMPLING_MS (500)
#define MIN_SAMLING_MS (50)
#define MIN_CPU_UP_TIME (750)
#define TOUCH_BOOST_ENABLED (0)
static bool isSuspended = false;
struct notifier_block lcd_worker;
static int suspend_cpu_num = 2, resume_cpu_num = (NR_CPUS -1);
static int endurance_level = 0;
static int core_limit = NR_CPUS;
static int now[8], last_time[8];
static int sampling_time = DEF_SAMPLING_MS;
static int load_threshold = DEFAULT_CPU_LOAD_THRESHOLD;
static int stop_boost = 0;
struct cpufreq_policy old_policy[NR_CPUS];
#ifdef CONFIG_SCHED_HMP
static int tplug_hp_style = DEFAULT_HOTPLUG_STYLE;
#else
static int tplug_hp_enabled = HOTPLUG_ENABLED;
#endif
static int tplug_sched_mode = DEFAULT_SCHED_MODE;
static int touch_boost_enabled = TOUCH_BOOST_ENABLED;
static struct workqueue_struct *tplug_wq;
static struct delayed_work tplug_work;
static struct workqueue_struct *tplug_boost_wq;
static struct delayed_work tplug_boost;
static struct workqueue_struct *tplug_resume_wq;
static struct delayed_work tplug_resume_work;
static unsigned int last_load[8] = { 0 };
struct cpu_load_data {
u64 prev_cpu_idle;
u64 prev_cpu_wall;
unsigned int avg_load_maxfreq;
unsigned int cur_load_maxfreq;
unsigned int samples;
unsigned int window_size;
cpumask_var_t related_cpus;
};
static DEFINE_PER_CPU(struct cpu_load_data, cpuload);
/* Two Endurance Levels for Octa Cores,
* Two for Quad Cores and
* One for Dual
*/
static inline void offline_cpus(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(suspend_cpu_num > NR_CPUS / 2 )
suspend_cpu_num = NR_CPUS / 2;
break;
case 2:
if( NR_CPUS >=4 && suspend_cpu_num > NR_CPUS / 4)
suspend_cpu_num = NR_CPUS / 4;
break;
default:
break;
}
for(cpu = NR_CPUS - 1; cpu > (suspend_cpu_num - 1); cpu--) {
if (cpu_online(cpu))
cpu_down(cpu);
}
pr_info("%s: %d cpus were offlined\n", THUNDERPLUG, (NR_CPUS - suspend_cpu_num));
}
static inline void cpus_online_all(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(resume_cpu_num > (NR_CPUS / 2) - 1 || resume_cpu_num == 1)
resume_cpu_num = ((NR_CPUS / 2) - 1);
break;
case 2:
if( NR_CPUS >= 4 && resume_cpu_num > ((NR_CPUS / 4) - 1))
resume_cpu_num = ((NR_CPUS / 4) - 1);
break;
case 0:
resume_cpu_num = (NR_CPUS - 1);
break;
default:
break;
}
if(DEBUG)
pr_info("%s: resume_cpu_num = %d\n",THUNDERPLUG, resume_cpu_num);
for (cpu = 1; cpu <= resume_cpu_num; cpu++) {
if (cpu_is_offline(cpu))
cpu_up(cpu);
}
pr_info("%s: all cpus were onlined\n", THUNDERPLUG);
}
static void __ref tplug_boost_work_fn(struct work_struct *work)
{
struct cpufreq_policy policy;
int cpu, ret;
for(cpu = 1; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1)
#else
if(tplug_hp_enabled == 1)
#endif
if(cpu_is_offline(cpu))
cpu_up(cpu);
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
continue;
old_policy[cpu] = policy;
policy.min = policy.max;
cpufreq_update_policy(cpu);
}
if(stop_boost == 0)
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(10));
}
static void tplug_input_event(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
{
if (type == EV_KEY && code == BTN_TOUCH) {
if(DEBUG)
pr_info("%s : type = %d, code = %d, value = %d\n", THUNDERPLUG, type, code, value);
if(value == 0) {
stop_boost = 1;
if(DEBUG)
pr_info("%s: stopping boost\n", THUNDERPLUG);
}
else {
stop_boost = 0;
if(DEBUG)
pr_info("%s: starting boost\n", THUNDERPLUG);
}
}
#ifdef CONFIG_SCHED_HMP
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#else
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#endif
{
if(DEBUG)
pr_info("%s : touch boost\n", THUNDERPLUG);
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(0));
}
}
static int tplug_input_connect(struct input_handler *handler,
struct input_dev *dev, const struct input_device_id *id)
{
struct input_handle *handle;
int error;
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;
handle->dev = dev;
handle->handler = handler;
handle->name = "cpufreq";
error = input_register_handle(handle);
if (error)
goto err2;
error = input_open_device(handle);
if (error)
goto err1;
return 0;
err1:
input_unregister_handle(handle);
err2:
kfree(handle);
return error;
}
static void tplug_input_disconnect(struct input_handle *handle)
{
input_close_device(handle);
input_unregister_handle(handle);
kfree(handle);
}
static const struct input_device_id tplug_ids[] = {
{ .driver_info = 1 },
{ },
};
static struct input_handler tplug_input_handler = {
.event = tplug_input_event,
.connect = tplug_input_connect,
.disconnect = tplug_input_disconnect,
.name = "tplug_handler",
.id_table = tplug_ids,
};
static ssize_t thunderplug_suspend_cpus_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", suspend_cpu_num);
}
static ssize_t thunderplug_suspend_cpus_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val < 1 || val > NR_CPUS)
pr_info("%s: suspend cpus off-limits\n", THUNDERPLUG);
else
suspend_cpu_num = val;
return count;
}
static ssize_t thunderplug_endurance_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", endurance_level);
}
static ssize_t __ref thunderplug_endurance_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(tplug_hp_style == 1) {
switch(val) {
case 0:
case 1:
case 2:
if(endurance_level!=val &&
!(endurance_level > 1 && NR_CPUS < 4)) {
endurance_level = val;
offline_cpus();
cpus_online_all();
}
break;
default:
pr_info("%s: invalid endurance level\n", THUNDERPLUG);
break;
}
}
else
pr_info("%s: per-core hotplug style is disabled, ignoring endurance mode values\n", THUNDERPLUG);
return count;
}
static ssize_t thunderplug_sampling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", sampling_time);
}
static ssize_t __ref thunderplug_sampling_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > MIN_SAMLING_MS)
sampling_time = val;
return count;
}
static ssize_t thunderplug_tb_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", touch_boost_enabled);
}
static ssize_t __ref thunderplug_tb_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
switch(val)
{
case 0:
case 1:
touch_boost_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
return count;
}
static ssize_t thunderplug_load_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", load_threshold);
}
static ssize_t __ref thunderplug_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > 10)
load_threshold = val;
return count;
}
static unsigned int get_curr_load(unsigned int cpu)
{
int ret;
unsigned int idle_time, wall_time;
unsigned int cur_load;
u64 cur_wall_time, cur_idle_time;
struct cpu_load_data *pcpu = &per_cpu(cpuload, cpu);
struct cpufreq_policy policy;
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
return -EINVAL;
cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, 0);
wall_time = (unsigned int) (cur_wall_time - pcpu->prev_cpu_wall);
pcpu->prev_cpu_wall = cur_wall_time;
idle_time = (unsigned int) (cur_idle_time - pcpu->prev_cpu_idle);
pcpu->prev_cpu_idle = cur_idle_time;
if (unlikely(!wall_time || wall_time < idle_time))
return 0;
cur_load = 100 * (wall_time - idle_time) / wall_time;
return cur_load;
}
static void thunderplug_suspend(void)
{
offline_cpus();
pr_info("%s: suspend\n", THUNDERPLUG);
}
static void __ref thunderplug_resume(void)
{
cpus_online_all();
pr_info("%s: resume\n", THUNDERPLUG);
}
static void __cpuinit tplug_resume_work_fn(struct work_struct *work)
{
thunderplug_resume();
}
static void __cpuinit tplug_work_fn(struct work_struct *work)
{
int i;
unsigned int load[8], avg_load[8];
switch(endurance_level)
{
case 0:
core_limit = NR_CPUS;
break;
case 1:
core_limit = NR_CPUS / 2;
break;
case 2:
core_limit = NR_CPUS / 4;
break;
default:
core_limit = NR_CPUS;
break;
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i))
load[i] = get_curr_load(i);
else
load[i] = 0;
avg_load[i] = ((int) load[i] + (int) last_load[i]) / 2;
last_load[i] = load[i];
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i) && avg_load[i] > load_threshold && cpu_is_offline(i+1))
{
if(DEBUG)
pr_info("%s : bringing back cpu%d\n", THUNDERPLUG,i);
if(!((i+1) > 7)) {
last_time[i+1] = ktime_to_ms(ktime_get());
cpu_up(i+1);
}
}
else if(cpu_online(i) && avg_load[i] < load_threshold && cpu_online(i+1))
{
if(DEBUG)
pr_info("%s : offlining cpu%d\n", THUNDERPLUG,i);
if(!(i+1)==0) {
now[i+1] = ktime_to_ms(ktime_get());
if((now[i+1] - last_time[i+1]) > MIN_CPU_UP_TIME)
cpu_down(i+1);
}
}
}
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1 && !isSuspended)
#else
if(tplug_hp_enabled != 0 && !isSuspended)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else {
if(!isSuspended)
cpus_online_all();
else
thunderplug_suspend();
}
}
static int lcd_notifier_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
switch (event) {
case LCD_EVENT_ON_START:
isSuspended = false;
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style==1)
#else
if(tplug_hp_enabled)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else
queue_delayed_work_on(0, tplug_resume_wq, &tplug_resume_work,
msecs_to_jiffies(10));
pr_info("thunderplug : resume called\n");
break;
case LCD_EVENT_ON_END:
break;
case LCD_EVENT_OFF_START:
break;
case LCD_EVENT_OFF_END:
isSuspended = true;
pr_info("thunderplug : suspend called\n");
break;
default:
break;
}
return 0;
}
/* Thunderplug load balancer */
#ifdef CONFIG_SCHED_HMP
static void set_sched_profile(int mode) {
switch(mode) {
case 1:
/* Balanced */
sched_set_boost(DISABLED);
break;
case 2:
/* Turbo */
sched_set_boost(ENABLED);
break;
default:
pr_info("%s: Invalid mode\n", THUNDERPLUG);
break;
}
}
static ssize_t thunderplug_sched_mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_sched_mode);
}
static ssize_t __ref thunderplug_sched_mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
set_sched_profile(val);
tplug_sched_mode = val;
return count;
}
static ssize_t thunderplug_hp_style_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_style);
}
static ssize_t __ref thunderplug_hp_style_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val, last_val;
sscanf(buf, "%d", &val);
last_val = tplug_hp_style;
switch(val)
{
case HOTPLUG_PERCORE:
case HOTPLUG_SCHED:
tplug_hp_style = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_style == HOTPLUG_PERCORE && tplug_hp_style != last_val) {
pr_info("%s: Switching to Per-core hotplug model\n", THUNDERPLUG);
sched_set_boost(DISABLED);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
}
else if(tplug_hp_style==2) {
pr_info("%s: Switching to sched based hotplug model\n", THUNDERPLUG);
set_sched_profile(tplug_sched_mode);
}
return count;
}
static struct kobj_attribute thunderplug_hp_style_attribute =
__ATTR(hotplug_style,
0666,
thunderplug_hp_style_show, thunderplug_hp_style_store);
static struct kobj_attribute thunderplug_mode_attribute =
__ATTR(sched_mode,
0666,
thunderplug_sched_mode_show, thunderplug_sched_mode_store);
#else
static ssize_t thunderplug_hp_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_enabled);
}
static ssize_t __ref thunderplug_hp_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
int last_val = tplug_hp_enabled;
switch(val)
{
case 0:
case 1:
tplug_hp_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_enabled == 1 && tplug_hp_enabled != last_val)
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
return count;
}
static struct kobj_attribute thunderplug_hp_enabled_attribute =
__ATTR(hotplug_enabled,
0666,
thunderplug_hp_enabled_show, thunderplug_hp_enabled_store);
#endif
static ssize_t thunderplug_ver_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "ThunderPlug %u.%u", DRIVER_VERSION, DRIVER_SUBVER);
}
static struct kobj_attribute thunderplug_ver_attribute =
__ATTR(version,
0444,
thunderplug_ver_show, NULL);
static struct kobj_attribute thunderplug_suspend_cpus_attribute =
__ATTR(suspend_cpus,
0666,
thunderplug_suspend_cpus_show, thunderplug_suspend_cpus_store);
static struct kobj_attribute thunderplug_endurance_attribute =
__ATTR(endurance_level,
0666,
thunderplug_endurance_show, thunderplug_endurance_store);
static struct kobj_attribute thunderplug_sampling_attribute =
__ATTR(sampling_rate,
0666,
thunderplug_sampling_show, thunderplug_sampling_store);
static struct kobj_attribute thunderplug_load_attribute =
__ATTR(load_threshold,
0666,
thunderplug_load_show, thunderplug_load_store);
static struct kobj_attribute thunderplug_tb_enabled_attribute =
__ATTR(touch_boost,
0666,
thunderplug_tb_enabled_show, thunderplug_tb_enabled_store);
static struct attribute *thunderplug_attrs[] =
{
&thunderplug_ver_attribute.attr,
&thunderplug_suspend_cpus_attribute.attr,
&thunderplug_endurance_attribute.attr,
&thunderplug_sampling_attribute.attr,
&thunderplug_load_attribute.attr,
#ifdef CONFIG_SCHED_HMP
&thunderplug_mode_attribute.attr,
&thunderplug_hp_style_attribute.attr,
#else
&thunderplug_hp_enabled_attribute.attr,
#endif
&thunderplug_tb_enabled_attribute.attr,
NULL,
};
static struct attribute_group thunderplug_attr_group =
{
.attrs = thunderplug_attrs,
};
static struct kobject *thunderplug_kobj;
static int __init thunderplug_init(void)
{
int ret = 0;
int sysfs_result;
printk(KERN_DEBUG "[%s]\n",__func__);
thunderplug_kobj = kobject_create_and_add("thunderplug", kernel_kobj);
if (!thunderplug_kobj) {
pr_err("%s Interface create failed!\n",
__FUNCTION__);
return -ENOMEM;
}
sysfs_result = sysfs_create_group(thunderplug_kobj, &thunderplug_attr_group);
if (sysfs_result) {
pr_info("%s sysfs create failed!\n", __FUNCTION__);
kobject_put(thunderplug_kobj);
}
lcd_worker.notifier_call = lcd_notifier_callback;
lcd_register_client(&lcd_worker);
pr_info("%s : registering input boost", THUNDERPLUG);
ret = input_register_handler(&tplug_input_handler);
if (ret) {
pr_err("%s: Failed to register input handler: %d\n",
THUNDERPLUG, ret);
}
tplug_wq = alloc_workqueue("tplug",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_resume_wq = alloc_workqueue("tplug_resume",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_boost_wq = alloc_workqueue("tplug_boost",
WQ_HIGHPRI | WQ_UNBOUND, 1);
INIT_DELAYED_WORK(&tplug_work, tplug_work_fn);
INIT_DELAYED_WORK(&tplug_resume_work, tplug_resume_work_fn);
INIT_DELAYED_WORK(&tplug_boost, tplug_boost_work_fn);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(10));
pr_info("%s: init\n", THUNDERPLUG);
return ret;
}
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Varun Chitre <[email protected]>");
MODULE_DESCRIPTION("Hotplug driver for ARM SoCs");
late_initcall(thunderplug_init);
Here is my error.
Code:
CC arch/arm/mach-msm/thunderplug.o
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_endurance_store':
arch/arm/mach-msm/thunderplug.c:283:5: error: 'tplug_hp_style' undeclared (first use in this function)
if(tplug_hp_style == 1) {
^
arch/arm/mach-msm/thunderplug.c:283:5: note: each undeclared identifier is reported only once for each function it appears in
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_hp_enabled_store':
arch/arm/mach-msm/thunderplug.c:598:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
error, forbidden warning: thunderplug.c:598
make[1]: *** [arch/arm/mach-msm/thunderplug.o] Error 1
make[1]: *** Waiting for unfinished jobs...
Any help would be appreciated
apophis9283 said:
I am trying to add Thundeplug to my hotplug. Heres the code and error.
Code:
/* Copyright (c) 2015, Varun Chitre <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A simple hotplugging driver.
* Compatible from dual core CPUs to Octa Core CPUs
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/lcd_notify.h>
#include <linux/cpufreq.h>
#include "thunderplug.h"
#define DEBUG 0
#define THUNDERPLUG "thunderplug"
#define DRIVER_VERSION 5
#define DRIVER_SUBVER 0
#define DEFAULT_CPU_LOAD_THRESHOLD (65)
#define MIN_CPU_LOAD_THRESHOLD (10)
#define HOTPLUG_ENABLED (0)
#define DEFAULT_HOTPLUG_STYLE HOTPLUG_SCHED
#define DEFAULT_SCHED_MODE BALANCED
#define DEF_SAMPLING_MS (500)
#define MIN_SAMLING_MS (50)
#define MIN_CPU_UP_TIME (750)
#define TOUCH_BOOST_ENABLED (0)
static bool isSuspended = false;
struct notifier_block lcd_worker;
static int suspend_cpu_num = 2, resume_cpu_num = (NR_CPUS -1);
static int endurance_level = 0;
static int core_limit = NR_CPUS;
static int now[8], last_time[8];
static int sampling_time = DEF_SAMPLING_MS;
static int load_threshold = DEFAULT_CPU_LOAD_THRESHOLD;
static int stop_boost = 0;
struct cpufreq_policy old_policy[NR_CPUS];
#ifdef CONFIG_SCHED_HMP
static int tplug_hp_style = DEFAULT_HOTPLUG_STYLE;
#else
static int tplug_hp_enabled = HOTPLUG_ENABLED;
#endif
static int tplug_sched_mode = DEFAULT_SCHED_MODE;
static int touch_boost_enabled = TOUCH_BOOST_ENABLED;
static struct workqueue_struct *tplug_wq;
static struct delayed_work tplug_work;
static struct workqueue_struct *tplug_boost_wq;
static struct delayed_work tplug_boost;
static struct workqueue_struct *tplug_resume_wq;
static struct delayed_work tplug_resume_work;
static unsigned int last_load[8] = { 0 };
struct cpu_load_data {
u64 prev_cpu_idle;
u64 prev_cpu_wall;
unsigned int avg_load_maxfreq;
unsigned int cur_load_maxfreq;
unsigned int samples;
unsigned int window_size;
cpumask_var_t related_cpus;
};
static DEFINE_PER_CPU(struct cpu_load_data, cpuload);
/* Two Endurance Levels for Octa Cores,
* Two for Quad Cores and
* One for Dual
*/
static inline void offline_cpus(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(suspend_cpu_num > NR_CPUS / 2 )
suspend_cpu_num = NR_CPUS / 2;
break;
case 2:
if( NR_CPUS >=4 && suspend_cpu_num > NR_CPUS / 4)
suspend_cpu_num = NR_CPUS / 4;
break;
default:
break;
}
for(cpu = NR_CPUS - 1; cpu > (suspend_cpu_num - 1); cpu--) {
if (cpu_online(cpu))
cpu_down(cpu);
}
pr_info("%s: %d cpus were offlined\n", THUNDERPLUG, (NR_CPUS - suspend_cpu_num));
}
static inline void cpus_online_all(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(resume_cpu_num > (NR_CPUS / 2) - 1 || resume_cpu_num == 1)
resume_cpu_num = ((NR_CPUS / 2) - 1);
break;
case 2:
if( NR_CPUS >= 4 && resume_cpu_num > ((NR_CPUS / 4) - 1))
resume_cpu_num = ((NR_CPUS / 4) - 1);
break;
case 0:
resume_cpu_num = (NR_CPUS - 1);
break;
default:
break;
}
if(DEBUG)
pr_info("%s: resume_cpu_num = %d\n",THUNDERPLUG, resume_cpu_num);
for (cpu = 1; cpu <= resume_cpu_num; cpu++) {
if (cpu_is_offline(cpu))
cpu_up(cpu);
}
pr_info("%s: all cpus were onlined\n", THUNDERPLUG);
}
static void __ref tplug_boost_work_fn(struct work_struct *work)
{
struct cpufreq_policy policy;
int cpu, ret;
for(cpu = 1; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1)
#else
if(tplug_hp_enabled == 1)
#endif
if(cpu_is_offline(cpu))
cpu_up(cpu);
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
continue;
old_policy[cpu] = policy;
policy.min = policy.max;
cpufreq_update_policy(cpu);
}
if(stop_boost == 0)
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(10));
}
static void tplug_input_event(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
{
if (type == EV_KEY && code == BTN_TOUCH) {
if(DEBUG)
pr_info("%s : type = %d, code = %d, value = %d\n", THUNDERPLUG, type, code, value);
if(value == 0) {
stop_boost = 1;
if(DEBUG)
pr_info("%s: stopping boost\n", THUNDERPLUG);
}
else {
stop_boost = 0;
if(DEBUG)
pr_info("%s: starting boost\n", THUNDERPLUG);
}
}
#ifdef CONFIG_SCHED_HMP
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#else
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#endif
{
if(DEBUG)
pr_info("%s : touch boost\n", THUNDERPLUG);
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(0));
}
}
static int tplug_input_connect(struct input_handler *handler,
struct input_dev *dev, const struct input_device_id *id)
{
struct input_handle *handle;
int error;
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;
handle->dev = dev;
handle->handler = handler;
handle->name = "cpufreq";
error = input_register_handle(handle);
if (error)
goto err2;
error = input_open_device(handle);
if (error)
goto err1;
return 0;
err1:
input_unregister_handle(handle);
err2:
kfree(handle);
return error;
}
static void tplug_input_disconnect(struct input_handle *handle)
{
input_close_device(handle);
input_unregister_handle(handle);
kfree(handle);
}
static const struct input_device_id tplug_ids[] = {
{ .driver_info = 1 },
{ },
};
static struct input_handler tplug_input_handler = {
.event = tplug_input_event,
.connect = tplug_input_connect,
.disconnect = tplug_input_disconnect,
.name = "tplug_handler",
.id_table = tplug_ids,
};
static ssize_t thunderplug_suspend_cpus_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", suspend_cpu_num);
}
static ssize_t thunderplug_suspend_cpus_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val < 1 || val > NR_CPUS)
pr_info("%s: suspend cpus off-limits\n", THUNDERPLUG);
else
suspend_cpu_num = val;
return count;
}
static ssize_t thunderplug_endurance_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", endurance_level);
}
static ssize_t __ref thunderplug_endurance_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(tplug_hp_style == 1) {
switch(val) {
case 0:
case 1:
case 2:
if(endurance_level!=val &&
!(endurance_level > 1 && NR_CPUS < 4)) {
endurance_level = val;
offline_cpus();
cpus_online_all();
}
break;
default:
pr_info("%s: invalid endurance level\n", THUNDERPLUG);
break;
}
}
else
pr_info("%s: per-core hotplug style is disabled, ignoring endurance mode values\n", THUNDERPLUG);
return count;
}
static ssize_t thunderplug_sampling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", sampling_time);
}
static ssize_t __ref thunderplug_sampling_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > MIN_SAMLING_MS)
sampling_time = val;
return count;
}
static ssize_t thunderplug_tb_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", touch_boost_enabled);
}
static ssize_t __ref thunderplug_tb_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
switch(val)
{
case 0:
case 1:
touch_boost_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
return count;
}
static ssize_t thunderplug_load_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", load_threshold);
}
static ssize_t __ref thunderplug_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > 10)
load_threshold = val;
return count;
}
static unsigned int get_curr_load(unsigned int cpu)
{
int ret;
unsigned int idle_time, wall_time;
unsigned int cur_load;
u64 cur_wall_time, cur_idle_time;
struct cpu_load_data *pcpu = &per_cpu(cpuload, cpu);
struct cpufreq_policy policy;
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
return -EINVAL;
cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, 0);
wall_time = (unsigned int) (cur_wall_time - pcpu->prev_cpu_wall);
pcpu->prev_cpu_wall = cur_wall_time;
idle_time = (unsigned int) (cur_idle_time - pcpu->prev_cpu_idle);
pcpu->prev_cpu_idle = cur_idle_time;
if (unlikely(!wall_time || wall_time < idle_time))
return 0;
cur_load = 100 * (wall_time - idle_time) / wall_time;
return cur_load;
}
static void thunderplug_suspend(void)
{
offline_cpus();
pr_info("%s: suspend\n", THUNDERPLUG);
}
static void __ref thunderplug_resume(void)
{
cpus_online_all();
pr_info("%s: resume\n", THUNDERPLUG);
}
static void __cpuinit tplug_resume_work_fn(struct work_struct *work)
{
thunderplug_resume();
}
static void __cpuinit tplug_work_fn(struct work_struct *work)
{
int i;
unsigned int load[8], avg_load[8];
switch(endurance_level)
{
case 0:
core_limit = NR_CPUS;
break;
case 1:
core_limit = NR_CPUS / 2;
break;
case 2:
core_limit = NR_CPUS / 4;
break;
default:
core_limit = NR_CPUS;
break;
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i))
load[i] = get_curr_load(i);
else
load[i] = 0;
avg_load[i] = ((int) load[i] + (int) last_load[i]) / 2;
last_load[i] = load[i];
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i) && avg_load[i] > load_threshold && cpu_is_offline(i+1))
{
if(DEBUG)
pr_info("%s : bringing back cpu%d\n", THUNDERPLUG,i);
if(!((i+1) > 7)) {
last_time[i+1] = ktime_to_ms(ktime_get());
cpu_up(i+1);
}
}
else if(cpu_online(i) && avg_load[i] < load_threshold && cpu_online(i+1))
{
if(DEBUG)
pr_info("%s : offlining cpu%d\n", THUNDERPLUG,i);
if(!(i+1)==0) {
now[i+1] = ktime_to_ms(ktime_get());
if((now[i+1] - last_time[i+1]) > MIN_CPU_UP_TIME)
cpu_down(i+1);
}
}
}
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1 && !isSuspended)
#else
if(tplug_hp_enabled != 0 && !isSuspended)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else {
if(!isSuspended)
cpus_online_all();
else
thunderplug_suspend();
}
}
static int lcd_notifier_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
switch (event) {
case LCD_EVENT_ON_START:
isSuspended = false;
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style==1)
#else
if(tplug_hp_enabled)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else
queue_delayed_work_on(0, tplug_resume_wq, &tplug_resume_work,
msecs_to_jiffies(10));
pr_info("thunderplug : resume called\n");
break;
case LCD_EVENT_ON_END:
break;
case LCD_EVENT_OFF_START:
break;
case LCD_EVENT_OFF_END:
isSuspended = true;
pr_info("thunderplug : suspend called\n");
break;
default:
break;
}
return 0;
}
/* Thunderplug load balancer */
#ifdef CONFIG_SCHED_HMP
static void set_sched_profile(int mode) {
switch(mode) {
case 1:
/* Balanced */
sched_set_boost(DISABLED);
break;
case 2:
/* Turbo */
sched_set_boost(ENABLED);
break;
default:
pr_info("%s: Invalid mode\n", THUNDERPLUG);
break;
}
}
static ssize_t thunderplug_sched_mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_sched_mode);
}
static ssize_t __ref thunderplug_sched_mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
set_sched_profile(val);
tplug_sched_mode = val;
return count;
}
static ssize_t thunderplug_hp_style_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_style);
}
static ssize_t __ref thunderplug_hp_style_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val, last_val;
sscanf(buf, "%d", &val);
last_val = tplug_hp_style;
switch(val)
{
case HOTPLUG_PERCORE:
case HOTPLUG_SCHED:
tplug_hp_style = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_style == HOTPLUG_PERCORE && tplug_hp_style != last_val) {
pr_info("%s: Switching to Per-core hotplug model\n", THUNDERPLUG);
sched_set_boost(DISABLED);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
}
else if(tplug_hp_style==2) {
pr_info("%s: Switching to sched based hotplug model\n", THUNDERPLUG);
set_sched_profile(tplug_sched_mode);
}
return count;
}
static struct kobj_attribute thunderplug_hp_style_attribute =
__ATTR(hotplug_style,
0666,
thunderplug_hp_style_show, thunderplug_hp_style_store);
static struct kobj_attribute thunderplug_mode_attribute =
__ATTR(sched_mode,
0666,
thunderplug_sched_mode_show, thunderplug_sched_mode_store);
#else
static ssize_t thunderplug_hp_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_enabled);
}
static ssize_t __ref thunderplug_hp_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
int last_val = tplug_hp_enabled;
switch(val)
{
case 0:
case 1:
tplug_hp_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_enabled == 1 && tplug_hp_enabled != last_val)
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
return count;
}
static struct kobj_attribute thunderplug_hp_enabled_attribute =
__ATTR(hotplug_enabled,
0666,
thunderplug_hp_enabled_show, thunderplug_hp_enabled_store);
#endif
static ssize_t thunderplug_ver_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "ThunderPlug %u.%u", DRIVER_VERSION, DRIVER_SUBVER);
}
static struct kobj_attribute thunderplug_ver_attribute =
__ATTR(version,
0444,
thunderplug_ver_show, NULL);
static struct kobj_attribute thunderplug_suspend_cpus_attribute =
__ATTR(suspend_cpus,
0666,
thunderplug_suspend_cpus_show, thunderplug_suspend_cpus_store);
static struct kobj_attribute thunderplug_endurance_attribute =
__ATTR(endurance_level,
0666,
thunderplug_endurance_show, thunderplug_endurance_store);
static struct kobj_attribute thunderplug_sampling_attribute =
__ATTR(sampling_rate,
0666,
thunderplug_sampling_show, thunderplug_sampling_store);
static struct kobj_attribute thunderplug_load_attribute =
__ATTR(load_threshold,
0666,
thunderplug_load_show, thunderplug_load_store);
static struct kobj_attribute thunderplug_tb_enabled_attribute =
__ATTR(touch_boost,
0666,
thunderplug_tb_enabled_show, thunderplug_tb_enabled_store);
static struct attribute *thunderplug_attrs[] =
{
&thunderplug_ver_attribute.attr,
&thunderplug_suspend_cpus_attribute.attr,
&thunderplug_endurance_attribute.attr,
&thunderplug_sampling_attribute.attr,
&thunderplug_load_attribute.attr,
#ifdef CONFIG_SCHED_HMP
&thunderplug_mode_attribute.attr,
&thunderplug_hp_style_attribute.attr,
#else
&thunderplug_hp_enabled_attribute.attr,
#endif
&thunderplug_tb_enabled_attribute.attr,
NULL,
};
static struct attribute_group thunderplug_attr_group =
{
.attrs = thunderplug_attrs,
};
static struct kobject *thunderplug_kobj;
static int __init thunderplug_init(void)
{
int ret = 0;
int sysfs_result;
printk(KERN_DEBUG "[%s]\n",__func__);
thunderplug_kobj = kobject_create_and_add("thunderplug", kernel_kobj);
if (!thunderplug_kobj) {
pr_err("%s Interface create failed!\n",
__FUNCTION__);
return -ENOMEM;
}
sysfs_result = sysfs_create_group(thunderplug_kobj, &thunderplug_attr_group);
if (sysfs_result) {
pr_info("%s sysfs create failed!\n", __FUNCTION__);
kobject_put(thunderplug_kobj);
}
lcd_worker.notifier_call = lcd_notifier_callback;
lcd_register_client(&lcd_worker);
pr_info("%s : registering input boost", THUNDERPLUG);
ret = input_register_handler(&tplug_input_handler);
if (ret) {
pr_err("%s: Failed to register input handler: %d\n",
THUNDERPLUG, ret);
}
tplug_wq = alloc_workqueue("tplug",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_resume_wq = alloc_workqueue("tplug_resume",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_boost_wq = alloc_workqueue("tplug_boost",
WQ_HIGHPRI | WQ_UNBOUND, 1);
INIT_DELAYED_WORK(&tplug_work, tplug_work_fn);
INIT_DELAYED_WORK(&tplug_resume_work, tplug_resume_work_fn);
INIT_DELAYED_WORK(&tplug_boost, tplug_boost_work_fn);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(10));
pr_info("%s: init\n", THUNDERPLUG);
return ret;
}
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Varun Chitre <[email protected]>");
MODULE_DESCRIPTION("Hotplug driver for ARM SoCs");
late_initcall(thunderplug_init);
Here is my error.
Code:
CC arch/arm/mach-msm/thunderplug.o
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_endurance_store':
arch/arm/mach-msm/thunderplug.c:283:5: error: 'tplug_hp_style' undeclared (first use in this function)
if(tplug_hp_style == 1) {
^
arch/arm/mach-msm/thunderplug.c:283:5: note: each undeclared identifier is reported only once for each function it appears in
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_hp_enabled_store':
arch/arm/mach-msm/thunderplug.c:598:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
error, forbidden warning: thunderplug.c:598
make[1]: *** [arch/arm/mach-msm/thunderplug.o] Error 1
make[1]: *** Waiting for unfinished jobs...
Any help would be appreciated
Click to expand...
Click to collapse
Hard to say without seeing your whole kernel source but it looks like you don't use:
CONFIG_SCHED_HMP
@RenderBroken
See here, thanks for helping
https://github.com/varunchitre15/th...36ca2904495a/arch/arm64/hotplug/thunderplug.c
Looking for the commits now
Doesnt look like I have whats needed. Might take awhile to track all the commits down
Edit: Still not working. Ill keep looking into it
apophis9283 said:
@RenderBroken
See here, thanks for helping
https://github.com/varunchitre15/th...36ca2904495a/arch/arm64/hotplug/thunderplug.c
Looking for the commits now
Doesnt look like I have whats needed. Might take awhile to track all the commits down
Edit: Still not working. Ill keep looking into it
Click to expand...
Click to collapse
No sweat bro.
I am pretty sure the problem is that you are missing all the HMP commits in /kernel/sched and the hotplug driver wasn't coded to work without HMP. (By accident, I think he meant to though)
I have them but there is a large bringup to make it work I have done it with my test branch here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3
Honestly, I don't think it is worth the work.
RenderBroken said:
No sweat bro.
I am pretty sure the problem is that you are missing all the HMP commits in /kernel/sched and the hotplug driver wasn't coded to work without HMP. (By accident, I think he meant to though)
I have them but there is a large bringup to make it work I have done it with my test branch here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3
Honestly, I don't think it is worth the work.
Click to expand...
Click to collapse
I really want to get it working. I have it working but its like v1.0, im trying to get 5.0 to work
apophis9283 said:
I really want to get it working. I have it working but its like v1.0, im trying to get 5.0 to work
Click to expand...
Click to collapse
If you really want it working then you will need to make all the sched commits starting from here: https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=10
to here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=1
RenderBroken said:
If you really want it working then you will need to make all the sched commits starting from here: https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=10
to here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=1
Click to expand...
Click to collapse
Im just merging that branch into mine
apophis9283 said:
Im just merging that branch into mine
Click to expand...
Click to collapse
you know, the way I merge a massive number of commits in order is by:
1. git fetch the remote source to your local kernel source. This may mean adding the remote first.
2. Now you can create patches from their commits by using: git format-patch
3 So to create a range of patches from a range of commits (they have to be in order) you just:
Code:
git format-patch 8a8e3fff2c84152a7cb3895ff3b98fd6115f2d5a..142bfdc7328dd5290e99216674a2a48e23f645ba
The above is just an example but notice the".." in between the SHA1's. This means "and all commits in between these two commits".
4. So once you have all the patches created in your local source, you can apply them all really easily by running:
Code:
git am *.patch
The above means to apply all patches because all patches end in ".patch"
It will then start applying the patches in order right ontop of your source. If it fails a single commit it will let you fix it, skip it or just abort the whole thing. To fix it I just look for the commit message in the other's kernel source and cherry-pick it like normal. Cherry-picking is not as picky as git am is so most of the time it will apply the commit. If it succeeds, you just run:
Code:
git am --skip
Since you had applied the commit manually so it can skip over doing it.
To me this just keeps history cleaner and can sometimes be a huge time saver when all you want is a range of commits from another's source without merging in their other crap you dont want.
RenderBroken said:
you know, the way I merge a massive number of commits in order is by:
1. git fetch the remote source to your local kernel source. This may mean adding the remote first.
2. Now you can create patches from their commits by using: git format-patch
3 So to create a range of patches from a range of commits (they have to be in order) you just:
Code:
git format-patch 8a8e3fff2c84152a7cb3895ff3b98fd6115f2d5a..142bfdc7328dd5290e99216674a2a48e23f645ba
The above is just an example but notice the".." in between the SHA1's. This means "and all commits in between these two commits".
4. So once you have all the patches created in your local source, you can apply them all really easily by running:
Code:
git am *.patch
The above means to apply all patches because all patches end in ".patch"
It will then start applying the patches in order right ontop of your source. If it fails a single commit it will let you fix it, skip it or just abort the whole thing. To fix it I just look for the commit message in the other's kernel source and cherry-pick it like normal. Cherry-picking is not as picky as git am is so most of the time it will apply the commit. If it succeeds, you just run:
Code:
git am --skip
Since you had applied the commit manually so it can skip over doing it.
To me this just keeps history cleaner and can sometimes be a huge time saver when all you want is a range of commits from another's source without merging in their other crap you dont want.
Click to expand...
Click to collapse
sweet
apophis9283 said:
sweet
Click to expand...
Click to collapse
Yea, neobuddy89 taught me that trick a long time ago. I use it ALL the time when rebasing and such.
RenderBroken said:
Yea, neobuddy89 taught me that trick a long time ago. I use it ALL the time when rebasing and such.
Click to expand...
Click to collapse
Working on it now. Still gonna take a bit
Decided just to cp it all. It may take most of the night but...
apophis9283 said:
Decided just to cp it all. It may take most of the night but...
Click to expand...
Click to collapse
It takes time to Learn properly. I know it took me quite a bit of time at least.
RenderBroken said:
It takes time to Learn properly. I know it took me quite a bit of time at least.
Click to expand...
Click to collapse
Yeah, ive actually got quite far
Just merged all those. Damn that sucked
@RenderBroken
I get this error, not sure if i missed anything
kernel/sched/core.c: In function 'sd_init_CPU':
kernel/sched/core.c:8448:8: error: 'SD_CPU_INIT' undeclared (first use in this function)
*sd = SD_##type##_INIT; \
^
kernel/sched/core.c:8454:1: note: in expansion of macro 'SD_INIT_FUNC'
SD_INIT_FUNC(CPU)
^
kernel/sched/core.c:8448:8: note: each undeclared identifier is reported only once for each function it appears in
*sd = SD_##type##_INIT; \
^
kernel/sched/core.c:8454:1: note: in expansion of macro 'SD_INIT_FUNC'
SD_INIT_FUNC(CPU)
^
kernel/sched/core.c: In function 'sd_init_MC':
kernel/sched/core.c:8448:8: error: 'SD_MC_INIT' undeclared (first use in this function)
*sd = SD_##type##_INIT; \
^
kernel/sched/core.c:8459:2: note: in expansion of macro 'SD_INIT_FUNC'
SD_INIT_FUNC(MC)
^
I think topology is what im missing for that error. Just not sure
apophis9283 said:
I think topology is what im missing for that error. Just not sure
Click to expand...
Click to collapse
yea, did you remove the CONFIG_SCHED_MC stuff from your source?
RenderBroken said:
yea, did you remove the CONFIG_SCHED_MC stuff from your source?
Click to expand...
Click to collapse
Dont think so. Ive been trying all day to get it to compile
@RenderBroken
What would I be looking for?
I looked at my topology.h file. The parts that errored are in it
Probably just gonna revert all that. I cant get it working so its not worth the time
@RenderBroken
I decided to take a different route.
drivers/soc/qcom/thunderplug.c:281:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
I need to change it to c99 but dont know what to edit

Categories

Resources