mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
8
arch/avr32/oprofile/Makefile
Normal file
8
arch/avr32/oprofile/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
obj-$(CONFIG_OPROFILE) += oprofile.o
|
||||
|
||||
oprofile-y := $(addprefix ../../../drivers/oprofile/, \
|
||||
oprof.o cpu_buffer.o buffer_sync.o \
|
||||
event_buffer.o oprofile_files.o \
|
||||
oprofilefs.o oprofile_stats.o \
|
||||
timer_int.o)
|
||||
oprofile-y += op_model_avr32.o backtrace.o
|
81
arch/avr32/oprofile/backtrace.c
Normal file
81
arch/avr32/oprofile/backtrace.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* AVR32 specific backtracing code for oprofile
|
||||
*
|
||||
* Copyright 2008 Weinmann GmbH
|
||||
*
|
||||
* Author: Nikolaus Voss <n.voss@weinmann.de>
|
||||
*
|
||||
* Based on i386 oprofile backtrace code by John Levon and David Smith
|
||||
*
|
||||
* 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/oprofile.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/* The first two words of each frame on the stack look like this if we have
|
||||
* frame pointers */
|
||||
struct frame_head {
|
||||
unsigned long lr;
|
||||
struct frame_head *fp;
|
||||
};
|
||||
|
||||
/* copied from arch/avr32/kernel/process.c */
|
||||
static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
|
||||
{
|
||||
return (p > (unsigned long)tinfo)
|
||||
&& (p < (unsigned long)tinfo + THREAD_SIZE - 3);
|
||||
}
|
||||
|
||||
/* copied from arch/x86/oprofile/backtrace.c */
|
||||
static struct frame_head *dump_user_backtrace(struct frame_head *head)
|
||||
{
|
||||
struct frame_head bufhead[2];
|
||||
|
||||
/* Also check accessibility of one struct frame_head beyond */
|
||||
if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
|
||||
return NULL;
|
||||
if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
|
||||
return NULL;
|
||||
|
||||
oprofile_add_trace(bufhead[0].lr);
|
||||
|
||||
/* frame pointers should strictly progress back up the stack
|
||||
* (towards higher addresses) */
|
||||
if (bufhead[0].fp <= head)
|
||||
return NULL;
|
||||
|
||||
return bufhead[0].fp;
|
||||
}
|
||||
|
||||
void avr32_backtrace(struct pt_regs * const regs, unsigned int depth)
|
||||
{
|
||||
/* Get first frame pointer */
|
||||
struct frame_head *head = (struct frame_head *)(regs->r7);
|
||||
|
||||
if (!user_mode(regs)) {
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
/*
|
||||
* Traverse the kernel stack from frame to frame up to
|
||||
* "depth" steps.
|
||||
*/
|
||||
while (depth-- && valid_stack_ptr(task_thread_info(current),
|
||||
(unsigned long)head)) {
|
||||
oprofile_add_trace(head->lr);
|
||||
if (head->fp <= head)
|
||||
break;
|
||||
head = head->fp;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* Assume we have frame pointers in user mode process */
|
||||
while (depth-- && head)
|
||||
head = dump_user_backtrace(head);
|
||||
}
|
||||
}
|
||||
|
||||
|
236
arch/avr32/oprofile/op_model_avr32.c
Normal file
236
arch/avr32/oprofile/op_model_avr32.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* AVR32 Performance Counter Driver
|
||||
*
|
||||
* Copyright (C) 2005-2007 Atmel Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Ronny Pedersen
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
#define AVR32_PERFCTR_IRQ_GROUP 0
|
||||
#define AVR32_PERFCTR_IRQ_LINE 1
|
||||
|
||||
void avr32_backtrace(struct pt_regs * const regs, unsigned int depth);
|
||||
|
||||
enum { PCCNT, PCNT0, PCNT1, NR_counter };
|
||||
|
||||
struct avr32_perf_counter {
|
||||
unsigned long enabled;
|
||||
unsigned long event;
|
||||
unsigned long count;
|
||||
unsigned long unit_mask;
|
||||
unsigned long kernel;
|
||||
unsigned long user;
|
||||
|
||||
u32 ie_mask;
|
||||
u32 flag_mask;
|
||||
};
|
||||
|
||||
static struct avr32_perf_counter counter[NR_counter] = {
|
||||
{
|
||||
.ie_mask = SYSREG_BIT(IEC),
|
||||
.flag_mask = SYSREG_BIT(FC),
|
||||
}, {
|
||||
.ie_mask = SYSREG_BIT(IE0),
|
||||
.flag_mask = SYSREG_BIT(F0),
|
||||
}, {
|
||||
.ie_mask = SYSREG_BIT(IE1),
|
||||
.flag_mask = SYSREG_BIT(F1),
|
||||
},
|
||||
};
|
||||
|
||||
static void avr32_perf_counter_reset(void)
|
||||
{
|
||||
/* Reset all counter and disable/clear all interrupts */
|
||||
sysreg_write(PCCR, (SYSREG_BIT(PCCR_R)
|
||||
| SYSREG_BIT(PCCR_C)
|
||||
| SYSREG_BIT(FC)
|
||||
| SYSREG_BIT(F0)
|
||||
| SYSREG_BIT(F1)));
|
||||
}
|
||||
|
||||
static irqreturn_t avr32_perf_counter_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct avr32_perf_counter *ctr = dev_id;
|
||||
struct pt_regs *regs;
|
||||
u32 pccr;
|
||||
|
||||
if (likely(!(intc_get_pending(AVR32_PERFCTR_IRQ_GROUP)
|
||||
& (1 << AVR32_PERFCTR_IRQ_LINE))))
|
||||
return IRQ_NONE;
|
||||
|
||||
regs = get_irq_regs();
|
||||
pccr = sysreg_read(PCCR);
|
||||
|
||||
/* Clear the interrupt flags we're about to handle */
|
||||
sysreg_write(PCCR, pccr);
|
||||
|
||||
/* PCCNT */
|
||||
if (ctr->enabled && (pccr & ctr->flag_mask)) {
|
||||
sysreg_write(PCCNT, -ctr->count);
|
||||
oprofile_add_sample(regs, PCCNT);
|
||||
}
|
||||
ctr++;
|
||||
/* PCNT0 */
|
||||
if (ctr->enabled && (pccr & ctr->flag_mask)) {
|
||||
sysreg_write(PCNT0, -ctr->count);
|
||||
oprofile_add_sample(regs, PCNT0);
|
||||
}
|
||||
ctr++;
|
||||
/* PCNT1 */
|
||||
if (ctr->enabled && (pccr & ctr->flag_mask)) {
|
||||
sysreg_write(PCNT1, -ctr->count);
|
||||
oprofile_add_sample(regs, PCNT1);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int avr32_perf_counter_create_files(struct dentry *root)
|
||||
{
|
||||
struct dentry *dir;
|
||||
unsigned int i;
|
||||
char filename[4];
|
||||
|
||||
for (i = 0; i < NR_counter; i++) {
|
||||
snprintf(filename, sizeof(filename), "%u", i);
|
||||
dir = oprofilefs_mkdir(root, filename);
|
||||
|
||||
oprofilefs_create_ulong(dir, "enabled",
|
||||
&counter[i].enabled);
|
||||
oprofilefs_create_ulong(dir, "event",
|
||||
&counter[i].event);
|
||||
oprofilefs_create_ulong(dir, "count",
|
||||
&counter[i].count);
|
||||
|
||||
/* Dummy entries */
|
||||
oprofilefs_create_ulong(dir, "kernel",
|
||||
&counter[i].kernel);
|
||||
oprofilefs_create_ulong(dir, "user",
|
||||
&counter[i].user);
|
||||
oprofilefs_create_ulong(dir, "unit_mask",
|
||||
&counter[i].unit_mask);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int avr32_perf_counter_setup(void)
|
||||
{
|
||||
struct avr32_perf_counter *ctr;
|
||||
u32 pccr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
pr_debug("avr32_perf_counter_setup\n");
|
||||
|
||||
if (sysreg_read(PCCR) & SYSREG_BIT(PCCR_E)) {
|
||||
printk(KERN_ERR
|
||||
"oprofile: setup: perf counter already enabled\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ret = request_irq(AVR32_PERFCTR_IRQ_GROUP,
|
||||
avr32_perf_counter_interrupt, IRQF_SHARED,
|
||||
"oprofile", counter);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
avr32_perf_counter_reset();
|
||||
|
||||
pccr = 0;
|
||||
for (i = PCCNT; i < NR_counter; i++) {
|
||||
ctr = &counter[i];
|
||||
if (!ctr->enabled)
|
||||
continue;
|
||||
|
||||
pr_debug("enabling counter %d...\n", i);
|
||||
|
||||
pccr |= ctr->ie_mask;
|
||||
|
||||
switch (i) {
|
||||
case PCCNT:
|
||||
/* PCCNT always counts cycles, so no events */
|
||||
sysreg_write(PCCNT, -ctr->count);
|
||||
break;
|
||||
case PCNT0:
|
||||
pccr |= SYSREG_BF(CONF0, ctr->event);
|
||||
sysreg_write(PCNT0, -ctr->count);
|
||||
break;
|
||||
case PCNT1:
|
||||
pccr |= SYSREG_BF(CONF1, ctr->event);
|
||||
sysreg_write(PCNT1, -ctr->count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("oprofile: writing 0x%x to PCCR...\n", pccr);
|
||||
|
||||
sysreg_write(PCCR, pccr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void avr32_perf_counter_shutdown(void)
|
||||
{
|
||||
pr_debug("avr32_perf_counter_shutdown\n");
|
||||
|
||||
avr32_perf_counter_reset();
|
||||
free_irq(AVR32_PERFCTR_IRQ_GROUP, counter);
|
||||
}
|
||||
|
||||
static int avr32_perf_counter_start(void)
|
||||
{
|
||||
pr_debug("avr32_perf_counter_start\n");
|
||||
|
||||
sysreg_write(PCCR, sysreg_read(PCCR) | SYSREG_BIT(PCCR_E));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void avr32_perf_counter_stop(void)
|
||||
{
|
||||
pr_debug("avr32_perf_counter_stop\n");
|
||||
|
||||
sysreg_write(PCCR, sysreg_read(PCCR) & ~SYSREG_BIT(PCCR_E));
|
||||
}
|
||||
|
||||
static struct oprofile_operations avr32_perf_counter_ops __initdata = {
|
||||
.create_files = avr32_perf_counter_create_files,
|
||||
.setup = avr32_perf_counter_setup,
|
||||
.shutdown = avr32_perf_counter_shutdown,
|
||||
.start = avr32_perf_counter_start,
|
||||
.stop = avr32_perf_counter_stop,
|
||||
.cpu_type = "avr32",
|
||||
};
|
||||
|
||||
int __init oprofile_arch_init(struct oprofile_operations *ops)
|
||||
{
|
||||
if (!(current_cpu_data.features & AVR32_FEATURE_PCTR))
|
||||
return -ENODEV;
|
||||
|
||||
memcpy(ops, &avr32_perf_counter_ops,
|
||||
sizeof(struct oprofile_operations));
|
||||
|
||||
ops->backtrace = avr32_backtrace;
|
||||
|
||||
printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void oprofile_arch_exit(void)
|
||||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue