summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/arch/arm/kernel
diff options
context:
space:
mode:
authorKevin2014-11-15 10:00:36 +0800
committerKevin2014-11-15 10:00:36 +0800
commit9d40ac5867b9aefe0722bc1f110b965ff294d30d (patch)
treede942df665fac4bac0d9cb7ae86910fe937b0c1a /ANDROID_3.4.5/arch/arm/kernel
parent392e8802486cb573b916e746010e141a75f507e6 (diff)
downloadFOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.tar.gz
FOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.tar.bz2
FOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.zip
add via modify part source code for wm8880 4.4 kitkat
Diffstat (limited to 'ANDROID_3.4.5/arch/arm/kernel')
-rw-r--r--ANDROID_3.4.5/arch/arm/kernel/Makefile1
-rw-r--r--ANDROID_3.4.5/arch/arm/kernel/bios32.c3
-rwxr-xr-xANDROID_3.4.5/arch/arm/kernel/hibernate.c177
-rw-r--r--ANDROID_3.4.5/arch/arm/kernel/io.c28
-rw-r--r--ANDROID_3.4.5/arch/arm/kernel/process.c15
-rw-r--r--ANDROID_3.4.5/arch/arm/kernel/sched_clock.c2
-rw-r--r--ANDROID_3.4.5/arch/arm/kernel/smp_twd.c22
7 files changed, 235 insertions, 13 deletions
diff --git a/ANDROID_3.4.5/arch/arm/kernel/Makefile b/ANDROID_3.4.5/arch/arm/kernel/Makefile
index 7b787d64..d6ee77fb 100644
--- a/ANDROID_3.4.5/arch/arm/kernel/Makefile
+++ b/ANDROID_3.4.5/arch/arm/kernel/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o
+obj-$(CONFIG_HIBERNATION) += hibernate.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
diff --git a/ANDROID_3.4.5/arch/arm/kernel/bios32.c b/ANDROID_3.4.5/arch/arm/kernel/bios32.c
index ede5f774..c3232b36 100644
--- a/ANDROID_3.4.5/arch/arm/kernel/bios32.c
+++ b/ANDROID_3.4.5/arch/arm/kernel/bios32.c
@@ -473,7 +473,7 @@ void __init pci_common_init(struct hw_pci *hw)
list_for_each_entry(sys, &hw->buses, node) {
struct pci_bus *bus = sys->bus;
-
+#if 0
if (!pci_has_flag(PCI_PROBE_ONLY)) {
/*
* Size the bridge windows.
@@ -490,6 +490,7 @@ void __init pci_common_init(struct hw_pci *hw)
*/
pci_enable_bridges(bus);
}
+#endif
/*
* Tell drivers about devices found.
diff --git a/ANDROID_3.4.5/arch/arm/kernel/hibernate.c b/ANDROID_3.4.5/arch/arm/kernel/hibernate.c
new file mode 100755
index 00000000..4aa1dc98
--- /dev/null
+++ b/ANDROID_3.4.5/arch/arm/kernel/hibernate.c
@@ -0,0 +1,177 @@
+/*
+ * Hibernation support specific for ARM
+ *
+ * Derived from work on ARM hibernation support by:
+ *
+ * Ubuntu project, hibernation support for mach-dove
+ * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu)
+ * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.)
+ * https://lkml.org/lkml/2010/6/18/4
+ * https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html
+ * https://patchwork.kernel.org/patch/96442/
+ *
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+/*
+ from patch
+ ARM hibernation / suspend-to-disk
+ https://github.com/russdill/linux/commit/498079e0d06d2c0bd575ab4114d16b09e1ff3111
+ add by roger.
+*/
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <asm/system_misc.h>
+#include <linux/slab.h>
+#include <linux/crc32.h>
+#include <asm/idmap.h>
+#include <asm/suspend.h>
+
+#define _PRINT_PAGE_CRC_ 1//also need to define in kernel/power/power.h
+#undef _PRINT_PAGE_CRC_
+
+extern const void __nosave_begin, __nosave_end;
+extern void cpu_resume(void);
+extern void cpu_resume_restore_nosave(void);
+
+u32 __nosave_backup_phys; //__nosave data backup here.
+u32 __nosave_begin_phys; //__nosave data orginal location begin from here.
+u32 __nosave_end_phys; //__nosave data orginal location end from here.
+
+void swsusp_arch_add_info(char *archdata, size_t size)
+{
+ *(u32 *) archdata = virt_to_phys(cpu_resume);
+ printk("\n phyaddr of cpu_resume : 0x%x \n", virt_to_phys(cpu_resume));
+ *(((u32 *)archdata) + 1) = __nosave_backup_phys;
+ *(((u32 *)archdata) + 2) = __nosave_begin_phys;
+ *(((u32 *)archdata) + 3) = __nosave_end_phys;
+/*
+ Save and check idmap_pgd.
+ When using Kernel restoring method, the "restoring kernel" should has the same
+ idmap_pgd as the "restored kernel".
+ If not, the mmu table may be corrupted during the restoration,
+ which may cause data abort (MMU translation fail).
+*/
+ *(((u32 *)archdata) + 4) = (u32)idmap_pgd;
+}
+
+int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long nosave_begin_pfn =
+ __pa_symbol(&__nosave_begin) >> PAGE_SHIFT;
+ unsigned long nosave_end_pfn =
+ PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT;
+
+ return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
+
+void notrace save_processor_state(void)
+{
+ WARN_ON(num_online_cpus() != 1);
+ flush_thread();
+ local_fiq_disable();
+}
+
+void notrace restore_processor_state(void)
+{
+ local_fiq_enable();
+}
+
+/*
+ * Snapshot kernel memory and reset the system.
+ * After resume, the hibernation snapshot is written out.
+ */
+static int notrace __swsusp_arch_save_image(unsigned long unused)
+{
+ extern int swsusp_save(void);
+ int ret;
+
+ ret = swsusp_save();
+ if (ret == 0)
+ soft_restart(virt_to_phys(cpu_resume));
+ return ret;
+}
+
+/*
+ * Save the current CPU state before suspend / poweroff.
+ */
+int notrace swsusp_arch_suspend(void)
+{
+ return cpu_suspend(0, __swsusp_arch_save_image);
+}
+
+/*
+ * The framework loads the hibernation image into a linked list anchored
+ * at restore_pblist, for swsusp_arch_resume() to copy back to the proper
+ * destinations.
+ *
+ * To make this work if resume is triggered from initramfs, the
+ * pagetables need to be switched to allow writes to kernel mem.
+ */
+static void notrace __swsusp_arch_restore_image(void *unused)
+{
+ extern struct pbe *restore_pblist;
+ struct pbe *pbe;
+#ifdef _PRINT_PAGE_CRC_// add by roger.
+ unsigned long crc_le;
+ unsigned char *virt_addr;
+ unsigned long pfn;
+#endif
+
+
+ cpu_switch_mm(idmap_pgd, &init_mm);
+ for (pbe = restore_pblist; pbe; pbe = pbe->next){
+ copy_page(pbe->orig_address, pbe->address);
+ #ifdef _PRINT_PAGE_CRC_
+ virt_addr = pbe->orig_address;
+ pfn = page_to_pfn(virt_to_page(virt_addr));
+ crc_le = crc32_le(0, virt_addr, PAGE_SIZE);
+ printk("pfn:%lu:phy_addr:0x%x:crc:%lu:virt_addr:0x%x\n",
+ pfn, pfn*PAGE_SIZE, crc_le, virt_addr);
+ #endif
+ }
+ soft_restart_noirq(virt_to_phys(cpu_resume));
+}
+
+static u8 __swsusp_resume_stk[PAGE_SIZE/2] __nosavedata;
+
+/*
+ * Resume from the hibernation image.
+ * Due to the kernel heap / data restore, stack contents change underneath
+ * and that would make function calls impossible; switch to a temporary
+ * stack within the nosave region to avoid that problem.
+ */
+int __naked swsusp_arch_resume(void)
+{
+ extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
+
+ cpu_init(); /* get a clean PSR */
+ call_with_stack(__swsusp_arch_restore_image, 0,
+ __swsusp_resume_stk + sizeof(__swsusp_resume_stk));
+
+ return 0;
+}
+
+static int __init swsusp_arch_init(void)
+{
+ char *backup;
+ size_t len;
+ len = &__nosave_end - &__nosave_begin;
+ backup = kmalloc(len, GFP_KERNEL);
+ if (backup) {
+ printk("%s: Backed up %d byte nosave region\n", __func__, len);
+ memcpy(backup, &__nosave_begin, len);
+ }
+
+ __nosave_backup_phys = virt_to_phys(backup);
+ __nosave_begin_phys = virt_to_phys(&__nosave_begin);
+ __nosave_end_phys = virt_to_phys(&__nosave_end);
+ printk("__nosave_backup_phys=0x%x\n",__nosave_backup_phys);
+ printk("__nosave_begin_phys=0x%x\n",__nosave_begin_phys);
+ printk("__nosave_end_phys=0x%x\n",__nosave_end_phys);
+ return 0;
+}
+late_initcall(swsusp_arch_init);
diff --git a/ANDROID_3.4.5/arch/arm/kernel/io.c b/ANDROID_3.4.5/arch/arm/kernel/io.c
index dcd5b4d8..ba8f0559 100644
--- a/ANDROID_3.4.5/arch/arm/kernel/io.c
+++ b/ANDROID_3.4.5/arch/arm/kernel/io.c
@@ -23,13 +23,39 @@ void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
*/
void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
{
- const unsigned char *f = from;
+ /*const unsigned char *f = from;
while (count) {
count--;
writeb(*f, to);
f++;
to++;
+ }*/
+ /*Dannierchen update for 4 byte data memory cpy*/
+ void *vdest = (void __force *) to;
+
+ //__asm__ __volatile__ ("sync" : : : "memory");
+ while(count && ((((unsigned long)vdest)&3) || (((unsigned long)from)&3))) {
+ *((volatile u8 *)vdest) = *((u8 *)from);
+ from++;
+ vdest++;
+ count--;
+ /*printk("start sf_write(vdest:0x%x, from:0x%x )\n", vdest, from);*/
}
+ while(count >= 4) {
+ *((volatile u32 *)vdest) = *((volatile u32 *)from);
+ from += 4;
+ vdest += 4;
+ count-=4;
+ }
+ while(count) {
+ *((volatile u8 *)vdest) = *((u8 *)from);
+ from++;
+ vdest++;
+ count--;
+ /*printk("end sf_write(vdest:0x%x, from:0x%x )\n", vdest, from);*/
+ }
+ //__asm__ __volatile__ ("sync" : : : "memory");
+
}
/*
diff --git a/ANDROID_3.4.5/arch/arm/kernel/process.c b/ANDROID_3.4.5/arch/arm/kernel/process.c
index 41aad9ed..df0dec8e 100644
--- a/ANDROID_3.4.5/arch/arm/kernel/process.c
+++ b/ANDROID_3.4.5/arch/arm/kernel/process.c
@@ -162,6 +162,21 @@ static void __soft_restart(void *addr)
BUG();
}
+void soft_restart_noirq(unsigned long addr)/*add by roger.*/
+{
+ u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
+
+ /* Disable the L2 if we're the last man standing. */
+ if (num_online_cpus() == 1)
+ outer_disable();
+
+ /* Change to the new stack and continue with the reset. */
+ call_with_stack(__soft_restart, (void *)addr, (void *)stack);
+
+ /* Should never get here. */
+ BUG();
+}
+
void soft_restart(unsigned long addr)
{
u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
diff --git a/ANDROID_3.4.5/arch/arm/kernel/sched_clock.c b/ANDROID_3.4.5/arch/arm/kernel/sched_clock.c
index f4515393..69d63e56 100644
--- a/ANDROID_3.4.5/arch/arm/kernel/sched_clock.c
+++ b/ANDROID_3.4.5/arch/arm/kernel/sched_clock.c
@@ -149,7 +149,7 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
* Start the timer to keep sched_clock() properly updated and
* sets the initial epoch.
*/
- sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
+ sched_clock_timer.data = msecs_to_jiffies((w - (w / 10))/2);
update_sched_clock();
/*
diff --git a/ANDROID_3.4.5/arch/arm/kernel/smp_twd.c b/ANDROID_3.4.5/arch/arm/kernel/smp_twd.c
index fef42b21..ad0ac9a0 100644
--- a/ANDROID_3.4.5/arch/arm/kernel/smp_twd.c
+++ b/ANDROID_3.4.5/arch/arm/kernel/smp_twd.c
@@ -26,6 +26,7 @@
#include <asm/smp_twd.h>
#include <asm/localtimer.h>
#include <asm/hardware/gic.h>
+#include <mach/hardware.h>
/* set up by the platform code */
static void __iomem *twd_base;
@@ -104,7 +105,7 @@ static void twd_timer_stop(struct clock_event_device *clk)
*/
static void twd_update_frequency(void *data)
{
- twd_timer_rate = clk_get_rate(twd_clk);
+ twd_timer_rate = (auto_pll_divisor(DEV_ARM, GET_CPUTIMER, 0, 0) / 2);
clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
}
@@ -121,7 +122,7 @@ static int twd_cpufreq_transition(struct notifier_block *nb,
*/
if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
smp_call_function_single(freqs->cpu, twd_update_frequency,
- NULL, 1);
+ data, 1);
return NOTIFY_OK;
}
@@ -229,14 +230,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
struct clock_event_device **this_cpu_clk;
- if (!twd_clk)
- twd_clk = twd_get_clock();
-
- if (!IS_ERR_OR_NULL(twd_clk))
- twd_timer_rate = clk_get_rate(twd_clk);
- else
- twd_calibrate_rate();
-
+ twd_calibrate_rate();
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
clk->name = "local_timer";
@@ -282,6 +276,14 @@ static int __init twd_local_timer_common_register(void)
if (err)
goto out_irq;
+ if (!twd_clk)
+ twd_clk = twd_get_clock();
+
+ if (!IS_ERR_OR_NULL(twd_clk))
+ twd_timer_rate = clk_get_rate(twd_clk);
+ else
+ twd_calibrate_rate();
+
return 0;
out_irq: