diff options
Diffstat (limited to 'packages/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch')
-rw-r--r-- | packages/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch | 561 |
1 files changed, 0 insertions, 561 deletions
diff --git a/packages/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch b/packages/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch deleted file mode 100644 index f8343f89e1..0000000000 --- a/packages/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch +++ /dev/null @@ -1,561 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- linux-2.4.17_mvl21/arch/arm/mach-sa1100/apm.c~apm-hh-merge -+++ linux-2.4.17_mvl21/arch/arm/mach-sa1100/apm.c -@@ -86,6 +86,8 @@ - int magic; - struct apm_user * next; - int suser: 1; -+ int writer : 1; -+ int reader : 1; - int suspend_wait: 1; - int suspend_result; - int suspends_pending; -@@ -105,7 +107,7 @@ - /* - * Local variables - */ --//static int suspends_pending; -+static int suspends_pending; - //static int standbys_pending; - //static int ignore_normal_resume; - -@@ -123,8 +125,6 @@ - #else - static int power_off = 1; - #endif --static int exit_kapmd; --static int kapmd_running; - - static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); - static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); -@@ -192,6 +192,41 @@ - return as->events[as->event_tail]; - } - -+static void queue_event(apm_event_t event, struct apm_user *sender) -+{ -+ struct apm_user * as; -+ if (user_list == NULL) -+ return; -+ for (as = user_list; as != NULL; as = as->next) { -+ if ((as == sender) || (!as->reader)) -+ continue; -+ as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; -+ if (as->event_head == as->event_tail) { -+ static int notified; -+ -+ if (notified++ == 0) -+ printk(KERN_ERR "apm: an event queue overflowed\n"); -+ as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; -+ } -+ as->events[as->event_head] = event; -+ if ((!as->suser) || (!as->writer)) -+ continue; -+ switch (event) { -+ case APM_SYS_SUSPEND: -+ case APM_USER_SUSPEND: -+ as->suspends_pending++; -+ suspends_pending++; -+ break; -+ -+ case APM_SYS_STANDBY: -+ case APM_USER_STANDBY: -+ as->standbys_pending++; -+ break; -+ } -+ } -+ wake_up_interruptible(&apm_waitqueue); -+} -+ - static int check_apm_user(struct apm_user *as, const char *func) - { - if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) { -@@ -270,7 +305,6 @@ - return 0; - } - --extern int pm_do_suspend(void); - - static int do_ioctl(struct inode * inode, struct file *filp, - u_int cmd, u_long arg) -@@ -284,7 +318,17 @@ - return -EPERM; - switch (cmd) { - case APM_IOC_SUSPEND: -- pm_do_suspend(); -+ if (as->suspends_read > 0) { -+ as->suspends_read--; -+ as->suspends_pending--; -+ suspends_pending--; -+ } else { -+ queue_event(APM_USER_SUSPEND, as); -+ } -+ -+ if (suspends_pending <= 0) -+ wake_up(&apm_suspend_waitqueue); -+ - break; - default: - return -EINVAL; -@@ -301,6 +345,20 @@ - return 0; - filp->private_data = NULL; - lock_kernel(); -+ if (user_list == as) -+ user_list = as->next; -+ else { -+ struct apm_user * as1; -+ -+ for (as1 = user_list; -+ (as1 != NULL) && (as1->next != as); -+ as1 = as1->next) -+ ; -+ if (as1 == NULL) -+ printk(KERN_ERR "apm: filp not in user list\n"); -+ else -+ as1->next = as->next; -+ } - unlock_kernel(); - kfree(as); - return 0; -@@ -328,6 +386,8 @@ - * privileged operation -- cevans - */ - as->suser = capable(CAP_SYS_ADMIN); -+ as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; -+ as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; - as->next = user_list; - user_list = as; - filp->private_data = as; -@@ -411,33 +471,7 @@ - return p - buf; - } - --#ifndef MODULE --static int __init apm_setup(char *str) --{ -- int invert; -- -- while ((str != NULL) && (*str != '\0')) { -- if (strncmp(str, "off", 3) == 0) -- apm_disabled = 1; -- if (strncmp(str, "on", 2) == 0) -- apm_disabled = 0; -- invert = (strncmp(str, "no-", 3) == 0); -- if (invert) -- str += 3; -- if (strncmp(str, "debug", 5) == 0) -- debug = !invert; -- if ((strncmp(str, "power-off", 9) == 0) || -- (strncmp(str, "power_off", 9) == 0)) -- power_off = !invert; -- str = strchr(str, ','); -- if (str != NULL) -- str += strspn(str, ", \t"); -- } -- return 1; --} - --__setup("apm=", apm_setup); --#endif - - static struct file_operations apm_bios_fops = { - owner: THIS_MODULE, -@@ -449,13 +483,55 @@ - }; - - static struct miscdevice apm_device = { -- APM_MINOR_DEV, -- "apm_bios", -- &apm_bios_fops -+ minor : APM_MINOR_DEV, -+ name : "apm_bios", -+ fops : &apm_bios_fops - }; - - #define APM_INIT_ERROR_RETURN return -1 - -+static pid_t apmd_pid; -+static DECLARE_COMPLETION(apmd_exited); -+ -+static int apm(void *unused) -+{ -+ unsigned short bx; -+ unsigned short cx; -+ unsigned short dx; -+ int error; -+ char * power_stat; -+ char * bat_stat; -+ DECLARE_WAITQUEUE(wait, current); -+ struct apm_user au, *as; -+ -+ lock_kernel(); -+ -+ daemonize(); -+ -+ strcpy(current->comm, "kapmd"); -+ -+ as = &au; -+ as->magic = APM_BIOS_MAGIC; -+ as->event_tail = as->event_head = 0; -+ as->suspends_pending = as->standbys_pending = 0; -+ as->suspends_read = as->standbys_read = 0; -+ as->suser = 1; -+ as->writer = 1; -+ as->reader = 0; -+ -+ while (!signal_pending (current)) { -+ interruptible_sleep_on(&apm_suspend_waitqueue); -+ -+ pm_suggest_suspend(); -+ -+ queue_event(APM_NORMAL_RESUME, as); -+ } -+ -+ unlock_kernel(); -+ -+ complete_and_exit(&apmd_exited, 0); -+} -+ - /* - * Just start the APM thread. We do NOT want to do APM BIOS - * calls from anything but the APM thread, if for no other reason -@@ -494,18 +570,19 @@ - - misc_register(&apm_device); - -+ apmd_pid = kernel_thread(apm, NULL, 0); -+ - return 0; - } - - static void __exit apm_exit(void) - { - misc_deregister(&apm_device); -- remove_proc_entry("apm", NULL); -+ remove_proc_entry("apm", NULL); -+ kill_proc (apmd_pid, SIGTERM, 1); -+ wait_for_completion(&apmd_exited); - if (power_off) - pm_power_off = NULL; -- exit_kapmd = 1; -- while (kapmd_running) -- schedule(); - pm_active = 0; - } - -@@ -514,6 +591,7 @@ - - MODULE_AUTHOR("Jamey Hicks, pulling bits from original by Stephen Rothwell"); - MODULE_DESCRIPTION("A minimal emulation of APM"); -+MODULE_LICENSE("GPL"); - MODULE_PARM(debug, "i"); - MODULE_PARM_DESC(debug, "Enable debug mode"); - MODULE_PARM(power_off, "i"); ---- linux-2.4.17_mvl21/arch/arm/mach-sa1100/pm.c~apm-hh-merge -+++ linux-2.4.17_mvl21/arch/arm/mach-sa1100/pm.c -@@ -53,6 +53,10 @@ - #include <asm/arch/assabet.h> - #endif - -+#define __KERNEL_SYSCALLS__ -+#include <linux/unistd.h> -+ -+ - /* - * ARGH! Stupid ACPI people. They should define this in linux/sysctl.h, - * NOT linux/acpi.h. -@@ -64,123 +68,6 @@ - #define CTL_ACPI 9999 - #define ACPI_S1_SLP_TYP 19 - --#ifndef CONFIG_SA1100_BEAGLE -- --extern void sa1100_cpu_suspend(void); --extern void sa1100_cpu_resume(void); -- --extern unsigned long *sleep_save; /* virtual address */ --extern unsigned long sleep_save_p; /* physical address */ -- --#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x --#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] -- --int sa1110_suspend(void) --{ -- int retval; -- -- /* set up pointer to sleep parameters */ -- sleep_save = kmalloc (SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC); -- if (!sleep_save) -- return -ENOMEM; -- sleep_save_p = virt_to_phys(sleep_save); -- -- retval = pm_send_all(PM_SUSPEND, (void *)2); -- if (retval) { -- kfree(sleep_save); -- return retval; -- } -- -- cli(); -- -- /* preserve current time */ -- RCNR = xtime.tv_sec; -- -- /* save vital registers */ -- SAVE(OSCR); -- SAVE(OSMR0); -- SAVE(OSMR1); -- SAVE(OSMR2); -- SAVE(OSMR3); -- SAVE(OIER); -- -- SAVE(GPDR); -- SAVE(GRER); -- SAVE(GFER); -- SAVE(GAFR); -- -- SAVE(PPDR); -- SAVE(PPSR); -- SAVE(PPAR); -- SAVE(PSDR); -- -- SAVE(Ser1SDCR0); -- -- SAVE(ICMR); -- -- /* ... maybe a global variable initialized by arch code to set this? */ -- GRER = PWER; -- GFER = 0; -- GEDR = GEDR; -- -- /* Clear previous reset status */ -- RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; -- -- /* set resume return address */ -- PSPR = virt_to_phys(sa1100_cpu_resume); -- -- /* go zzz */ -- sa1100_cpu_suspend(); -- -- /* ensure not to come back here if it wasn't intended */ -- PSPR = 0; -- -- DPRINTK("*** made it back from resume\n"); -- -- /* restore registers */ -- RESTORE(GPDR); -- RESTORE(GRER); -- RESTORE(GFER); -- RESTORE(GAFR); -- -- /* clear any edge detect bit */ -- GEDR = GEDR; -- -- RESTORE(PPDR); -- RESTORE(PPSR); -- RESTORE(PPAR); -- RESTORE(PSDR); -- -- RESTORE(Ser1SDCR0); -- -- PSSR = PSSR_PH; -- -- RESTORE(OSMR0); -- RESTORE(OSMR1); -- RESTORE(OSMR2); -- RESTORE(OSMR3); -- RESTORE(OSCR); -- RESTORE(OIER); -- -- ICLR = 0; -- ICCR = 1; -- RESTORE(ICMR); -- -- /* restore current time */ -- xtime.tv_sec = RCNR; -- -- sti(); -- -- kfree (sleep_save); -- --#ifdef CONFIG_CPU_FREQ -- cpufreq_restore(); --#endif -- -- return pm_send_all(PM_RESUME, (void *)0); --} -- --#else //CONFIG_SA1100_BEAGLE - - typedef struct _tag_SLEEP_SAVED_DATA { - uint wakeup_addr; -@@ -363,9 +250,6 @@ - " ); - } - --extern void h3600_control_egpio( enum ipaq_egpio_type x, int setp ); --extern unsigned long h3600_read_egpio( void ); -- - static int GPDR_saved; - static int GPLR_saved; - static int GRER_saved; -@@ -742,21 +626,37 @@ - Ser3UTSR1 = 0xff; - } - --#endif //CONFIG_SA1100_BEAGLE -- -+/* -+ * If pm_suggest_suspend_hook is non-NULL, it is called by pm_suggest_suspend. -+ * -+ * If sysctl_pm_do_suspend_hook is non-NULL, it is called by sysctl_pm_do_suspend. -+ * If it returns a true value, then pm_suspend is not called. -+ * Use this to hook in apmd, for now. -+ * -+ * -not exported just so that the code compiles -+ */ -+int (*pm_suggest_suspend_hook)(int state); -+int (*pm_sysctl_suspend_hook)(int state); -+int pm_use_sbin_pm_helper = 1; - static char pm_helper_path[128] = "/sbin/pm_helper"; -+extern int exec_usermodehelper(char *path, char **argv, char **envp); -+int debug_pm = 0; -+static int pm_helper_veto = 0; - --static void -+static int - run_sbin_pm_helper( pm_request_t action ) - { - int i; - char *argv[3], *envp[8]; - - if (!pm_helper_path[0]) -- return; -+ return 2; - - if ( action != PM_SUSPEND && action != PM_RESUME ) -- return; -+ return 1; -+ -+ /* Be root */ -+ current->uid = current->gid = 0; - - i = 0; - argv[i++] = pm_helper_path; -@@ -771,14 +671,15 @@ - envp[i] = 0; - - /* other stuff we want to pass to /sbin/hotplug */ -- call_usermodehelper (argv [0], argv, envp); -+ return exec_usermodehelper (argv [0], argv, envp); - } - -+int pm_force_suspend(void); -+ - int pm_do_suspend(void) - { -- DPRINTK("suggest\n"); -- run_sbin_pm_helper(PM_SUSPEND); -- return 0; -+ DPRINTK("suspend now\n"); -+ return pm_force_suspend(); - } - - #ifdef CONFIG_SA1100_BEAGLE -@@ -863,9 +764,91 @@ - } - #endif - -+int pm_suggest_suspend(void) -+{ -+ int retval; -+ -+ if (pm_suggest_suspend_hook) { -+ if (pm_suggest_suspend_hook(PM_SUSPEND)) -+ return 0; -+ } -+ -+ if (pm_use_sbin_pm_helper) { -+ pid_t pid; -+ int res; -+ int status = 0; -+ unsigned int old_fs; -+ -+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_SUSPEND, 0 ); -+ if ( pid < 0 ) -+ return pid; -+ -+ if (debug_pm) -+ printk(KERN_CRIT "%s:%d got pid=%d\n", __FUNCTION__, __LINE__, pid); -+ -+ old_fs = get_fs (); -+ set_fs (get_ds ()); -+ res = waitpid(pid, &status, __WCLONE); -+ set_fs (old_fs); -+ -+ if ( pid != res ) { -+ if (debug_pm) -+ printk(KERN_CRIT ": waitpid returned %d (exit_code=%d); not suspending\n", res, status ); -+ -+ return -1; -+ } -+ -+ /*if ( WIFEXITED(status) && ( WIFEXITSTATUS(status) != 0 )) {*/ -+ if (( status & 0xff7f ) != 0 ) { -+ if (pm_helper_veto) { -+ if (debug_pm) -+ printk(KERN_CRIT "%s: SUSPEND WAS CANCELLED BY pm_helper (exit status %d)\n", __FUNCTION__, status >> 8); -+ return -1; -+ } else { -+ if (debug_pm) -+ printk(KERN_CRIT "%s: pm_helper returned %d, but going ahead anyway\n", __FUNCTION__, status >> 8); -+ } -+ } -+ } -+ -+ if (debug_pm) -+ printk(KERN_CRIT "%s: REALLY SUSPENDING NOW\n", __FUNCTION__ ); -+ -+ if (pm_sysctl_suspend_hook) { -+ if (pm_sysctl_suspend_hook(PM_SUSPEND)) -+ return 0; -+ } -+ -+ retval = pm_do_suspend(); -+ if (retval) { -+ if (debug_pm) -+ printk(KERN_CRIT "pm_suspend returned %d\n", retval); -+ return retval; -+ } -+ -+ if (pm_use_sbin_pm_helper) { -+ pid_t pid; -+ -+ if (debug_pm) -+ printk(KERN_CRIT "%s: running pm_helper for wakeup\n", __FUNCTION__); -+ -+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_RESUME, 0 ); -+ if ( pid < 0 ) -+ return pid; -+ -+ if ( pid != waitpid ( pid, NULL, __WCLONE )) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(pm_suggest_suspend); -+ -+ - static struct ctl_table pm_table[] = - { -- {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0644, NULL, (proc_handler *)&pm_force_suspend}, -+/* {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0644, NULL, (proc_handler *)&pm_force_suspend}, */ - {2, "helper", pm_helper_path, sizeof(pm_helper_path), 0644, NULL, (proc_handler *)&proc_dostring}, - #ifdef CONFIG_SA1100_BEAGLE - {3, "wakeup_delayed_time", &wakeup_delayed_time, sizeof(wakeup_delayed_time), 0644, NULL, &proc_dointvec }, |