diff --git a/[refs] b/[refs] index d639f35f37f9..be62291b6176 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2c75910f1aa042be1dd769378d2611bf551721ac +refs/heads/master: 5a1eb5c4453207ad9e7f6e8ca4f8db289743c993 diff --git a/trunk/Documentation/ABI/testing/sysfs-devices-cache_disable b/trunk/Documentation/ABI/testing/sysfs-devices-cache_disable new file mode 100644 index 000000000000..175bb4f70512 --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-devices-cache_disable @@ -0,0 +1,18 @@ +What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X +Date: August 2008 +KernelVersion: 2.6.27 +Contact: mark.langsdorf@amd.com +Description: These files exist in every cpu's cache index directories. + There are currently 2 cache_disable_# files in each + directory. Reading from these files on a supported + processor will return that cache disable index value + for that processor and node. Writing to one of these + files will cause the specificed cache index to be disabled. + + Currently, only AMD Family 10h Processors support cache index + disable, and only for their L3 caches. See the BIOS and + Kernel Developer's Guide at + http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf + for formatting information and other details on the + cache index disable. +Users: joachim.deguara@amd.com diff --git a/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu b/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu deleted file mode 100644 index a703b9e9aeb9..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu +++ /dev/null @@ -1,156 +0,0 @@ -What: /sys/devices/system/cpu/ -Date: pre-git history -Contact: Linux kernel mailing list -Description: - A collection of both global and individual CPU attributes - - Individual CPU attributes are contained in subdirectories - named by the kernel's logical CPU number, e.g.: - - /sys/devices/system/cpu/cpu#/ - -What: /sys/devices/system/cpu/sched_mc_power_savings - /sys/devices/system/cpu/sched_smt_power_savings -Date: June 2006 -Contact: Linux kernel mailing list -Description: Discover and adjust the kernel's multi-core scheduler support. - - Possible values are: - - 0 - No power saving load balance (default value) - 1 - Fill one thread/core/package first for long running threads - 2 - Also bias task wakeups to semi-idle cpu package for power - savings - - sched_mc_power_savings is dependent upon SCHED_MC, which is - itself architecture dependent. - - sched_smt_power_savings is dependent upon SCHED_SMT, which - is itself architecture dependent. - - The two files are independent of each other. It is possible - that one file may be present without the other. - - Introduced by git commit 5c45bf27. - - -What: /sys/devices/system/cpu/kernel_max - /sys/devices/system/cpu/offline - /sys/devices/system/cpu/online - /sys/devices/system/cpu/possible - /sys/devices/system/cpu/present -Date: December 2008 -Contact: Linux kernel mailing list -Description: CPU topology files that describe kernel limits related to - hotplug. Briefly: - - kernel_max: the maximum cpu index allowed by the kernel - configuration. - - offline: cpus that are not online because they have been - HOTPLUGGED off or exceed the limit of cpus allowed by the - kernel configuration (kernel_max above). - - online: cpus that are online and being scheduled. - - possible: cpus that have been allocated resources and can be - brought online if they are present. - - present: cpus that have been identified as being present in - the system. - - See Documentation/cputopology.txt for more information. - - - -What: /sys/devices/system/cpu/cpu#/node -Date: October 2009 -Contact: Linux memory management mailing list -Description: Discover NUMA node a CPU belongs to - - When CONFIG_NUMA is enabled, a symbolic link that points - to the corresponding NUMA node directory. - - For example, the following symlink is created for cpu42 - in NUMA node 2: - - /sys/devices/system/cpu/cpu42/node2 -> ../../node/node2 - - -What: /sys/devices/system/cpu/cpu#/topology/core_id - /sys/devices/system/cpu/cpu#/topology/core_siblings - /sys/devices/system/cpu/cpu#/topology/core_siblings_list - /sys/devices/system/cpu/cpu#/topology/physical_package_id - /sys/devices/system/cpu/cpu#/topology/thread_siblings - /sys/devices/system/cpu/cpu#/topology/thread_siblings_list -Date: December 2008 -Contact: Linux kernel mailing list -Description: CPU topology files that describe a logical CPU's relationship - to other cores and threads in the same physical package. - - One cpu# directory is created per logical CPU in the system, - e.g. /sys/devices/system/cpu/cpu42/. - - Briefly, the files above are: - - core_id: the CPU core ID of cpu#. Typically it is the - hardware platform's identifier (rather than the kernel's). - The actual value is architecture and platform dependent. - - core_siblings: internal kernel map of cpu#'s hardware threads - within the same physical_package_id. - - core_siblings_list: human-readable list of the logical CPU - numbers within the same physical_package_id as cpu#. - - physical_package_id: physical package id of cpu#. Typically - corresponds to a physical socket number, but the actual value - is architecture and platform dependent. - - thread_siblings: internel kernel map of cpu#'s hardware - threads within the same core as cpu# - - thread_siblings_list: human-readable list of cpu#'s hardware - threads within the same core as cpu# - - See Documentation/cputopology.txt for more information. - - -What: /sys/devices/system/cpu/cpuidle/current_driver - /sys/devices/system/cpu/cpuidle/current_governer_ro -Date: September 2007 -Contact: Linux kernel mailing list -Description: Discover cpuidle policy and mechanism - - Various CPUs today support multiple idle levels that are - differentiated by varying exit latencies and power - consumption during idle. - - Idle policy (governor) is differentiated from idle mechanism - (driver) - - current_driver: displays current idle mechanism - - current_governor_ro: displays current idle policy - - See files in Documentation/cpuidle/ for more information. - - -What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X -Date: August 2008 -KernelVersion: 2.6.27 -Contact: mark.langsdorf@amd.com -Description: These files exist in every cpu's cache index directories. - There are currently 2 cache_disable_# files in each - directory. Reading from these files on a supported - processor will return that cache disable index value - for that processor and node. Writing to one of these - files will cause the specificed cache index to be disabled. - - Currently, only AMD Family 10h Processors support cache index - disable, and only for their L3 caches. See the BIOS and - Kernel Developer's Guide at - http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf - for formatting information and other details on the - cache index disable. -Users: joachim.deguara@amd.com diff --git a/trunk/Documentation/cputopology.txt b/trunk/Documentation/cputopology.txt index f1c5c4bccd3e..b41f3e58aefa 100644 --- a/trunk/Documentation/cputopology.txt +++ b/trunk/Documentation/cputopology.txt @@ -1,28 +1,15 @@ -Export CPU topology info via sysfs. Items (attributes) are similar +Export cpu topology info via sysfs. Items (attributes) are similar to /proc/cpuinfo. 1) /sys/devices/system/cpu/cpuX/topology/physical_package_id: - - physical package id of cpuX. Typically corresponds to a physical - socket number, but the actual value is architecture and platform - dependent. - +represent the physical package id of cpu X; 2) /sys/devices/system/cpu/cpuX/topology/core_id: - - the CPU core ID of cpuX. Typically it is the hardware platform's - identifier (rather than the kernel's). The actual value is - architecture and platform dependent. - +represent the cpu core id to cpu X; 3) /sys/devices/system/cpu/cpuX/topology/thread_siblings: - - internel kernel map of cpuX's hardware threads within the same - core as cpuX - +represent the thread siblings to cpu X in the same core; 4) /sys/devices/system/cpu/cpuX/topology/core_siblings: - - internal kernel map of cpuX's hardware threads within the same - physical_package_id. +represent the thread siblings to cpu X in the same physical package; To implement it in an architecture-neutral way, a new source file, drivers/base/topology.c, is to export the 4 attributes. @@ -45,32 +32,32 @@ not defined by include/asm-XXX/topology.h: 3) thread_siblings: just the given CPU 4) core_siblings: just the given CPU -Additionally, CPU topology information is provided under +Additionally, cpu topology information is provided under /sys/devices/system/cpu and includes these files. The internal source for the output is in brackets ("[]"). - kernel_max: the maximum CPU index allowed by the kernel configuration. + kernel_max: the maximum cpu index allowed by the kernel configuration. [NR_CPUS-1] - offline: CPUs that are not online because they have been + offline: cpus that are not online because they have been HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit - of CPUs allowed by the kernel configuration (kernel_max + of cpus allowed by the kernel configuration (kernel_max above). [~cpu_online_mask + cpus >= NR_CPUS] - online: CPUs that are online and being scheduled [cpu_online_mask] + online: cpus that are online and being scheduled [cpu_online_mask] - possible: CPUs that have been allocated resources and can be + possible: cpus that have been allocated resources and can be brought online if they are present. [cpu_possible_mask] - present: CPUs that have been identified as being present in the + present: cpus that have been identified as being present in the system. [cpu_present_mask] The format for the above output is compatible with cpulist_parse() [see ]. Some examples follow. -In this example, there are 64 CPUs in the system but cpus 32-63 exceed +In this example, there are 64 cpus in the system but cpus 32-63 exceed the kernel max which is limited to 0..31 by the NR_CPUS config option -being 32. Note also that CPUs 2 and 4-31 are not online but could be +being 32. Note also that cpus 2 and 4-31 are not online but could be brought online as they are both present and possible. kernel_max: 31 @@ -80,8 +67,8 @@ brought online as they are both present and possible. present: 0-31 In this example, the NR_CPUS config option is 128, but the kernel was -started with possible_cpus=144. There are 4 CPUs in the system and cpu2 -was manually taken offline (and is the only CPU that can be brought +started with possible_cpus=144. There are 4 cpus in the system and cpu2 +was manually taken offline (and is the only cpu that can be brought online.) kernel_max: 127 @@ -91,4 +78,4 @@ online.) present: 0-3 See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter -as well as more information on the various cpumasks. +as well as more information on the various cpumask's. diff --git a/trunk/Documentation/filesystems/ext4.txt b/trunk/Documentation/filesystems/ext4.txt index 6d94e0696f8c..bf4f4b7e11b3 100644 --- a/trunk/Documentation/filesystems/ext4.txt +++ b/trunk/Documentation/filesystems/ext4.txt @@ -134,15 +134,9 @@ ro Mount filesystem read only. Note that ext4 will mount options "ro,noload" can be used to prevent writes to the filesystem. -journal_checksum Enable checksumming of the journal transactions. - This will allow the recovery code in e2fsck and the - kernel to detect corruption in the kernel. It is a - compatible change and will be ignored by older kernels. - journal_async_commit Commit block can be written to disk without waiting for descriptor blocks. If enabled older kernels cannot - mount the device. This will enable 'journal_checksum' - internally. + mount the device. journal=update Update the ext4 file system's journal to the current format. diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index fd9a2f67edf2..1c8eb4518ce0 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -522,7 +522,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. pcm_devs - Number of PCM devices assigned to each card (default = 1, up to 4) pcm_substreams - Number of PCM substreams assigned to each PCM - (default = 8, up to 128) + (default = 8, up to 16) hrtimer - Use hrtimer (=1, default) or system timer (=0) fake_buffer - Fake buffer allocations (default = 1) diff --git a/trunk/Documentation/trace/ftrace.txt b/trunk/Documentation/trace/ftrace.txt index 8179692fbb90..957b22fde2df 100644 --- a/trunk/Documentation/trace/ftrace.txt +++ b/trunk/Documentation/trace/ftrace.txt @@ -1231,7 +1231,6 @@ something like this simple program: #include #include #include -#include #define _STR(x) #x #define STR(x) _STR(x) @@ -1266,7 +1265,6 @@ const char *find_debugfs(void) return NULL; } - strcat(debugfs, "/tracing/"); debugfs_found = 1; return debugfs; diff --git a/trunk/Makefile b/trunk/Makefile index b4c04f734e56..9425d1de54c7 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 32 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc5 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* diff --git a/trunk/arch/arm/include/asm/cacheflush.h b/trunk/arch/arm/include/asm/cacheflush.h index 3d0cdd21b882..fd03fb63a332 100644 --- a/trunk/arch/arm/include/asm/cacheflush.h +++ b/trunk/arch/arm/include/asm/cacheflush.h @@ -414,14 +414,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page static inline void __flush_icache_all(void) { -#ifdef CONFIG_ARM_ERRATA_411920 - extern void v6_icache_inval_all(void); - v6_icache_inval_all(); -#else asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" : : "r" (0)); -#endif } #define ARCH_HAS_FLUSH_ANON_PAGE diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 2a573d4fea24..1423a3419789 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/kernel/signal.c * - * Copyright (C) 1995-2009 Russell King + * Copyright (C) 1995-2002 Russell King * * 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 @@ -29,7 +29,6 @@ */ #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) -#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) /* * With EABI, the syscall number has to be loaded into r7. @@ -49,18 +48,6 @@ const unsigned long sigreturn_codes[7] = { MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, }; -/* - * Either we support OABI only, or we have EABI with the OABI - * compat layer enabled. In the later case we don't know if - * user space is EABI or not, and if not we must not clobber r7. - * Always using the OABI syscall solves that issue and works for - * all those cases. - */ -const unsigned long syscall_restart_code[2] = { - SWI_SYS_RESTART, /* swi __NR_restart_syscall */ - 0xe49df004, /* ldr pc, [sp], #4 */ -}; - /* * atomically swap in the new signal mask, and wait for a signal. */ @@ -658,12 +645,32 @@ static void do_signal(struct pt_regs *regs, int syscall) regs->ARM_pc -= 4; #else u32 __user *usp; + u32 swival = __NR_restart_syscall; - regs->ARM_sp -= 4; + regs->ARM_sp -= 12; usp = (u32 __user *)regs->ARM_sp; - put_user(regs->ARM_pc, usp); - regs->ARM_pc = KERN_RESTART_CODE; + /* + * Either we supports OABI only, or we have + * EABI with the OABI compat layer enabled. + * In the later case we don't know if user + * space is EABI or not, and if not we must + * not clobber r7. Always using the OABI + * syscall solves that issue and works for + * all those cases. + */ + swival = swival - __NR_SYSCALL_BASE + __NR_OABI_SYSCALL_BASE; + + put_user(regs->ARM_pc, &usp[0]); + /* swi __NR_restart_syscall */ + put_user(0xef000000 | swival, &usp[1]); + /* ldr pc, [sp], #12 */ + put_user(0xe49df00c, &usp[2]); + + flush_icache_range((unsigned long)usp, + (unsigned long)(usp + 3)); + + regs->ARM_pc = regs->ARM_sp + 4; #endif } } diff --git a/trunk/arch/arm/kernel/signal.h b/trunk/arch/arm/kernel/signal.h index 6fcfe8398aa4..27beece15502 100644 --- a/trunk/arch/arm/kernel/signal.h +++ b/trunk/arch/arm/kernel/signal.h @@ -1,14 +1,12 @@ /* * linux/arch/arm/kernel/signal.h * - * Copyright (C) 2005-2009 Russell King. + * Copyright (C) 2005 Russell King. * * 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. */ #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) -#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) extern const unsigned long sigreturn_codes[7]; -extern const unsigned long syscall_restart_code[2]; diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 95718a6b50a6..f838f36eb702 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/kernel/traps.c * - * Copyright (C) 1995-2009 Russell King + * Copyright (C) 1995-2002 Russell King * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds * * This program is free software; you can redistribute it and/or modify @@ -751,8 +751,6 @@ void __init early_trap_init(void) */ memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, sizeof(sigreturn_codes)); - memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, - sizeof(syscall_restart_code)); flush_icache_range(vectors, vectors + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); diff --git a/trunk/arch/arm/kernel/unwind.c b/trunk/arch/arm/kernel/unwind.c index 786ac2b6914a..39baf1128bfa 100644 --- a/trunk/arch/arm/kernel/unwind.c +++ b/trunk/arch/arm/kernel/unwind.c @@ -26,15 +26,6 @@ * http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html */ -#if !defined (__ARM_EABI__) -#warning Your compiler does not have EABI support. -#warning ARM unwind is known to compile only with EABI compilers. -#warning Change compiler or disable ARM_UNWIND option. -#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) -#warning Your compiler is too buggy; it is known to not compile ARM unwind support. -#warning Change compiler or disable ARM_UNWIND option. -#endif - #include #include #include diff --git a/trunk/arch/arm/mach-at91/include/mach/cpu.h b/trunk/arch/arm/mach-at91/include/mach/cpu.h index c22df30ed5e5..34a9502c48bc 100644 --- a/trunk/arch/arm/mach-at91/include/mach/cpu.h +++ b/trunk/arch/arm/mach-at91/include/mach/cpu.h @@ -25,8 +25,6 @@ #define ARCH_ID_AT91SAM9G20 0x019905a0 #define ARCH_ID_AT91SAM9RL64 0x019b03a0 #define ARCH_ID_AT91SAM9G45 0x819b05a0 -#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ -#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ #define ARCH_ID_AT91CAP9 0x039A03A0 #define ARCH_ID_AT91SAM9XE128 0x329973a0 @@ -43,11 +41,6 @@ static inline unsigned long at91_cpu_identify(void) return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); } -static inline unsigned long at91_cpu_fully_identify(void) -{ - return at91_sys_read(AT91_DBGU_CIDR); -} - #define ARCH_EXID_AT91SAM9M11 0x00000001 #define ARCH_EXID_AT91SAM9M10 0x00000002 #define ARCH_EXID_AT91SAM9G45 0x00000004 @@ -125,10 +118,8 @@ static inline unsigned long at91cap9_rev_identify(void) #ifdef CONFIG_ARCH_AT91SAM9G45 #define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45) -#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES) #else #define cpu_is_at91sam9g45() (0) -#define cpu_is_at91sam9g45es() (0) #endif #ifdef CONFIG_ARCH_AT91CAP9 diff --git a/trunk/arch/arm/mach-integrator/include/mach/memory.h b/trunk/arch/arm/mach-integrator/include/mach/memory.h index 4891828454f5..2b2e7a110724 100644 --- a/trunk/arch/arm/mach-integrator/include/mach/memory.h +++ b/trunk/arch/arm/mach-integrator/include/mach/memory.h @@ -28,6 +28,5 @@ #define BUS_OFFSET UL(0x80000000) #define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET) #define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET) -#define __pfn_to_bus(x) (((x) << PAGE_SHIFT) + BUS_OFFSET) #endif diff --git a/trunk/arch/arm/mach-realview/core.h b/trunk/arch/arm/mach-realview/core.h index 699671fa6e0b..46cd6acb4d40 100644 --- a/trunk/arch/arm/mach-realview/core.h +++ b/trunk/arch/arm/mach-realview/core.h @@ -61,5 +61,5 @@ extern void realview_timer_init(unsigned int timer_irq); extern int realview_flash_register(struct resource *res, u32 num); extern int realview_eth_register(const char *name, struct resource *res); extern int realview_usb_register(struct resource *res); -extern void (*realview_reset)(char); + #endif diff --git a/trunk/arch/arm/mach-realview/include/mach/board-pb1176.h b/trunk/arch/arm/mach-realview/include/mach/board-pb1176.h index 34b80b7d40b8..98f8e7eeacc2 100644 --- a/trunk/arch/arm/mach-realview/include/mach/board-pb1176.h +++ b/trunk/arch/arm/mach-realview/include/mach/board-pb1176.h @@ -73,9 +73,4 @@ #define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */ #define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */ -/* - * Control register SYS_RESETCTL is set to 1 to force a soft reset - */ -#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL 0x0100 - #endif /* __ASM_ARCH_BOARD_PB1176_H */ diff --git a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h index 7abf918b77e9..f0d68e0fea01 100644 --- a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h +++ b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h @@ -81,16 +81,4 @@ #define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */ #define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */ - /* - * Values for REALVIEW_SYS_RESET_CTRL - */ -#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR 0x01 -#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT 0x02 -#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET 0x03 -#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET 0x04 -#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR 0x05 -#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC 0x06 - -#define REALVIEW_PB11MP_SYS_CTRL_LED (1 << 0) - #endif /* __ASM_ARCH_BOARD_PB11MP_H */ diff --git a/trunk/arch/arm/mach-realview/include/mach/platform.h b/trunk/arch/arm/mach-realview/include/mach/platform.h index 4f46bf71e752..c8f50835fed2 100644 --- a/trunk/arch/arm/mach-realview/include/mach/platform.h +++ b/trunk/arch/arm/mach-realview/include/mach/platform.h @@ -119,6 +119,19 @@ #define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) #define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) +/* + * Values for REALVIEW_SYS_RESET_CTRL + */ +#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01 +#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02 +#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03 +#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04 +#define REALVIEW_SYS_CTRL_RESET_POR 0x05 +#define REALVIEW_SYS_CTRL_RESET_DoC 0x06 + +#define REALVIEW_SYS_CTRL_LED (1 << 0) + + /* ------------------------------------------------------------------------ * RealView control registers * ------------------------------------------------------------------------ @@ -140,7 +153,7 @@ * SYS_CLD, SYS_BOOTCS */ #define REALVIEW_SYS_LOCK_LOCKED (1 << 16) -#define REALVIEW_SYS_LOCKVAL_MASK 0xA05F /* Enable write access */ +#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ /* * REALVIEW_SYS_FLASH diff --git a/trunk/arch/arm/mach-realview/include/mach/system.h b/trunk/arch/arm/mach-realview/include/mach/system.h index a30f2e3ec178..1a15a441e027 100644 --- a/trunk/arch/arm/mach-realview/include/mach/system.h +++ b/trunk/arch/arm/mach-realview/include/mach/system.h @@ -25,8 +25,6 @@ #include #include -void (*realview_reset)(char mode); - static inline void arch_idle(void) { /* @@ -38,12 +36,16 @@ static inline void arch_idle(void) static inline void arch_reset(char mode, const char *cmd) { + void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET; + unsigned int val; + /* * To reset, we hit the on-board reset register * in the system FPGA */ - if (realview_reset) - realview_reset(mode); + val = __raw_readl(hdr_ctrl); + val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR; + __raw_writel(val, hdr_ctrl); } #endif diff --git a/trunk/arch/arm/mach-realview/realview_pb1176.c b/trunk/arch/arm/mach-realview/realview_pb1176.c index a6ba147692c1..2817fe099319 100644 --- a/trunk/arch/arm/mach-realview/realview_pb1176.c +++ b/trunk/arch/arm/mach-realview/realview_pb1176.c @@ -290,16 +290,6 @@ static struct sys_timer realview_pb1176_timer = { .init = realview_pb1176_timer_init, }; -static void realview_pb1176_reset(char mode) -{ - void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_RESETCTL_OFFSET; - void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_LOCK_OFFSET; - __raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl); - __raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl); -} - static void __init realview_pb1176_init(void) { int i; @@ -323,7 +313,6 @@ static void __init realview_pb1176_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif - realview_reset = realview_pb1176_reset; } MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") diff --git a/trunk/arch/arm/mach-realview/realview_pb11mp.c b/trunk/arch/arm/mach-realview/realview_pb11mp.c index 070d284ce96e..94680fcf726d 100644 --- a/trunk/arch/arm/mach-realview/realview_pb11mp.c +++ b/trunk/arch/arm/mach-realview/realview_pb11mp.c @@ -299,21 +299,6 @@ static struct sys_timer realview_pb11mp_timer = { .init = realview_pb11mp_timer_init, }; -static void realview_pb11mp_reset(char mode) -{ - void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_RESETCTL_OFFSET; - unsigned int val; - - /* - * To reset, we hit the on-board reset register - * in the system FPGA - */ - val = __raw_readl(hdr_ctrl); - val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR; - __raw_writel(val, hdr_ctrl); -} - static void __init realview_pb11mp_init(void) { int i; @@ -339,7 +324,6 @@ static void __init realview_pb11mp_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif - realview_reset = realview_pb11mp_reset; } MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") diff --git a/trunk/arch/arm/mach-s3c2410/gpio.c b/trunk/arch/arm/mach-s3c2410/gpio.c index 9664e011dae2..7974afca297c 100644 --- a/trunk/arch/arm/mach-s3c2410/gpio.c +++ b/trunk/arch/arm/mach-s3c2410/gpio.c @@ -28,7 +28,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-s3c2410/include/mach/dma.h b/trunk/arch/arm/mach-s3c2410/include/mach/dma.h index 92e2687009ea..c3a2629e0ded 100644 --- a/trunk/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/trunk/arch/arm/mach-s3c2410/include/mach/dma.h @@ -110,8 +110,6 @@ enum s3c2410_dma_loadst { * waiting for reloads */ #define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */ -#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */ - /* dma buffer */ struct s3c2410_dma_buf; @@ -196,9 +194,4 @@ struct s3c2410_dma_chan { typedef unsigned long dma_device_t; -static inline bool s3c_dma_has_circular(void) -{ - return false; -} - #endif /* __ASM_ARCH_DMA_H */ diff --git a/trunk/arch/arm/mach-s3c2440/Kconfig b/trunk/arch/arm/mach-s3c2440/Kconfig index a8b69d77571b..d7bba919a77e 100644 --- a/trunk/arch/arm/mach-s3c2440/Kconfig +++ b/trunk/arch/arm/mach-s3c2440/Kconfig @@ -103,7 +103,6 @@ config MACH_MINI2440 select LEDS_TRIGGER_BACKLIGHT select SND_S3C24XX_SOC_S3C24XX_UDA134X select S3C_DEV_NAND - select S3C_DEV_USB_HOST help Say Y here to select support for the MINI2440. Is a 10cm x 10cm board available via various sources. It can come with a 3.5" or 7" touch LCD. diff --git a/trunk/arch/arm/mach-s3c2440/mach-mini2440.c b/trunk/arch/arm/mach-s3c2440/mach-mini2440.c index 1c3382fefdd2..ec71a6965786 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/trunk/arch/arm/mach-s3c2440/mach-mini2440.c @@ -144,7 +144,7 @@ static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = { .type = (S3C2410_LCDCON1_TFT16BPP |\ S3C2410_LCDCON1_TFT) -static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { +struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { [0] = { /* mini2440 + 3.5" TFT + touchscreen */ _LCD_DECLARE( 7, /* The 3.5 is quite fast */ @@ -191,7 +191,7 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { #define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2)) #define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2)) -static struct s3c2410fb_mach_info mini2440_fb_info __initdata = { +struct s3c2410fb_mach_info mini2440_fb_info __initdata = { .displays = &mini2440_lcd_cfg[0], /* not constant! see init */ .num_displays = 1, .default_display = 0, diff --git a/trunk/arch/arm/mach-s3c6400/include/mach/dma.h b/trunk/arch/arm/mach-s3c6400/include/mach/dma.h index 004edab23954..1067619f0ba0 100644 --- a/trunk/arch/arm/mach-s3c6400/include/mach/dma.h +++ b/trunk/arch/arm/mach-s3c6400/include/mach/dma.h @@ -68,11 +68,6 @@ static __inline__ int s3c_dma_has_circular(void) #define S3C2410_DMAF_CIRCULAR (1 << 0) -static inline bool s3c_dma_has_circular(void) -{ - return false; -} - #include #endif /* __ASM_ARCH_IRQ_H */ diff --git a/trunk/arch/arm/mm/context.c b/trunk/arch/arm/mm/context.c index a9e22e31eaa1..6bda76a43199 100644 --- a/trunk/arch/arm/mm/context.c +++ b/trunk/arch/arm/mm/context.c @@ -50,7 +50,10 @@ void __new_context(struct mm_struct *mm) isb(); flush_tlb_all(); if (icache_is_vivt_asid_tagged()) { - __flush_icache_all(); + asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" + "mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n" + : + : "r" (0)); dsb(); } } diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index b9590a7085ca..b30925fcbcdc 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -205,7 +205,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, order = get_order(size); - if (mask < 0xffffffffULL) + if (mask != 0xffffffff) gfp |= GFP_DMA; page = alloc_pages(gfp, order); @@ -289,7 +289,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, if (!mask) goto error; - if (mask < 0xffffffffULL) + if (mask != 0xffffffff) gfp |= GFP_DMA; virt = kmalloc(size, gfp); if (!virt) diff --git a/trunk/arch/arm/mm/flush.c b/trunk/arch/arm/mm/flush.c index 7f294f307c83..b27942909b23 100644 --- a/trunk/arch/arm/mm/flush.c +++ b/trunk/arch/arm/mm/flush.c @@ -18,6 +18,10 @@ #include "mm.h" +#ifdef CONFIG_ARM_ERRATA_411920 +extern void v6_icache_inval_all(void); +#endif + #ifdef CONFIG_CPU_CACHE_VIPT #define ALIAS_FLUSH_START 0xffff4000 @@ -31,11 +35,16 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) flush_tlb_kernel_page(to); asm( "mcrr p15, 0, %1, %0, c14\n" - " mcr p15, 0, %2, c7, c10, 4" + " mcr p15, 0, %2, c7, c10, 4\n" +#ifndef CONFIG_ARM_ERRATA_411920 + " mcr p15, 0, %2, c7, c5, 0\n" +#endif : : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) : "cc"); - __flush_icache_all(); +#ifdef CONFIG_ARM_ERRATA_411920 + v6_icache_inval_all(); +#endif } void flush_cache_mm(struct mm_struct *mm) @@ -48,11 +57,16 @@ void flush_cache_mm(struct mm_struct *mm) if (cache_is_vipt_aliasing()) { asm( "mcr p15, 0, %0, c7, c14, 0\n" - " mcr p15, 0, %0, c7, c10, 4" + " mcr p15, 0, %0, c7, c10, 4\n" +#ifndef CONFIG_ARM_ERRATA_411920 + " mcr p15, 0, %0, c7, c5, 0\n" +#endif : : "r" (0) : "cc"); - __flush_icache_all(); +#ifdef CONFIG_ARM_ERRATA_411920 + v6_icache_inval_all(); +#endif } } @@ -67,11 +81,16 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned if (cache_is_vipt_aliasing()) { asm( "mcr p15, 0, %0, c7, c14, 0\n" - " mcr p15, 0, %0, c7, c10, 4" + " mcr p15, 0, %0, c7, c10, 4\n" +#ifndef CONFIG_ARM_ERRATA_411920 + " mcr p15, 0, %0, c7, c5, 0\n" +#endif : : "r" (0) : "cc"); - __flush_icache_all(); +#ifdef CONFIG_ARM_ERRATA_411920 + v6_icache_inval_all(); +#endif } } diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 52c40d155672..40940d7ce4ff 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -273,6 +273,7 @@ static void __init bootmem_init_node(int node, struct meminfo *mi, struct membank *bank = &mi->bank[i]; if (!bank->highmem) free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); + memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank)); } /* @@ -369,19 +370,6 @@ int pfn_valid(unsigned long pfn) return 0; } EXPORT_SYMBOL(pfn_valid); - -static void arm_memory_present(struct meminfo *mi, int node) -{ -} -#else -static void arm_memory_present(struct meminfo *mi, int node) -{ - int i; - for_each_nodebank(i, mi, node) { - struct membank *bank = &mi->bank[i]; - memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank)); - } -} #endif static int __init meminfo_cmp(const void *_a, const void *_b) @@ -439,12 +427,6 @@ void __init bootmem_init(void) */ if (node == initrd_node) bootmem_reserve_initrd(node); - - /* - * Sparsemem tries to allocate bootmem in memory_present(), - * so must be done after the fixed reservations - */ - arm_memory_present(mi, node); } /* diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index ea67be0223ac..02243eeccf50 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -117,13 +117,6 @@ static void __init early_cachepolicy(char **p) } if (i == ARRAY_SIZE(cache_policies)) printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); - /* - * This restriction is partly to do with the way we boot; it is - * unpredictable to have memory mapped using two different sets of - * memory attributes (shared, type, and cache attribs). We can not - * change these attributes once the initial assembly has setup the - * page tables. - */ if (cpu_architecture() >= CPU_ARCH_ARMv6) { printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n"); cachepolicy = CPOLICY_WRITEBACK; diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 70f75d2e3ead..194737d60a22 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -32,10 +32,8 @@ #ifndef CONFIG_SMP #define TTB_FLAGS TTB_RGN_WBWA -#define PMD_FLAGS PMD_SECT_WB #else #define TTB_FLAGS TTB_RGN_WBWA|TTB_S -#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S #endif ENTRY(cpu_v6_proc_init) @@ -224,9 +222,10 @@ __v6_proc_info: .long 0x0007b000 .long 0x0007f000 .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS + PMD_SECT_AP_READ .long PMD_TYPE_SECT | \ PMD_SECT_XN | \ PMD_SECT_AP_WRITE | \ diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index eeeed01ee44a..23ebcf6eab9f 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -33,11 +33,9 @@ #ifndef CONFIG_SMP /* PTWs cacheable, inner WB not shareable, outer WB not shareable */ #define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB -#define PMD_FLAGS PMD_SECT_WB #else /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ #define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA -#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S #endif ENTRY(cpu_v7_proc_init) @@ -328,9 +326,10 @@ __v7_proc_info: .long 0x000f0000 @ Required ID value .long 0x000f0000 @ Mask for ID .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS + PMD_SECT_AP_READ .long PMD_TYPE_SECT | \ PMD_SECT_XN | \ PMD_SECT_AP_WRITE | \ diff --git a/trunk/arch/arm/plat-s3c24xx/adc.c b/trunk/arch/arm/plat-s3c24xx/adc.c index df47322492d5..4d36b784fb8b 100644 --- a/trunk/arch/arm/plat-s3c24xx/adc.c +++ b/trunk/arch/arm/plat-s3c24xx/adc.c @@ -189,7 +189,7 @@ int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch) err: return ret; } -EXPORT_SYMBOL_GPL(s3c_adc_read); +EXPORT_SYMBOL_GPL(s3c_adc_convert); static void s3c_adc_default_select(struct s3c_adc_client *client, unsigned select) diff --git a/trunk/arch/arm/plat-s3c24xx/cpu.c b/trunk/arch/arm/plat-s3c24xx/cpu.c index 4af9dd948793..5447e60f3936 100644 --- a/trunk/arch/arm/plat-s3c24xx/cpu.c +++ b/trunk/arch/arm/plat-s3c24xx/cpu.c @@ -61,7 +61,6 @@ static const char name_s3c2410[] = "S3C2410"; static const char name_s3c2412[] = "S3C2412"; static const char name_s3c2440[] = "S3C2440"; static const char name_s3c2442[] = "S3C2442"; -static const char name_s3c2442b[] = "S3C2442B"; static const char name_s3c2443[] = "S3C2443"; static const char name_s3c2410a[] = "S3C2410A"; static const char name_s3c2440a[] = "S3C2440A"; @@ -112,15 +111,6 @@ static struct cpu_table cpu_ids[] __initdata = { .init = s3c2442_init, .name = name_s3c2442 }, - { - .idcode = 0x32440aab, - .idmask = 0xffffffff, - .map_io = s3c244x_map_io, - .init_clocks = s3c244x_init_clocks, - .init_uarts = s3c244x_init_uarts, - .init = s3c2442_init, - .name = name_s3c2442b - }, { .idcode = 0x32412001, .idmask = 0xffffffff, diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c index f046f8c51084..196b19123653 100644 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ b/trunk/arch/arm/plat-s3c24xx/dma.c @@ -208,14 +208,14 @@ s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan, { unsigned long reload; + pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n", + buf, (unsigned long)buf->data, buf->size); + if (buf == NULL) { dmawarn("buffer is NULL\n"); return -EINVAL; } - pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n", - buf, (unsigned long)buf->data, buf->size); - /* check the state of the channel before we do anything */ if (chan->load_state == S3C2410_DMALOAD_1LOADED) { diff --git a/trunk/arch/arm/plat-s3c24xx/gpio.c b/trunk/arch/arm/plat-s3c24xx/gpio.c index 5467470badfd..95df059b5a1d 100644 --- a/trunk/arch/arm/plat-s3c24xx/gpio.c +++ b/trunk/arch/arm/plat-s3c24xx/gpio.c @@ -29,7 +29,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/trunk/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h index c776120b99e6..efeb025affc7 100644 --- a/trunk/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h +++ b/trunk/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h @@ -222,9 +222,7 @@ extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *); /* S3C2410 and compatible exported functions */ extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg); -extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg); -#ifdef CONFIG_S3C2410_IOTIMING extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, struct s3c_iotimings *iot); @@ -233,11 +231,8 @@ extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, struct s3c_iotimings *iot); -#else -#define s3c2410_iotiming_calc NULL -#define s3c2410_iotiming_get NULL -#define s3c2410_iotiming_set NULL -#endif /* CONFIG_S3C2410_IOTIMING */ + +extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg); /* S3C2412 compatible routines */ diff --git a/trunk/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/trunk/arch/arm/plat-s3c24xx/include/plat/s3c2410.h index 82ab4aad1bbe..b6deeef8f663 100644 --- a/trunk/arch/arm/plat-s3c24xx/include/plat/s3c2410.h +++ b/trunk/arch/arm/plat-s3c24xx/include/plat/s3c2410.h @@ -27,7 +27,6 @@ extern void s3c2410_init_clocks(int xtal); #define s3c2410_init_uarts NULL #define s3c2410_map_io NULL #define s3c2410_init NULL -#define s3c2410a_init NULL #endif extern int s3c2410_baseclk_add(void); diff --git a/trunk/arch/arm/plat-s3c64xx/include/plat/regs-clock.h b/trunk/arch/arm/plat-s3c64xx/include/plat/regs-clock.h index ff46e7fa957a..a8777a755dfa 100644 --- a/trunk/arch/arm/plat-s3c64xx/include/plat/regs-clock.h +++ b/trunk/arch/arm/plat-s3c64xx/include/plat/regs-clock.h @@ -51,8 +51,8 @@ #define S3C6400_CLKDIV0_HCLK_SHIFT (8) #define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4) #define S3C6400_CLKDIV0_MPLL_SHIFT (4) -#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0) -#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0) +#define S3C6400_CLKDIV0_ARM_MASK (0x3 << 0) +#define S3C6410_CLKDIV0_ARM_MASK (0x7 << 0) #define S3C6400_CLKDIV0_ARM_SHIFT (0) /* CLKDIV1 */ diff --git a/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c b/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c index 6ffa21eb1b91..9745852261e0 100644 --- a/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c +++ b/trunk/arch/arm/plat-s3c64xx/s3c6400-clock.c @@ -677,9 +677,6 @@ void __init_or_cpufreq s3c6400_setup_clocks(void) printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - /* For now assume the mux always selects the crystal */ - clk_ext_xtal_mux.parent = xtal_clk; - epll = s3c6400_get_epll(xtal); mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); diff --git a/trunk/arch/avr32/mach-at32ap/include/mach/cpu.h b/trunk/arch/avr32/mach-at32ap/include/mach/cpu.h index 9c96a130f3a8..44d0bfa1f409 100644 --- a/trunk/arch/avr32/mach-at32ap/include/mach/cpu.h +++ b/trunk/arch/avr32/mach-at32ap/include/mach/cpu.h @@ -31,8 +31,5 @@ #define cpu_is_at91sam9263() (0) #define cpu_is_at91sam9rl() (0) #define cpu_is_at91cap9() (0) -#define cpu_is_at91sam9g10() (0) -#define cpu_is_at91sam9g45() (0) -#define cpu_is_at91sam9g45es() (0) #endif /* __ASM_ARCH_CPU_H */ diff --git a/trunk/arch/ia64/include/asm/spinlock.h b/trunk/arch/ia64/include/asm/spinlock.h index 239ecdc9516d..30bb930e1111 100644 --- a/trunk/arch/ia64/include/asm/spinlock.h +++ b/trunk/arch/ia64/include/asm/spinlock.h @@ -25,82 +25,61 @@ * by atomically noting the tail and incrementing it by one (thus adding * ourself to the queue and noting our position), then waiting until the head * becomes equal to the the initial value of the tail. - * The pad bits in the middle are used to prevent the next_ticket number - * overflowing into the now_serving number. * - * 31 17 16 15 14 0 + * 63 32 31 0 * +----------------------------------------------------+ - * | now_serving | padding | next_ticket | + * | next_ticket_number | now_serving | * +----------------------------------------------------+ */ -#define TICKET_SHIFT 17 -#define TICKET_BITS 15 -#define TICKET_MASK ((1 << TICKET_BITS) - 1) +#define TICKET_SHIFT 32 static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) { - int *p = (int *)&lock->lock, ticket, serve; + int *p = (int *)&lock->lock, turn, now_serving; - ticket = ia64_fetchadd(1, p, acq); + now_serving = *p; + turn = ia64_fetchadd(1, p+1, acq); - if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK)) + if (turn == now_serving) return; - ia64_invala(); - - for (;;) { - asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(p) : "memory"); - - if (!(((serve >> TICKET_SHIFT) ^ ticket) & TICKET_MASK)) - return; + do { cpu_relax(); - } + } while (ACCESS_ONCE(*p) != turn); } static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) { - int tmp = ACCESS_ONCE(lock->lock); + long tmp = ACCESS_ONCE(lock->lock), try; + + if (!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1L << TICKET_SHIFT) - 1))) { + try = tmp + (1L << TICKET_SHIFT); - if (!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK)) - return ia64_cmpxchg(acq, &lock->lock, tmp, tmp + 1, sizeof (tmp)) == tmp; + return ia64_cmpxchg(acq, &lock->lock, tmp, try, sizeof (tmp)) == tmp; + } return 0; } static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) { - unsigned short *p = (unsigned short *)&lock->lock + 1, tmp; + int *p = (int *)&lock->lock; - asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p)); - ACCESS_ONCE(*p) = (tmp + 2) & ~1; -} - -static __always_inline void __ticket_spin_unlock_wait(raw_spinlock_t *lock) -{ - int *p = (int *)&lock->lock, ticket; - - ia64_invala(); - - for (;;) { - asm volatile ("ld4.c.nc %0=[%1]" : "=r"(ticket) : "r"(p) : "memory"); - if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK)) - return; - cpu_relax(); - } + (void)ia64_fetchadd(1, p, rel); } static inline int __ticket_spin_is_locked(raw_spinlock_t *lock) { long tmp = ACCESS_ONCE(lock->lock); - return !!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK); + return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1L << TICKET_SHIFT) - 1)); } static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) { long tmp = ACCESS_ONCE(lock->lock); - return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1; + return (((tmp >> TICKET_SHIFT) - tmp) & ((1L << TICKET_SHIFT) - 1)) > 1; } static inline int __raw_spin_is_locked(raw_spinlock_t *lock) @@ -137,7 +116,8 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) { - __ticket_spin_unlock_wait(lock); + while (__raw_spin_is_locked(lock)) + cpu_relax(); } #define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0) diff --git a/trunk/arch/ia64/include/asm/spinlock_types.h b/trunk/arch/ia64/include/asm/spinlock_types.h index 474e46f1ab4a..b61d136d9bc2 100644 --- a/trunk/arch/ia64/include/asm/spinlock_types.h +++ b/trunk/arch/ia64/include/asm/spinlock_types.h @@ -6,7 +6,7 @@ #endif typedef struct { - volatile unsigned int lock; + volatile unsigned long lock; } raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 496ac7a99488..d2877a7bfe2e 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -887,60 +887,6 @@ ia64_mca_modify_comm(const struct task_struct *previous_current) memcpy(current->comm, comm, sizeof(current->comm)); } -static void -finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, - unsigned long *nat) -{ - const u64 *bank; - - /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use - * pmsa_{xip,xpsr,xfs} - */ - if (ia64_psr(regs)->ic) { - regs->cr_iip = ms->pmsa_iip; - regs->cr_ipsr = ms->pmsa_ipsr; - regs->cr_ifs = ms->pmsa_ifs; - } else { - regs->cr_iip = ms->pmsa_xip; - regs->cr_ipsr = ms->pmsa_xpsr; - regs->cr_ifs = ms->pmsa_xfs; - } - regs->pr = ms->pmsa_pr; - regs->b0 = ms->pmsa_br0; - regs->ar_rsc = ms->pmsa_rsc; - copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, ®s->r1, nat); - copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, ®s->r2, nat); - copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, ®s->r3, nat); - copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, ®s->r8, nat); - copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, ®s->r9, nat); - copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, ®s->r10, nat); - copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, ®s->r11, nat); - copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, ®s->r12, nat); - copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, ®s->r13, nat); - copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, ®s->r14, nat); - copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, ®s->r15, nat); - if (ia64_psr(regs)->bn) - bank = ms->pmsa_bank1_gr; - else - bank = ms->pmsa_bank0_gr; - copy_reg(&bank[16-16], ms->pmsa_nat_bits, ®s->r16, nat); - copy_reg(&bank[17-16], ms->pmsa_nat_bits, ®s->r17, nat); - copy_reg(&bank[18-16], ms->pmsa_nat_bits, ®s->r18, nat); - copy_reg(&bank[19-16], ms->pmsa_nat_bits, ®s->r19, nat); - copy_reg(&bank[20-16], ms->pmsa_nat_bits, ®s->r20, nat); - copy_reg(&bank[21-16], ms->pmsa_nat_bits, ®s->r21, nat); - copy_reg(&bank[22-16], ms->pmsa_nat_bits, ®s->r22, nat); - copy_reg(&bank[23-16], ms->pmsa_nat_bits, ®s->r23, nat); - copy_reg(&bank[24-16], ms->pmsa_nat_bits, ®s->r24, nat); - copy_reg(&bank[25-16], ms->pmsa_nat_bits, ®s->r25, nat); - copy_reg(&bank[26-16], ms->pmsa_nat_bits, ®s->r26, nat); - copy_reg(&bank[27-16], ms->pmsa_nat_bits, ®s->r27, nat); - copy_reg(&bank[28-16], ms->pmsa_nat_bits, ®s->r28, nat); - copy_reg(&bank[29-16], ms->pmsa_nat_bits, ®s->r29, nat); - copy_reg(&bank[30-16], ms->pmsa_nat_bits, ®s->r30, nat); - copy_reg(&bank[31-16], ms->pmsa_nat_bits, ®s->r31, nat); -} - /* On entry to this routine, we are running on the per cpu stack, see * mca_asm.h. The original stack has not been touched by this event. Some of * the original stack's registers will be in the RBS on this stack. This stack @@ -975,6 +921,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1]; u64 ar_bspstore = regs->ar_bspstore; u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16); + const u64 *bank; const char *msg; int cpu = smp_processor_id(); @@ -1077,9 +1024,54 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, p = (char *)r12 - sizeof(*regs); old_regs = (struct pt_regs *)p; memcpy(old_regs, regs, sizeof(*regs)); + /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use + * pmsa_{xip,xpsr,xfs} + */ + if (ia64_psr(regs)->ic) { + old_regs->cr_iip = ms->pmsa_iip; + old_regs->cr_ipsr = ms->pmsa_ipsr; + old_regs->cr_ifs = ms->pmsa_ifs; + } else { + old_regs->cr_iip = ms->pmsa_xip; + old_regs->cr_ipsr = ms->pmsa_xpsr; + old_regs->cr_ifs = ms->pmsa_xfs; + } + old_regs->pr = ms->pmsa_pr; + old_regs->b0 = ms->pmsa_br0; old_regs->loadrs = loadrs; + old_regs->ar_rsc = ms->pmsa_rsc; old_unat = old_regs->ar_unat; - finish_pt_regs(old_regs, ms, &old_unat); + copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &old_regs->r1, &old_unat); + copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &old_regs->r2, &old_unat); + copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &old_regs->r3, &old_unat); + copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &old_regs->r8, &old_unat); + copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &old_regs->r9, &old_unat); + copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &old_regs->r10, &old_unat); + copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &old_regs->r11, &old_unat); + copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &old_regs->r12, &old_unat); + copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &old_regs->r13, &old_unat); + copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &old_regs->r14, &old_unat); + copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &old_regs->r15, &old_unat); + if (ia64_psr(old_regs)->bn) + bank = ms->pmsa_bank1_gr; + else + bank = ms->pmsa_bank0_gr; + copy_reg(&bank[16-16], ms->pmsa_nat_bits, &old_regs->r16, &old_unat); + copy_reg(&bank[17-16], ms->pmsa_nat_bits, &old_regs->r17, &old_unat); + copy_reg(&bank[18-16], ms->pmsa_nat_bits, &old_regs->r18, &old_unat); + copy_reg(&bank[19-16], ms->pmsa_nat_bits, &old_regs->r19, &old_unat); + copy_reg(&bank[20-16], ms->pmsa_nat_bits, &old_regs->r20, &old_unat); + copy_reg(&bank[21-16], ms->pmsa_nat_bits, &old_regs->r21, &old_unat); + copy_reg(&bank[22-16], ms->pmsa_nat_bits, &old_regs->r22, &old_unat); + copy_reg(&bank[23-16], ms->pmsa_nat_bits, &old_regs->r23, &old_unat); + copy_reg(&bank[24-16], ms->pmsa_nat_bits, &old_regs->r24, &old_unat); + copy_reg(&bank[25-16], ms->pmsa_nat_bits, &old_regs->r25, &old_unat); + copy_reg(&bank[26-16], ms->pmsa_nat_bits, &old_regs->r26, &old_unat); + copy_reg(&bank[27-16], ms->pmsa_nat_bits, &old_regs->r27, &old_unat); + copy_reg(&bank[28-16], ms->pmsa_nat_bits, &old_regs->r28, &old_unat); + copy_reg(&bank[29-16], ms->pmsa_nat_bits, &old_regs->r29, &old_unat); + copy_reg(&bank[30-16], ms->pmsa_nat_bits, &old_regs->r30, &old_unat); + copy_reg(&bank[31-16], ms->pmsa_nat_bits, &old_regs->r31, &old_unat); /* Next stack a struct switch_stack. mca_asm.S built a partial * switch_stack, copy it and fill in the blanks using pt_regs and @@ -1149,8 +1141,6 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, no_mod: mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", smp_processor_id(), type, msg); - old_unat = regs->ar_unat; - finish_pt_regs(regs, ms, &old_unat); return previous_current; } diff --git a/trunk/arch/ia64/kernel/unaligned.c b/trunk/arch/ia64/kernel/unaligned.c index 776dd40397e2..6db08599ebbc 100644 --- a/trunk/arch/ia64/kernel/unaligned.c +++ b/trunk/arch/ia64/kernel/unaligned.c @@ -60,6 +60,7 @@ dump (const char *str, void *vp, size_t len) */ int no_unaligned_warning; int unaligned_dump_stack; +static int noprint_warning; /* * For M-unit: @@ -1356,8 +1357,9 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) /* watch for command names containing %s */ printk(KERN_WARNING "%s", buf); } else { - if (no_unaligned_warning) { - printk_once(KERN_WARNING "%s(%d) encountered an " + if (no_unaligned_warning && !noprint_warning) { + noprint_warning = 1; + printk(KERN_WARNING "%s(%d) encountered an " "unaligned exception which required\n" "kernel assistance, which degrades " "the performance of the application.\n" diff --git a/trunk/arch/ia64/mm/tlb.c b/trunk/arch/ia64/mm/tlb.c index ee09d261f2e6..f426dc78d959 100644 --- a/trunk/arch/ia64/mm/tlb.c +++ b/trunk/arch/ia64/mm/tlb.c @@ -100,36 +100,24 @@ wrap_mmu_context (struct mm_struct *mm) * this primitive it can be moved up to a spinaphore.h header. */ struct spinaphore { - unsigned long ticket; - unsigned long serve; + atomic_t cur; }; static inline void spinaphore_init(struct spinaphore *ss, int val) { - ss->ticket = 0; - ss->serve = val; + atomic_set(&ss->cur, val); } static inline void down_spin(struct spinaphore *ss) { - unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve; - - if (time_before(t, ss->serve)) - return; - - ia64_invala(); - - for (;;) { - asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); - if (time_before(t, serve)) - return; - cpu_relax(); - } + while (unlikely(!atomic_add_unless(&ss->cur, -1, 0))) + while (atomic_read(&ss->cur) == 0) + cpu_relax(); } static inline void up_spin(struct spinaphore *ss) { - ia64_fetchadd(1, &ss->serve, rel); + atomic_add(1, &ss->cur); } static struct spinaphore ptcg_sem; diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index c0fca2c1c858..7de76dd352fe 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -56,13 +56,10 @@ int raw_pci_read(unsigned int seg, unsigned int bus, unsigned int devfn, if ((seg | reg) <= 255) { addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg); mode = 0; - } else if (sal_revision >= SAL_VERSION_CODE(3,2)) { + } else { addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg); mode = 1; - } else { - return -EINVAL; } - result = ia64_sal_pci_config_read(addr, mode, len, &data); if (result != 0) return -EINVAL; @@ -83,11 +80,9 @@ int raw_pci_write(unsigned int seg, unsigned int bus, unsigned int devfn, if ((seg | reg) <= 255) { addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg); mode = 0; - } else if (sal_revision >= SAL_VERSION_CODE(3,2)) { + } else { addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg); mode = 1; - } else { - return -EINVAL; } result = ia64_sal_pci_config_write(addr, mode, len, value); if (result != 0) diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index 308e6595110e..25831c47c579 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -119,6 +119,7 @@ sn_pcidev_info_get(struct pci_dev *dev) * Additionally note that the struct sn_flush_device_war also has to be * removed from arch/ia64/sn/include/xtalk/hubdev.h */ +static u8 war_implemented = 0; static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, struct sn_flush_device_common *common) @@ -127,8 +128,11 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, struct sn_flush_device_war *dev_entry; struct ia64_sal_retval isrv = {0,0,0,0}; - printk_once(KERN_WARNING - "PROM version < 4.50 -- implementing old PROM flush WAR\n"); + if (!war_implemented) { + printk(KERN_WARNING "PROM version < 4.50 -- implementing old " + "PROM flush WAR\n"); + war_implemented = 1; + } war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); BUG_ON(!war_list); diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 55ac3c4e11d2..4c7e74790958 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -786,18 +786,17 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) break; case SN_HWPERF_GET_OBJ_NODE: - i = a.arg; - if (a.sz != sizeof(u64) || i < 0) { + if (a.sz != sizeof(u64) || a.arg < 0) { r = -EINVAL; goto error; } if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) { - if (i >= nobj) { + if (a.arg >= nobj) { r = -EINVAL; vfree(objs); goto error; } - if (objs[i].id != a.arg) { + if (objs[(i = a.arg)].id != a.arg) { for (i = 0; i < nobj; i++) { if (objs[i].id == a.arg) break; diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index 3a9319f93e89..c41234f1b825 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -11,9 +11,6 @@ config M32R select HAVE_IDE select HAVE_OPROFILE select INIT_ALL_POSSIBLE - select HAVE_KERNEL_GZIP - select HAVE_KERNEL_BZIP2 - select HAVE_KERNEL_LZMA config SBUS bool diff --git a/trunk/arch/m32r/boot/compressed/Makefile b/trunk/arch/m32r/boot/compressed/Makefile index 1003880d0dfd..560484ae35ec 100644 --- a/trunk/arch/m32r/boot/compressed/Makefile +++ b/trunk/arch/m32r/boot/compressed/Makefile @@ -4,8 +4,8 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \ - vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds +targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \ + piggy.o vmlinux.lds OBJECTS = $(obj)/head.o $(obj)/misc.o @@ -27,12 +27,6 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE - $(call if_changed,bzip2) - -$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE - $(call if_changed,lzma) - CFLAGS_misc.o += -fpic ifdef CONFIG_MMU @@ -43,9 +37,5 @@ endif OBJCOPYFLAGS += -R .empty_zero_page -suffix_$(CONFIG_KERNEL_GZIP) = gz -suffix_$(CONFIG_KERNEL_BZIP2) = bz2 -suffix_$(CONFIG_KERNEL_LZMA) = lzma - -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE $(call if_changed,ld) diff --git a/trunk/arch/m32r/boot/compressed/misc.c b/trunk/arch/m32r/boot/compressed/misc.c index 370d60881977..d394292498c0 100644 --- a/trunk/arch/m32r/boot/compressed/misc.c +++ b/trunk/arch/m32r/boot/compressed/misc.c @@ -9,49 +9,140 @@ * Adapted for SH by Stuart Menefy, Aug 1999 * * 2003-02-12: Support M32R by Takeo Takahashi + * This is based on arch/sh/boot/compressed/misc.c. */ +#include + /* * gzip declarations */ + +#define OF(args) args #define STATIC static #undef memset #undef memcpy #define memzero(s, n) memset ((s), 0, (n)) +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ + +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); static void error(char *m); +static unsigned char *input_data; +static int input_len; + +static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; + #include "m32r_sio.c" static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; -#ifdef CONFIG_KERNEL_BZIP2 -static void *memset(void *s, int c, size_t n) +#define HEAP_SIZE 0x10000 + +#include "../../../../lib/inflate.c" + +void* memset(void* s, int c, size_t n) { - char *ss = s; + int i; + char *ss = (char*)s; - while (n--) - *ss++ = c; + for (i=0;i> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; +} static void error(char *x) { @@ -62,20 +153,20 @@ static void error(char *x) while(1); /* Halt */ } +/* return decompressed size */ void decompress_kernel(int mmu_on, unsigned char *zimage_data, unsigned int zimage_len, unsigned long heap) { - unsigned char *input_data = zimage_data; - int input_len = zimage_len; - unsigned char *output_data; - output_data = (unsigned char *)CONFIG_MEMORY_START + 0x2000 + (mmu_on ? 0x80000000 : 0); free_mem_ptr = heap; - free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + input_data = zimage_data; + input_len = zimage_len; - puts("\nDecompressing Linux... "); - decompress(input_data, input_len, NULL, NULL, output_data, NULL, error); - puts("done.\nBooting the kernel.\n"); + makecrc(); + puts("Uncompressing Linux... "); + gunzip(); + puts("Ok, booting the kernel.\n"); } diff --git a/trunk/arch/m32r/kernel/smp.c b/trunk/arch/m32r/kernel/smp.c index 31cef20b2996..8a88f1f0a3e2 100644 --- a/trunk/arch/m32r/kernel/smp.c +++ b/trunk/arch/m32r/kernel/smp.c @@ -806,7 +806,7 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num, if (mask & ~physids_coerce(phys_cpu_present_map)) BUG(); - if (ipi_num >= NR_IPIS || ipi_num < 0) + if (ipi_num >= NR_IPIS) BUG(); mask <<= IPI_SHIFT; diff --git a/trunk/arch/m32r/kernel/time.c b/trunk/arch/m32r/kernel/time.c index 9cedcef11575..e7fee0f198d5 100644 --- a/trunk/arch/m32r/kernel/time.c +++ b/trunk/arch/m32r/kernel/time.c @@ -75,7 +75,7 @@ u32 arch_gettimeoffset(void) count = 0; count = (latch - count) * TICK_SIZE; - elapsed_time = DIV_ROUND_CLOSEST(count, latch); + elapsed_time = (count + latch / 2) / latch; /* NOTE: LATCH is equal to the "interval" value (= reload count). */ #else /* CONFIG_SMP */ @@ -93,7 +93,7 @@ u32 arch_gettimeoffset(void) p_count = count; count = (latch - count) * TICK_SIZE; - elapsed_time = DIV_ROUND_CLOSEST(count, latch); + elapsed_time = (count + latch / 2) / latch; /* NOTE: LATCH is equal to the "interval" value (= reload count). */ #endif /* CONFIG_SMP */ #elif defined(CONFIG_CHIP_M32310) @@ -211,7 +211,7 @@ void __init time_init(void) bus_clock = boot_cpu_data.bus_clock; divide = boot_cpu_data.timer_divide; - latch = DIV_ROUND_CLOSEST(bus_clock/divide, HZ); + latch = (bus_clock/divide + HZ / 2) / HZ; printk("Timer start : latch = %ld\n", latch); diff --git a/trunk/arch/m32r/kernel/vmlinux.lds.S b/trunk/arch/m32r/kernel/vmlinux.lds.S index 7da94eaa082b..8ceb6181d805 100644 --- a/trunk/arch/m32r/kernel/vmlinux.lds.S +++ b/trunk/arch/m32r/kernel/vmlinux.lds.S @@ -42,8 +42,6 @@ SECTIONS _etext = .; /* End of text section */ EXCEPTION_TABLE(16) - NOTES - RODATA RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE) _edata = .; /* End of data section */ diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index ecdc19a299b2..29dd8489ffec 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -561,7 +561,7 @@ config HPAPCI config MVME147_SCC bool "SCC support for MVME147 serial ports" - depends on MVME147 && BROKEN + depends on MVME147 help This is the driver for the serial ports on the Motorola MVME147 boards. Everyone using one of these boards should say Y here. @@ -576,14 +576,14 @@ config SERIAL167 config MVME162_SCC bool "SCC support for MVME162 serial ports" - depends on MVME16x && BROKEN + depends on MVME16x help This is the driver for the serial ports on the Motorola MVME162 and 172 boards. Everyone using one of these boards should say Y here. config BVME6000_SCC bool "SCC support for BVME6000 serial ports" - depends on BVME6000 && BROKEN + depends on BVME6000 help This is the driver for the serial ports on the BVME4000 and BVME6000 boards from BVM Ltd. Everyone using one of these boards should say diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 03bd56a2fb6e..705a7a9170f3 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -1012,9 +1012,9 @@ config BOOT_ELF32 config MIPS_L1_CACHE_SHIFT int - default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL - default "6" if MIPS_CPU_SCACHE + default "4" if MACH_DECSTATION || MIKROTIK_RB532 default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON + default "4" if PMC_MSP4200_EVAL default "5" config HAVE_STD_PC_SERIAL_PORT diff --git a/trunk/arch/mips/alchemy/common/irq.c b/trunk/arch/mips/alchemy/common/irq.c index d670928afcfd..c88c821b4c36 100644 --- a/trunk/arch/mips/alchemy/common/irq.c +++ b/trunk/arch/mips/alchemy/common/irq.c @@ -354,28 +354,6 @@ static void au1x_ic1_ack(unsigned int irq_nr) au_sync(); } -static void au1x_ic0_maskack(unsigned int irq_nr) -{ - unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; - - au_writel(1 << bit, IC0_WAKECLR); - au_writel(1 << bit, IC0_MASKCLR); - au_writel(1 << bit, IC0_RISINGCLR); - au_writel(1 << bit, IC0_FALLINGCLR); - au_sync(); -} - -static void au1x_ic1_maskack(unsigned int irq_nr) -{ - unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; - - au_writel(1 << bit, IC1_WAKECLR); - au_writel(1 << bit, IC1_MASKCLR); - au_writel(1 << bit, IC1_RISINGCLR); - au_writel(1 << bit, IC1_FALLINGCLR); - au_sync(); -} - static int au1x_ic1_setwake(unsigned int irq, unsigned int on) { unsigned int bit = irq - AU1000_INTC1_INT_BASE; @@ -401,21 +379,25 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on) /* * irq_chips for both ICs; this way the mask handlers can be * as short as possible. + * + * NOTE: the ->ack() callback is used by the handle_edge_irq + * flowhandler only, the ->mask_ack() one by handle_level_irq, + * so no need for an irq_chip for each type of irq (level/edge). */ static struct irq_chip au1x_ic0_chip = { .name = "Alchemy-IC0", - .ack = au1x_ic0_ack, + .ack = au1x_ic0_ack, /* edge */ .mask = au1x_ic0_mask, - .mask_ack = au1x_ic0_maskack, + .mask_ack = au1x_ic0_mask, /* level */ .unmask = au1x_ic0_unmask, .set_type = au1x_ic_settype, }; static struct irq_chip au1x_ic1_chip = { .name = "Alchemy-IC1", - .ack = au1x_ic1_ack, + .ack = au1x_ic1_ack, /* edge */ .mask = au1x_ic1_mask, - .mask_ack = au1x_ic1_maskack, + .mask_ack = au1x_ic1_mask, /* level */ .unmask = au1x_ic1_unmask, .set_type = au1x_ic_settype, .set_wake = au1x_ic1_setwake, diff --git a/trunk/arch/mips/alchemy/mtx-1/board_setup.c b/trunk/arch/mips/alchemy/mtx-1/board_setup.c index 45b61c9b82b9..cc32c69a74ad 100644 --- a/trunk/arch/mips/alchemy/mtx-1/board_setup.c +++ b/trunk/arch/mips/alchemy/mtx-1/board_setup.c @@ -69,7 +69,6 @@ void __init board_setup(void) #else au_writel(0xf, Au1500_PCI_CFG); #endif - board_pci_idsel = mtx1_pci_idsel; #endif /* Initialize sys_pinfunc */ @@ -86,6 +85,8 @@ void __init board_setup(void) alchemy_gpio_direction_output(211, 1); /* green on */ alchemy_gpio_direction_output(212, 0); /* red off */ + board_pci_idsel = mtx1_pci_idsel; + printk(KERN_INFO "4G Systems MTX-1 Board\n"); } diff --git a/trunk/arch/mips/ar7/platform.c b/trunk/arch/mips/ar7/platform.c index 835f3f0319ca..e2278c04459d 100644 --- a/trunk/arch/mips/ar7/platform.c +++ b/trunk/arch/mips/ar7/platform.c @@ -503,7 +503,6 @@ static int __init ar7_register_devices(void) { u16 chip_id; int res; - u32 *bootcr, val; #ifdef CONFIG_SERIAL_8250 static struct uart_port uart_port[2]; @@ -596,13 +595,7 @@ static int __init ar7_register_devices(void) ar7_wdt_res.end = ar7_wdt_res.start + 0x20; - bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4); - val = *bootcr; - iounmap(bootcr); - - /* Register watchdog only if enabled in hardware */ - if (val & AR7_WDT_HW_ENA) - res = platform_device_register(&ar7_wdt); + res = platform_device_register(&ar7_wdt); return res; } diff --git a/trunk/arch/mips/bcm63xx/Makefile b/trunk/arch/mips/bcm63xx/Makefile index 00064b660809..c146d1ededed 100644 --- a/trunk/arch/mips/bcm63xx/Makefile +++ b/trunk/arch/mips/bcm63xx/Makefile @@ -1,5 +1,5 @@ obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ - dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o + dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-y += boards/ diff --git a/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c b/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c index 05a35cf5963d..78e155d21be6 100644 --- a/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define PFX "board_bcm963xx: " @@ -793,6 +794,8 @@ int __init board_register_devices(void) { u32 val; + bcm63xx_uart_register(); + if (board.has_pccard) bcm63xx_pcmcia_register(); diff --git a/trunk/arch/mips/bcm63xx/cpu.c b/trunk/arch/mips/bcm63xx/cpu.c index 70378bb5e3f9..6dc43f0483e8 100644 --- a/trunk/arch/mips/bcm63xx/cpu.c +++ b/trunk/arch/mips/bcm63xx/cpu.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -285,7 +284,6 @@ void __init bcm63xx_cpu_init(void) { unsigned int tmp, expected_cpu_id; struct cpuinfo_mips *c = ¤t_cpu_data; - unsigned int cpu = smp_processor_id(); /* soc registers location depends on cpu type */ expected_cpu_id = 0; @@ -295,7 +293,6 @@ void __init bcm63xx_cpu_init(void) * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c */ case CPU_BCM3302: - __cpu_name[cpu] = "Broadcom BCM6338"; expected_cpu_id = BCM6338_CPU_ID; bcm63xx_regs_base = bcm96338_regs_base; bcm63xx_irqs = bcm96338_irqs; diff --git a/trunk/arch/mips/bcm63xx/dev-uart.c b/trunk/arch/mips/bcm63xx/dev-uart.c index b0519461ad9b..5f3d89c4a988 100644 --- a/trunk/arch/mips/bcm63xx/dev-uart.c +++ b/trunk/arch/mips/bcm63xx/dev-uart.c @@ -10,6 +10,7 @@ #include #include #include +#include static struct resource uart_resources[] = { { @@ -38,4 +39,3 @@ int __init bcm63xx_uart_register(void) uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); return platform_device_register(&bcm63xx_uart_device); } -arch_initcall(bcm63xx_uart_register); diff --git a/trunk/arch/mips/bcm63xx/dev-wdt.c b/trunk/arch/mips/bcm63xx/dev-wdt.c deleted file mode 100644 index 3e6c716a4c11..000000000000 --- a/trunk/arch/mips/bcm63xx/dev-wdt.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2008 Florian Fainelli - */ - -#include -#include -#include -#include - -static struct resource wdt_resources[] = { - { - .start = -1, /* filled at runtime */ - .end = -1, /* filled at runtime */ - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bcm63xx_wdt_device = { - .name = "bcm63xx-wdt", - .id = 0, - .num_resources = ARRAY_SIZE(wdt_resources), - .resource = wdt_resources, -}; - -int __init bcm63xx_wdt_register(void) -{ - wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT); - wdt_resources[0].end = wdt_resources[0].start; - wdt_resources[0].end += RSET_WDT_SIZE - 1; - - return platform_device_register(&bcm63xx_wdt_device); -} -arch_initcall(bcm63xx_wdt_register); diff --git a/trunk/arch/mips/bcm63xx/setup.c b/trunk/arch/mips/bcm63xx/setup.c index d0056598fbfc..b18a0ca926fa 100644 --- a/trunk/arch/mips/bcm63xx/setup.c +++ b/trunk/arch/mips/bcm63xx/setup.c @@ -75,9 +75,7 @@ void bcm63xx_machine_reboot(void) bcm6348_a1_reboot(); printk(KERN_INFO "triggering watchdog soft-reset...\n"); - reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG); - reg |= SYS_PLL_SOFT_RESET; - bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG); + bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG); while (1) ; } diff --git a/trunk/arch/mips/cavium-octeon/octeon-irq.c b/trunk/arch/mips/cavium-octeon/octeon-irq.c index 6f2acf09328d..384f1842bfb1 100644 --- a/trunk/arch/mips/cavium-octeon/octeon-irq.c +++ b/trunk/arch/mips/cavium-octeon/octeon-irq.c @@ -17,15 +17,6 @@ DEFINE_RWLOCK(octeon_irq_ciu0_rwlock); DEFINE_RWLOCK(octeon_irq_ciu1_rwlock); DEFINE_SPINLOCK(octeon_irq_msi_lock); -static int octeon_coreid_for_cpu(int cpu) -{ -#ifdef CONFIG_SMP - return cpu_logical_map(cpu); -#else - return cvmx_get_core_num(); -#endif -} - static void octeon_irq_core_ack(unsigned int irq) { unsigned int bit = irq - OCTEON_IRQ_SW0; @@ -161,10 +152,11 @@ static void octeon_irq_ciu0_disable(unsigned int irq) int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ unsigned long flags; uint64_t en0; +#ifdef CONFIG_SMP int cpu; write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags); for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); + int coreid = cpu_logical_map(cpu); en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); en0 &= ~(1ull << bit); cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); @@ -175,57 +167,26 @@ static void octeon_irq_ciu0_disable(unsigned int irq) */ cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags); -} - -/* - * Enable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu0_enable_v2(unsigned int irq) -{ - int index = cvmx_get_core_num() * 2; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); -} - -/* - * Disable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu0_disable_v2(unsigned int irq) -{ - int index = cvmx_get_core_num() * 2; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); -} - -/* - * Disable the irq on the all cores for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu0_disable_all_v2(unsigned int irq) -{ - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - int index; - int cpu; - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2; - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); - } +#else + int coreid = cvmx_get_core_num(); + local_irq_save(flags); + en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + en0 &= ~(1ull << bit); + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); + cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); + local_irq_restore(flags); +#endif } #ifdef CONFIG_SMP static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest) { int cpu; - unsigned long flags; int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ - write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags); + write_lock(&octeon_irq_ciu0_rwlock); for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); + int coreid = cpu_logical_map(cpu); uint64_t en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); if (cpumask_test_cpu(cpu, dest)) @@ -239,45 +200,11 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask * * of them are done. */ cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); - write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags); + write_unlock(&octeon_irq_ciu0_rwlock); return 0; } - -/* - * Set affinity for the irq for chips that have the EN*_W1{S,C} - * registers. - */ -static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq, - const struct cpumask *dest) -{ - int cpu; - int index; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2; - if (cpumask_test_cpu(cpu, dest)) - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); - else - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); - } - return 0; -} -#endif - -/* - * Newer octeon chips have support for lockless CIU operation. - */ -static struct irq_chip octeon_irq_chip_ciu0_v2 = { - .name = "CIU0", - .enable = octeon_irq_ciu0_enable_v2, - .disable = octeon_irq_ciu0_disable_all_v2, - .ack = octeon_irq_ciu0_disable_v2, - .eoi = octeon_irq_ciu0_enable_v2, -#ifdef CONFIG_SMP - .set_affinity = octeon_irq_ciu0_set_affinity_v2, #endif -}; static struct irq_chip octeon_irq_chip_ciu0 = { .name = "CIU0", @@ -342,10 +269,11 @@ static void octeon_irq_ciu1_disable(unsigned int irq) int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ unsigned long flags; uint64_t en1; +#ifdef CONFIG_SMP int cpu; write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags); for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); + int coreid = cpu_logical_map(cpu); en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); en1 &= ~(1ull << bit); cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); @@ -356,58 +284,26 @@ static void octeon_irq_ciu1_disable(unsigned int irq) */ cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags); -} - -/* - * Enable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu1_enable_v2(unsigned int irq) -{ - int index = cvmx_get_core_num() * 2 + 1; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); -} - -/* - * Disable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu1_disable_v2(unsigned int irq) -{ - int index = cvmx_get_core_num() * 2 + 1; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); -} - -/* - * Disable the irq on the all cores for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu1_disable_all_v2(unsigned int irq) -{ - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - int index; - int cpu; - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2 + 1; - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } +#else + int coreid = cvmx_get_core_num(); + local_irq_save(flags); + en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + en1 &= ~(1ull << bit); + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); + cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + local_irq_restore(flags); +#endif } #ifdef CONFIG_SMP -static int octeon_irq_ciu1_set_affinity(unsigned int irq, - const struct cpumask *dest) +static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest) { int cpu; - unsigned long flags; int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ - write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags); + write_lock(&octeon_irq_ciu1_rwlock); for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); + int coreid = cpu_logical_map(cpu); uint64_t en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1 (coreid * 2 + 1)); @@ -422,46 +318,12 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq, * of them are done. */ cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); - write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags); - - return 0; -} + write_unlock(&octeon_irq_ciu1_rwlock); -/* - * Set affinity for the irq for chips that have the EN*_W1{S,C} - * registers. - */ -static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq, - const struct cpumask *dest) -{ - int cpu; - int index; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2 + 1; - if (cpumask_test_cpu(cpu, dest)) - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); - else - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } return 0; } #endif -/* - * Newer octeon chips have support for lockless CIU operation. - */ -static struct irq_chip octeon_irq_chip_ciu1_v2 = { - .name = "CIU0", - .enable = octeon_irq_ciu1_enable_v2, - .disable = octeon_irq_ciu1_disable_all_v2, - .ack = octeon_irq_ciu1_disable_v2, - .eoi = octeon_irq_ciu1_enable_v2, -#ifdef CONFIG_SMP - .set_affinity = octeon_irq_ciu1_set_affinity_v2, -#endif -}; - static struct irq_chip octeon_irq_chip_ciu1 = { .name = "CIU1", .enable = octeon_irq_ciu1_enable, @@ -558,8 +420,6 @@ static struct irq_chip octeon_irq_chip_msi = { void __init arch_init_irq(void) { int irq; - struct irq_chip *chip0; - struct irq_chip *chip1; #ifdef CONFIG_SMP /* Set the default affinity to the boot cpu. */ @@ -570,16 +430,6 @@ void __init arch_init_irq(void) if (NR_IRQS < OCTEON_IRQ_LAST) pr_err("octeon_irq_init: NR_IRQS is set too low\n"); - if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) { - chip0 = &octeon_irq_chip_ciu0_v2; - chip1 = &octeon_irq_chip_ciu1_v2; - } else { - chip0 = &octeon_irq_chip_ciu0; - chip1 = &octeon_irq_chip_ciu1; - } - /* 0 - 15 reserved for i8259 master and slave controller. */ /* 17 - 23 Mips internal */ @@ -590,12 +440,14 @@ void __init arch_init_irq(void) /* 24 - 87 CIU_INT_SUM0 */ for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { - set_irq_chip_and_handler(irq, chip0, handle_percpu_irq); + set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu0, + handle_percpu_irq); } /* 88 - 151 CIU_INT_SUM1 */ for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) { - set_irq_chip_and_handler(irq, chip1, handle_percpu_irq); + set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu1, + handle_percpu_irq); } #ifdef CONFIG_PCI_MSI @@ -653,10 +505,14 @@ asmlinkage void plat_irq_dispatch(void) #ifdef CONFIG_HOTPLUG_CPU static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu) { - unsigned int isset; - int coreid = octeon_coreid_for_cpu(cpu); + unsigned int isset; +#ifdef CONFIG_SMP + int coreid = cpu_logical_map(cpu); +#else + int coreid = cvmx_get_core_num(); +#endif int bit = (irq < OCTEON_IRQ_WDOG0) ? - irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0; + irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0; if (irq < 64) { isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) & (1ull << bit)) >> bit; diff --git a/trunk/arch/mips/cavium-octeon/smp.c b/trunk/arch/mips/cavium-octeon/smp.c index c198efdf583e..32d51a31dc48 100644 --- a/trunk/arch/mips/cavium-octeon/smp.c +++ b/trunk/arch/mips/cavium-octeon/smp.c @@ -65,12 +65,11 @@ void octeon_send_ipi_single(int cpu, unsigned int action) cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action); } -static inline void octeon_send_ipi_mask(const struct cpumask *mask, - unsigned int action) +static inline void octeon_send_ipi_mask(cpumask_t mask, unsigned int action) { unsigned int i; - for_each_cpu_mask(i, *mask) + for_each_cpu_mask(i, mask) octeon_send_ipi_single(i, action); } diff --git a/trunk/arch/mips/include/asm/fixmap.h b/trunk/arch/mips/include/asm/fixmap.h index 0b89b83e2055..efeddc8db8b1 100644 --- a/trunk/arch/mips/include/asm/fixmap.h +++ b/trunk/arch/mips/include/asm/fixmap.h @@ -48,9 +48,9 @@ enum fixed_addresses { #define FIX_N_COLOURS 8 FIX_CMAP_BEGIN, #ifdef CONFIG_MIPS_MT_SMTC - FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS * 2), + FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS), #else - FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2), + FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS, #endif #ifdef CONFIG_HIGHMEM /* reserved pte's for temporary kernel mappings */ diff --git a/trunk/arch/mips/include/asm/gcmpregs.h b/trunk/arch/mips/include/asm/gcmpregs.h index c0cf76a2ca89..36fd969d64d6 100644 --- a/trunk/arch/mips/include/asm/gcmpregs.h +++ b/trunk/arch/mips/include/asm/gcmpregs.h @@ -19,20 +19,15 @@ #define GCMP_GDB_OFS 0x8000 /* Global Debug Block */ /* Offsets to individual GCMP registers from GCMP base */ -#define GCMPOFS(block, tag, reg) \ - (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS) -#define GCMPOFSn(block, tag, reg, n) \ - (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS(n)) +#define GCMPOFS(block, tag, reg) (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS) #define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg) -#define GCMPGCBOFSn(reg, n) GCMPOFSn(GCB, GCB, reg, n) #define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg) #define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg) #define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg) /* GCMP register access */ #define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg)) -#define GCMPGCBn(reg, n) REGP(_gcmp_base, GCMPGCBOFSn(reg, n)) #define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg)) #define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg)) #define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg)) @@ -54,10 +49,10 @@ #define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17) #define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0 #define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2) -#define GCMP_GCB_GCMPB_CMDEFTGT_DISABLED 0 -#define GCMP_GCB_GCMPB_CMDEFTGT_MEM 1 -#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2 -#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3 +#define GCMP_GCB_GCMPB_CMDEFTGT_MEM 0 +#define GCMP_GCB_GCMPB_CMDEFTGT_MEM1 1 +#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2 +#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3 #define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */ #define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */ #define GCMP_GCB_GCSRAP_CMACCESS_SHF 0 @@ -120,6 +115,5 @@ #define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */ extern int __init gcmp_probe(unsigned long, unsigned long); -extern int __init gcmp_niocu(void); -extern void __init gcmp_setregion(int, unsigned long, unsigned long, int); + #endif /* _ASM_GCMPREGS_H */ diff --git a/trunk/arch/mips/include/asm/gic.h b/trunk/arch/mips/include/asm/gic.h index 9b9436a4d816..a8f57341f123 100644 --- a/trunk/arch/mips/include/asm/gic.h +++ b/trunk/arch/mips/include/asm/gic.h @@ -12,6 +12,7 @@ #define _ASM_GICREGS_H #undef GICISBYTELITTLEENDIAN +#define GICISWORDLITTLEENDIAN /* Constants */ #define GIC_POL_POS 1 @@ -19,7 +20,11 @@ #define GIC_TRIG_EDGE 1 #define GIC_TRIG_LEVEL 0 +#ifdef CONFIG_SMP #define GIC_NUM_INTRS (24 + NR_CPUS * 2) +#else +#define GIC_NUM_INTRS 32 +#endif #define MSK(n) ((1 << (n)) - 1) #define REG32(addr) (*(volatile unsigned int *) (addr)) @@ -65,13 +70,13 @@ #define USM_VISIBLE_SECTION_SIZE 0x10000 /* Register Map for Shared Section */ +#if defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(GICISWORDLITTLEENDIAN) #define GIC_SH_CONFIG_OFS 0x0000 /* Shared Global Counter */ #define GIC_SH_COUNTER_31_00_OFS 0x0010 #define GIC_SH_COUNTER_63_32_OFS 0x0014 -#define GIC_SH_REVISIONID_OFS 0x0020 /* Interrupt Polarity */ #define GIC_SH_POL_31_0_OFS 0x0100 @@ -159,31 +164,24 @@ (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) -/* Convert an interrupt number to a byte offset/bit for multi-word registers */ -#define GIC_INTR_OFS(intr) (((intr) / 32)*4) -#define GIC_INTR_BIT(intr) ((intr) % 32) - /* Polarity : Reset Value is always 0 */ #define GIC_SH_SET_POLARITY_OFS 0x0100 #define GIC_SET_POLARITY(intr, pol) \ - GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ - GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr)) + GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + (((intr) / 32) * 4)), (pol) << ((intr) % 32)) /* Triggering : Reset Value is always 0 */ #define GIC_SH_SET_TRIGGER_OFS 0x0180 #define GIC_SET_TRIGGER(intr, trig) \ - GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ - GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr)) + GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + (((intr) / 32) * 4)), (trig) << ((intr) % 32)) /* Mask manipulation */ #define GIC_SH_SMASK_OFS 0x0380 -#define GIC_SET_INTR_MASK(intr) \ - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ - GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) +#define GIC_SET_INTR_MASK(intr, val) \ + GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32))) + #define GIC_SH_RMASK_OFS 0x0300 -#define GIC_CLR_INTR_MASK(intr) \ - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ - GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) +#define GIC_CLR_INTR_MASK(intr, val) \ + GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32))) /* Register Map for Local Section */ #define GIC_VPE_CTL_OFS 0x0000 @@ -221,6 +219,161 @@ #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 +#else /* CONFIG_CPU_BIG_ENDIAN */ + +#define GIC_SH_CONFIG_OFS 0x0000 + +/* Shared Global Counter */ +#define GIC_SH_COUNTER_31_00_OFS 0x0014 +#define GIC_SH_COUNTER_63_32_OFS 0x0010 + +/* Interrupt Polarity */ +#define GIC_SH_POL_31_0_OFS 0x0104 +#define GIC_SH_POL_63_32_OFS 0x0100 +#define GIC_SH_POL_95_64_OFS 0x010c +#define GIC_SH_POL_127_96_OFS 0x0108 +#define GIC_SH_POL_159_128_OFS 0x0114 +#define GIC_SH_POL_191_160_OFS 0x0110 +#define GIC_SH_POL_223_192_OFS 0x011c +#define GIC_SH_POL_255_224_OFS 0x0118 + +/* Edge/Level Triggering */ +#define GIC_SH_TRIG_31_0_OFS 0x0184 +#define GIC_SH_TRIG_63_32_OFS 0x0180 +#define GIC_SH_TRIG_95_64_OFS 0x018c +#define GIC_SH_TRIG_127_96_OFS 0x0188 +#define GIC_SH_TRIG_159_128_OFS 0x0194 +#define GIC_SH_TRIG_191_160_OFS 0x0190 +#define GIC_SH_TRIG_223_192_OFS 0x019c +#define GIC_SH_TRIG_255_224_OFS 0x0198 + +/* Dual Edge Triggering */ +#define GIC_SH_DUAL_31_0_OFS 0x0204 +#define GIC_SH_DUAL_63_32_OFS 0x0200 +#define GIC_SH_DUAL_95_64_OFS 0x020c +#define GIC_SH_DUAL_127_96_OFS 0x0208 +#define GIC_SH_DUAL_159_128_OFS 0x0214 +#define GIC_SH_DUAL_191_160_OFS 0x0210 +#define GIC_SH_DUAL_223_192_OFS 0x021c +#define GIC_SH_DUAL_255_224_OFS 0x0218 + +/* Set/Clear corresponding bit in Edge Detect Register */ +#define GIC_SH_WEDGE_OFS 0x0280 + +/* Reset Mask - Disables Interrupt */ +#define GIC_SH_RMASK_31_0_OFS 0x0304 +#define GIC_SH_RMASK_63_32_OFS 0x0300 +#define GIC_SH_RMASK_95_64_OFS 0x030c +#define GIC_SH_RMASK_127_96_OFS 0x0308 +#define GIC_SH_RMASK_159_128_OFS 0x0314 +#define GIC_SH_RMASK_191_160_OFS 0x0310 +#define GIC_SH_RMASK_223_192_OFS 0x031c +#define GIC_SH_RMASK_255_224_OFS 0x0318 + +/* Set Mask (WO) - Enables Interrupt */ +#define GIC_SH_SMASK_31_0_OFS 0x0384 +#define GIC_SH_SMASK_63_32_OFS 0x0380 +#define GIC_SH_SMASK_95_64_OFS 0x038c +#define GIC_SH_SMASK_127_96_OFS 0x0388 +#define GIC_SH_SMASK_159_128_OFS 0x0394 +#define GIC_SH_SMASK_191_160_OFS 0x0390 +#define GIC_SH_SMASK_223_192_OFS 0x039c +#define GIC_SH_SMASK_255_224_OFS 0x0398 + +/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ +#define GIC_SH_MASK_31_0_OFS 0x0404 +#define GIC_SH_MASK_63_32_OFS 0x0400 +#define GIC_SH_MASK_95_64_OFS 0x040c +#define GIC_SH_MASK_127_96_OFS 0x0408 +#define GIC_SH_MASK_159_128_OFS 0x0414 +#define GIC_SH_MASK_191_160_OFS 0x0410 +#define GIC_SH_MASK_223_192_OFS 0x041c +#define GIC_SH_MASK_255_224_OFS 0x0418 + +/* Pending Global Interrupts (RO) */ +#define GIC_SH_PEND_31_0_OFS 0x0484 +#define GIC_SH_PEND_63_32_OFS 0x0480 +#define GIC_SH_PEND_95_64_OFS 0x048c +#define GIC_SH_PEND_127_96_OFS 0x0488 +#define GIC_SH_PEND_159_128_OFS 0x0494 +#define GIC_SH_PEND_191_160_OFS 0x0490 +#define GIC_SH_PEND_223_192_OFS 0x049c +#define GIC_SH_PEND_255_224_OFS 0x0498 + +#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 + +/* Maps Interrupt X to a Pin */ +#define GIC_SH_MAP_TO_PIN(intr) \ + (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) + +#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2004 + +/* + * Maps Interrupt X to a VPE. This is more complex than the LE case, as + * odd and even registers need to be transposed. It does work - trust me! + */ +#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ + (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + \ + (((((vpe) / 32) ^ 1) - 1) * 4)) +#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) + +/* Polarity */ +#define GIC_SH_SET_POLARITY_OFS 0x0100 +#define GIC_SET_POLARITY(intr, pol) \ + GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (pol) << ((intr) % 32)) + +/* Triggering */ +#define GIC_SH_SET_TRIGGER_OFS 0x0180 +#define GIC_SET_TRIGGER(intr, trig) \ + GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (trig) << ((intr) % 32)) + +/* Mask manipulation */ +#define GIC_SH_SMASK_OFS 0x0380 +#define GIC_SET_INTR_MASK(intr, val) \ + GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32))) + +#define GIC_SH_RMASK_OFS 0x0300 +#define GIC_CLR_INTR_MASK(intr, val) \ + GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32))) + +/* Register Map for Local Section */ +#define GIC_VPE_CTL_OFS 0x0000 +#define GIC_VPE_PEND_OFS 0x0004 +#define GIC_VPE_MASK_OFS 0x0008 +#define GIC_VPE_RMASK_OFS 0x000c +#define GIC_VPE_SMASK_OFS 0x0010 +#define GIC_VPE_WD_MAP_OFS 0x0040 +#define GIC_VPE_COMPARE_MAP_OFS 0x0044 +#define GIC_VPE_TIMER_MAP_OFS 0x0048 +#define GIC_VPE_PERFCTR_MAP_OFS 0x0050 +#define GIC_VPE_SWINT0_MAP_OFS 0x0054 +#define GIC_VPE_SWINT1_MAP_OFS 0x0058 +#define GIC_VPE_OTHER_ADDR_OFS 0x0080 +#define GIC_VPE_WD_CONFIG0_OFS 0x0090 +#define GIC_VPE_WD_COUNT0_OFS 0x0094 +#define GIC_VPE_WD_INITIAL0_OFS 0x0098 +#define GIC_VPE_COMPARE_LO_OFS 0x00a4 +#define GIC_VPE_COMPARE_HI_OFS 0x00a0 + +#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 +#define GIC_VPE_EIC_SS(intr) \ + (GIC_EIC_SHADOW_SET_BASE + (4 * intr)) + +#define GIC_VPE_EIC_VEC_BASE 0x0800 +#define GIC_VPE_EIC_VEC(intr) \ + (GIC_VPE_EIC_VEC_BASE + (4 * intr)) + +#define GIC_VPE_TENABLE_NMI_OFS 0x1000 +#define GIC_VPE_TENABLE_YQ_OFS 0x1004 +#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 +#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 + +/* User Mode Visible Section Register Map */ +#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0004 +#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0000 + +#endif /* !LE */ + /* Masks */ #define GIC_SH_CONFIG_COUNTSTOP_SHF 28 #define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) @@ -320,13 +473,12 @@ struct gic_intrmask_regs { * in building ipi_map. */ struct gic_intr_map { + unsigned int intrnum; /* Ext Intr Num */ unsigned int cpunum; /* Directed to this CPU */ unsigned int pin; /* Directed to this Pin */ unsigned int polarity; /* Polarity : +/- */ unsigned int trigtype; /* Trigger : Edge/Levl */ - unsigned int flags; /* Misc flags */ -#define GIC_FLAG_IPI 0x01 -#define GIC_FLAG_TRANSPARENT 0x02 + unsigned int ipiflag; /* Is used for IPI ? */ }; extern void gic_init(unsigned long gic_base_addr, diff --git a/trunk/arch/mips/include/asm/mach-ar7/ar7.h b/trunk/arch/mips/include/asm/mach-ar7/ar7.h index 21cbbc706448..de71694614de 100644 --- a/trunk/arch/mips/include/asm/mach-ar7/ar7.h +++ b/trunk/arch/mips/include/asm/mach-ar7/ar7.h @@ -78,9 +78,6 @@ #define AR7_REF_CLOCK 25000000 #define AR7_XTAL_CLOCK 24000000 -/* DCL */ -#define AR7_WDT_HW_ENA 0x10 - struct plat_cpmac_data { int reset_bit; int power_bit; diff --git a/trunk/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/trunk/arch/mips/include/asm/mach-au1x00/gpio-au1000.h index 91595fa89034..feea00148b5d 100644 --- a/trunk/arch/mips/include/asm/mach-au1x00/gpio-au1000.h +++ b/trunk/arch/mips/include/asm/mach-au1x00/gpio-au1000.h @@ -104,8 +104,6 @@ static inline int au1100_gpio2_to_irq(int gpio) if ((gpio >= 8) && (gpio <= 15)) return MAKE_IRQ(0, 29); /* shared GPIO208_215 */ - - return -ENXIO; } #ifdef CONFIG_SOC_AU1100 diff --git a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h new file mode 100644 index 000000000000..bf348f573bbc --- /dev/null +++ b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h @@ -0,0 +1,6 @@ +#ifndef BCM63XX_DEV_UART_H_ +#define BCM63XX_DEV_UART_H_ + +int bcm63xx_uart_register(void); + +#endif /* BCM63XX_DEV_UART_H_ */ diff --git a/trunk/arch/mips/include/asm/mach-ip27/topology.h b/trunk/arch/mips/include/asm/mach-ip27/topology.h index 09a59bcc1b07..f6837422fe65 100644 --- a/trunk/arch/mips/include/asm/mach-ip27/topology.h +++ b/trunk/arch/mips/include/asm/mach-ip27/topology.h @@ -44,8 +44,8 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; .busy_factor = 32, \ .imbalance_pct = 125, \ .cache_nice_tries = 1, \ - .flags = SD_LOAD_BALANCE | \ - SD_BALANCE_EXEC, \ + .flags = SD_LOAD_BALANCE \ + | SD_BALANCE_EXEC \ .last_balance = jiffies, \ .balance_interval = 1, \ .nr_balance_failed = 0, \ diff --git a/trunk/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/trunk/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h index 9947e57c91de..ce5b6e270e3f 100644 --- a/trunk/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h +++ b/trunk/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h @@ -29,7 +29,7 @@ #define cpu_has_cache_cdex_p 0 #define cpu_has_cache_cdex_s 0 #define cpu_has_counter 1 -#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) +#define cpu_has_dc_aliases 1 #define cpu_has_divec 0 #define cpu_has_dsp 0 #define cpu_has_ejtag 0 @@ -54,5 +54,6 @@ #define cpu_has_vce 0 #define cpu_has_vtag_icache 0 #define cpu_has_watch 1 +#define cpu_icache_snoops_remote_store 1 #endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */ diff --git a/trunk/arch/mips/include/asm/mmu_context.h b/trunk/arch/mips/include/asm/mmu_context.h index 6083db586500..d9743536a621 100644 --- a/trunk/arch/mips/include/asm/mmu_context.h +++ b/trunk/arch/mips/include/asm/mmu_context.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #ifdef CONFIG_MIPS_MT_SMTC #include @@ -37,13 +36,11 @@ extern unsigned long pgd_current[]; #ifdef CONFIG_32BIT #define TLBMISS_HANDLER_SETUP() \ write_c0_context((unsigned long) smp_processor_id() << 25); \ - back_to_back_c0_hazard(); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif #ifdef CONFIG_64BIT #define TLBMISS_HANDLER_SETUP() \ write_c0_context((unsigned long) smp_processor_id() << 26); \ - back_to_back_c0_hazard(); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif @@ -168,12 +165,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * having ASID_MASK smaller than the hardware maximum, * make sure no "soft" bits become "hard"... */ - write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | - cpu_asid(cpu, next)); + write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) + | (cpu_context(cpu, next) & ASID_MASK)); ehb(); /* Make sure it propagates to TCStatus */ evpe(mtflags); #else - write_c0_entryhi(cpu_asid(cpu, next)); + write_c0_entryhi(cpu_context(cpu, next)); #endif /* CONFIG_MIPS_MT_SMTC */ TLBMISS_HANDLER_SETUP_PGD(next->pgd); @@ -229,11 +226,11 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) } /* See comments for similar code above */ write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | - cpu_asid(cpu, next)); + (cpu_context(cpu, next) & ASID_MASK)); ehb(); /* Make sure it propagates to TCStatus */ evpe(mtflags); #else - write_c0_entryhi(cpu_asid(cpu, next)); + write_c0_entryhi(cpu_context(cpu, next)); #endif /* CONFIG_MIPS_MT_SMTC */ TLBMISS_HANDLER_SETUP_PGD(next->pgd); diff --git a/trunk/arch/mips/include/asm/setup.h b/trunk/arch/mips/include/asm/setup.h index 50511aac04e9..e600cedda976 100644 --- a/trunk/arch/mips/include/asm/setup.h +++ b/trunk/arch/mips/include/asm/setup.h @@ -1,7 +1,7 @@ #ifndef _MIPS_SETUP_H #define _MIPS_SETUP_H -#define COMMAND_LINE_SIZE 4096 +#define COMMAND_LINE_SIZE 256 #ifdef __KERNEL__ extern void setup_early_printk(void); diff --git a/trunk/arch/mips/include/asm/smtc_ipi.h b/trunk/arch/mips/include/asm/smtc_ipi.h index 15278dbd7e79..8ce517574340 100644 --- a/trunk/arch/mips/include/asm/smtc_ipi.h +++ b/trunk/arch/mips/include/asm/smtc_ipi.h @@ -45,7 +45,6 @@ struct smtc_ipi_q { spinlock_t lock; struct smtc_ipi *tail; int depth; - int resched_flag; /* reschedule already queued */ }; static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p) diff --git a/trunk/arch/mips/include/asm/spram.h b/trunk/arch/mips/include/asm/spram.h deleted file mode 100644 index 0b89006e4907..000000000000 --- a/trunk/arch/mips/include/asm/spram.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _MIPS_SPRAM_H -#define _MIPS_SPRAM_H - -#ifdef CONFIG_CPU_MIPSR2 -extern __init void spram_config(void); -#else -static inline void spram_config(void) { }; -#endif /* CONFIG_CPU_MIPSR2 */ - -#endif /* _MIPS_SPRAM_H */ diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index 845da2107ed1..01cc1630b66c 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -86,7 +86,14 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL) +#define alloc_thread_info(tsk) \ +({ \ + struct thread_info *ret; \ + \ + ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \ + \ + ret; \ +}) #else #define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) #endif diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index 7bd32d04c2cc..7fd170d007e7 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -134,7 +134,7 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) static struct irqaction r4030_timer_irqaction = { .handler = r4030_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_DISABLED, .name = "R4030 timer", }; diff --git a/trunk/arch/mips/kernel/cevt-bcm1480.c b/trunk/arch/mips/kernel/cevt-bcm1480.c index bfea327c636c..e02f79b1eb51 100644 --- a/trunk/arch/mips/kernel/cevt-bcm1480.c +++ b/trunk/arch/mips/kernel/cevt-bcm1480.c @@ -144,7 +144,7 @@ void __cpuinit sb1480_clockevent_init(void) bcm1480_unmask_irq(cpu, irq); action->handler = sibyte_counter_handler; - action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER; + action->flags = IRQF_DISABLED | IRQF_PERCPU; action->name = name; action->dev_id = cd; diff --git a/trunk/arch/mips/kernel/cevt-ds1287.c b/trunk/arch/mips/kernel/cevt-ds1287.c index 00a4da277cbb..6996da4d74a2 100644 --- a/trunk/arch/mips/kernel/cevt-ds1287.c +++ b/trunk/arch/mips/kernel/cevt-ds1287.c @@ -107,7 +107,7 @@ static irqreturn_t ds1287_interrupt(int irq, void *dev_id) static struct irqaction ds1287_irqaction = { .handler = ds1287_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "ds1287", }; diff --git a/trunk/arch/mips/kernel/cevt-gt641xx.c b/trunk/arch/mips/kernel/cevt-gt641xx.c index f5d265eb6eae..92351e00ae0e 100644 --- a/trunk/arch/mips/kernel/cevt-gt641xx.c +++ b/trunk/arch/mips/kernel/cevt-gt641xx.c @@ -113,7 +113,7 @@ static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id) static struct irqaction gt641xx_timer0_irqaction = { .handler = gt641xx_timer0_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "gt641xx_timer0", }; diff --git a/trunk/arch/mips/kernel/cevt-r4k.c b/trunk/arch/mips/kernel/cevt-r4k.c index b469ad05d520..2652362ce047 100644 --- a/trunk/arch/mips/kernel/cevt-r4k.c +++ b/trunk/arch/mips/kernel/cevt-r4k.c @@ -83,7 +83,7 @@ irqreturn_t c0_compare_interrupt(int irq, void *dev_id) struct irqaction c0_compare_irqaction = { .handler = c0_compare_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "timer", }; diff --git a/trunk/arch/mips/kernel/cevt-sb1250.c b/trunk/arch/mips/kernel/cevt-sb1250.c index da78eeaea6e8..ac5903d1b20e 100644 --- a/trunk/arch/mips/kernel/cevt-sb1250.c +++ b/trunk/arch/mips/kernel/cevt-sb1250.c @@ -143,7 +143,7 @@ void __cpuinit sb1250_clockevent_init(void) sb1250_unmask_irq(cpu, irq); action->handler = sibyte_counter_handler; - action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER; + action->flags = IRQF_DISABLED | IRQF_PERCPU; action->name = name; action->dev_id = cd; diff --git a/trunk/arch/mips/kernel/cevt-txx9.c b/trunk/arch/mips/kernel/cevt-txx9.c index 218ee6bda935..0037f21baf0d 100644 --- a/trunk/arch/mips/kernel/cevt-txx9.c +++ b/trunk/arch/mips/kernel/cevt-txx9.c @@ -146,7 +146,7 @@ static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) static struct irqaction txx9tmr_irq = { .handler = txx9tmr_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "txx9tmr", .dev_id = &txx9_clock_event_device, }; diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 7a51866068a4..f709657e4dcd 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -23,7 +23,7 @@ #include #include #include -#include + /* * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, * the implementation of the "wait" feature differs between CPU families. This @@ -711,6 +711,12 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c) mips_probe_watch_registers(c); } +#ifdef CONFIG_CPU_MIPSR2 +extern void spram_config(void); +#else +static inline void spram_config(void) {} +#endif + static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) { decode_configs(c); diff --git a/trunk/arch/mips/kernel/head.S b/trunk/arch/mips/kernel/head.S index ea695d9605e9..531ce7b16124 100644 --- a/trunk/arch/mips/kernel/head.S +++ b/trunk/arch/mips/kernel/head.S @@ -191,7 +191,6 @@ NESTED(kernel_entry, 16, sp) # kernel entry point /* Set the SP after an empty pt_regs. */ PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE PTR_ADDU sp, $28 - back_to_back_c0_hazard set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer diff --git a/trunk/arch/mips/kernel/i8253.c b/trunk/arch/mips/kernel/i8253.c index ed5c441615e4..f7d8d5d0ddbf 100644 --- a/trunk/arch/mips/kernel/i8253.c +++ b/trunk/arch/mips/kernel/i8253.c @@ -98,7 +98,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, .name = "timer" }; diff --git a/trunk/arch/mips/kernel/irq-gic.c b/trunk/arch/mips/kernel/irq-gic.c index b181f2f0ea8e..d2072cd38592 100644 --- a/trunk/arch/mips/kernel/irq-gic.c +++ b/trunk/arch/mips/kernel/irq-gic.c @@ -14,23 +14,38 @@ static unsigned long _gic_base; -static unsigned int _irqbase; -static unsigned int gic_irq_flags[GIC_NUM_INTRS]; -#define GIC_IRQ_FLAG_EDGE 0x0001 +static unsigned int _irqbase, _mapsize, numvpes, numintrs; +static struct gic_intr_map *_intrmap; -struct gic_pcpu_mask pcpu_masks[NR_CPUS]; +static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; +#define gic_wedgeb2bok 0 /* + * Can GIC handle b2b writes to wedge register? + */ +#if gic_wedgeb2bok == 0 +static DEFINE_SPINLOCK(gic_wedgeb2b_lock); +#endif + void gic_send_ipi(unsigned int intr) { +#if gic_wedgeb2bok == 0 + unsigned long flags; +#endif pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, read_c0_status()); + if (!gic_wedgeb2bok) + spin_lock_irqsave(&gic_wedgeb2b_lock, flags); GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); + if (!gic_wedgeb2bok) { + (void) GIC_REG(SHARED, GIC_SH_CONFIG); + spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags); + } } /* This is Malta specific and needs to be exported */ -static void __init vpe_local_setup(unsigned int numvpes) +static void vpe_local_setup(unsigned int numvpes) { int i; unsigned long timer_interrupt = 5, perf_interrupt = 5; @@ -90,34 +105,44 @@ unsigned int gic_get_int(void) static unsigned int gic_irq_startup(unsigned int irq) { - irq -= _irqbase; pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); - GIC_SET_INTR_MASK(irq); + irq -= _irqbase; + GIC_SET_INTR_MASK(irq, 1); return 0; } static void gic_irq_ack(unsigned int irq) { - irq -= _irqbase; +#if gic_wedgeb2bok == 0 + unsigned long flags; +#endif pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); - GIC_CLR_INTR_MASK(irq); + irq -= _irqbase; + GIC_CLR_INTR_MASK(irq, 1); - if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE) + if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { + if (!gic_wedgeb2bok) + spin_lock_irqsave(&gic_wedgeb2b_lock, flags); GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); + if (!gic_wedgeb2bok) { + (void) GIC_REG(SHARED, GIC_SH_CONFIG); + spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags); + } + } } static void gic_mask_irq(unsigned int irq) { - irq -= _irqbase; pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); - GIC_CLR_INTR_MASK(irq); + irq -= _irqbase; + GIC_CLR_INTR_MASK(irq, 1); } static void gic_unmask_irq(unsigned int irq) { - irq -= _irqbase; pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); - GIC_SET_INTR_MASK(irq); + irq -= _irqbase; + GIC_SET_INTR_MASK(irq, 1); } #ifdef CONFIG_SMP @@ -130,8 +155,9 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) unsigned long flags; int i; + pr_debug(KERN_DEBUG "%s called\n", __func__); irq -= _irqbase; - pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); + cpumask_and(&tmp, cpumask, cpu_online_mask); if (cpus_empty(tmp)) return -1; @@ -142,6 +168,13 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) /* Re-route this IRQ */ GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); + /* + * FIXME: assumption that _intrmap is ordered and has no holes + */ + + /* Update the intr_map */ + _intrmap[irq].cpunum = first_cpu(tmp); + /* Update the pcpu_masks */ for (i = 0; i < NR_CPUS; i++) clear_bit(irq, pcpu_masks[i].pcpu_mask); @@ -168,9 +201,8 @@ static struct irq_chip gic_irq_controller = { #endif }; -static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, - unsigned int pin, unsigned int polarity, unsigned int trigtype, - unsigned int flags) +static void __init setup_intr(unsigned int intr, unsigned int cpu, + unsigned int pin, unsigned int polarity, unsigned int trigtype) { /* Setup Intr to Pin mapping */ if (pin & GIC_MAP_TO_NMI_MSK) { @@ -195,43 +227,38 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, GIC_SET_TRIGGER(intr, trigtype); /* Init Intr Masks */ - GIC_CLR_INTR_MASK(intr); - /* Initialise per-cpu Interrupt software masks */ - if (flags & GIC_FLAG_IPI) - set_bit(intr, pcpu_masks[cpu].pcpu_mask); - if (flags & GIC_FLAG_TRANSPARENT) - GIC_SET_INTR_MASK(intr); - if (trigtype == GIC_TRIG_EDGE) - gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE; + GIC_SET_INTR_MASK(intr, 0); } -static void __init gic_basic_init(int numintrs, int numvpes, - struct gic_intr_map *intrmap, int mapsize) +static void __init gic_basic_init(void) { unsigned int i, cpu; /* Setup defaults */ - for (i = 0; i < numintrs; i++) { + for (i = 0; i < GIC_NUM_INTRS; i++) { GIC_SET_POLARITY(i, GIC_POL_POS); GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); - GIC_CLR_INTR_MASK(i); - if (i < GIC_NUM_INTRS) - gic_irq_flags[i] = 0; + GIC_SET_INTR_MASK(i, 0); } /* Setup specifics */ - for (i = 0; i < mapsize; i++) { - cpu = intrmap[i].cpunum; + for (i = 0; i < _mapsize; i++) { + cpu = _intrmap[i].cpunum; if (cpu == X) continue; - if (cpu == 0 && i != 0 && intrmap[i].flags == 0) + + if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 && + _intrmap[i].ipiflag == 0) continue; - gic_setup_intr(i, - intrmap[i].cpunum, - intrmap[i].pin, - intrmap[i].polarity, - intrmap[i].trigtype, - intrmap[i].flags); + + setup_intr(_intrmap[i].intrnum, + _intrmap[i].cpunum, + _intrmap[i].pin, + _intrmap[i].polarity, + _intrmap[i].trigtype); + /* Initialise per-cpu Interrupt software masks */ + if (_intrmap[i].ipiflag) + set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask); } vpe_local_setup(numvpes); @@ -246,11 +273,12 @@ void __init gic_init(unsigned long gic_base_addr, unsigned int irqbase) { unsigned int gicconfig; - int numvpes, numintrs; _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, gic_addrspace_size); _irqbase = irqbase; + _intrmap = intr_map; + _mapsize = intr_map_size; GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> @@ -262,5 +290,5 @@ void __init gic_init(unsigned long gic_base_addr, pr_debug("%s called\n", __func__); - gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); + gic_basic_init(); } diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index b77fefaff9da..6242bc68add7 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -428,9 +428,3 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } - -asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf, - size_t len) -{ - return sys_lookup_dcookie(merge_64(a0, a1), buf, len); -} diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 14dde4ca932e..9bbf9775e0bd 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -450,7 +450,7 @@ sys_call_table: PTR sys_io_submit PTR sys_io_cancel /* 4245 */ PTR sys_exit_group - PTR sys32_lookup_dcookie + PTR sys_lookup_dcookie PTR sys_epoll_create PTR sys_epoll_ctl PTR sys_epoll_wait /* 4250 */ @@ -505,7 +505,7 @@ sys_call_table: PTR sys_fchmodat PTR sys_faccessat /* 4300 */ PTR compat_sys_pselect6 - PTR compat_sys_ppoll + PTR sys_ppoll PTR sys_unshare PTR sys_splice PTR sys32_sync_file_range /* 4305 */ diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 24630fd8ef60..4d181df44a40 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -75,6 +75,7 @@ unsigned long irq_hwmask[NR_IRQS]; asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; + /* * Number of InterProcessor Interrupt (IPI) message buffers to allocate */ @@ -387,7 +388,6 @@ void smtc_prepare_cpus(int cpus) IPIQ[i].head = IPIQ[i].tail = NULL; spin_lock_init(&IPIQ[i].lock); IPIQ[i].depth = 0; - IPIQ[i].resched_flag = 0; /* No reschedules queued initially */ } /* cpu_data index starts at zero */ @@ -741,24 +741,11 @@ void smtc_forward_irq(unsigned int irq) static void smtc_ipi_qdump(void) { int i; - struct smtc_ipi *temp; for (i = 0; i < NR_CPUS ;i++) { - pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", + printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail, IPIQ[i].depth); - temp = IPIQ[i].head; - - while (temp != IPIQ[i].tail) { - pr_debug("%d %d %d: ", temp->type, temp->dest, - (int)temp->arg); -#ifdef SMTC_IPI_DEBUG - pr_debug("%u %lu\n", temp->sender, temp->stamp); -#else - pr_debug("\n"); -#endif - temp = temp->flink; - } } } @@ -797,16 +784,11 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) int mtflags; unsigned long tcrestart; extern void r4k_wait_irqoff(void), __pastwait(void); - int set_resched_flag = (type == LINUX_SMP_IPI && - action == SMP_RESCHEDULE_YOURSELF); if (cpu == smp_processor_id()) { printk("Cannot Send IPI to self!\n"); return; } - if (set_resched_flag && IPIQ[cpu].resched_flag != 0) - return; /* There is a reschedule queued already */ - /* Set up a descriptor, to be delivered either promptly or queued */ pipi = smtc_ipi_dq(&freeIPIq); if (pipi == NULL) { @@ -819,7 +801,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) pipi->dest = cpu; if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { /* If not on same VPE, enqueue and send cross-VPE interrupt */ - IPIQ[cpu].resched_flag |= set_resched_flag; smtc_ipi_nq(&IPIQ[cpu], pipi); LOCK_CORE_PRA(); settc(cpu_data[cpu].tc_id); @@ -866,7 +847,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) */ write_tc_c0_tchalt(0); UNLOCK_CORE_PRA(); - IPIQ[cpu].resched_flag |= set_resched_flag; smtc_ipi_nq(&IPIQ[cpu], pipi); } else { postdirect: @@ -1016,15 +996,12 @@ void deferred_smtc_ipi(void) * already enabled. */ local_irq_save(flags); + spin_lock(&q->lock); pipi = __smtc_ipi_dq(q); spin_unlock(&q->lock); - if (pipi != NULL) { - if (pipi->type == LINUX_SMP_IPI && - (int)pipi->arg == SMP_RESCHEDULE_YOURSELF) - IPIQ[cpu].resched_flag = 0; + if (pipi != NULL) ipi_decode(pipi); - } /* * The use of the __raw_local restore isn't * as obviously necessary here as in smtc_ipi_replay(), @@ -1105,9 +1082,6 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) * with interrupts off */ local_irq_save(flags); - if (pipi->type == LINUX_SMP_IPI && - (int)pipi->arg == SMP_RESCHEDULE_YOURSELF) - IPIQ[cpu].resched_flag = 0; ipi_decode(pipi); local_irq_restore(flags); } diff --git a/trunk/arch/mips/kernel/spram.c b/trunk/arch/mips/kernel/spram.c index 1821d12a6410..6ddb507a87ef 100644 --- a/trunk/arch/mips/kernel/spram.c +++ b/trunk/arch/mips/kernel/spram.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -197,7 +198,8 @@ static __cpuinit void probe_spram(char *type, offset += 2 * SPRAM_TAG_STRIDE; } } -void __cpuinit spram_config(void) + +__cpuinit void spram_config(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config0; @@ -206,7 +208,6 @@ void __cpuinit spram_config(void) case CPU_24K: case CPU_34K: case CPU_74K: - case CPU_1004K: config0 = read_c0_config(); /* FIXME: addresses are Malta specific */ if (config0 & (1<<24)) { diff --git a/trunk/arch/mips/kernel/vpe.c b/trunk/arch/mips/kernel/vpe.c index 60477529362e..03092ab2a296 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -1116,6 +1116,8 @@ static int vpe_open(struct inode *inode, struct file *filp) v->shared_ptr = NULL; v->__start = 0; + unlock_kernel(); + return 0; } diff --git a/trunk/arch/mips/loongson/common/irq.c b/trunk/arch/mips/loongson/common/irq.c index b32b4a3e5137..f368c735cbd3 100644 --- a/trunk/arch/mips/loongson/common/irq.c +++ b/trunk/arch/mips/loongson/common/irq.c @@ -55,6 +55,7 @@ void __init arch_init_irq(void) * int-handler is not on bootstrap */ clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); /* setting irq trigger mode */ set_irq_trigger_mode(); diff --git a/trunk/arch/mips/math-emu/dp_simple.c b/trunk/arch/mips/math-emu/dp_simple.c index d9ae1dbabda7..1c555e6c6a9f 100644 --- a/trunk/arch/mips/math-emu/dp_simple.c +++ b/trunk/arch/mips/math-emu/dp_simple.c @@ -62,6 +62,8 @@ ieee754dp ieee754dp_neg(ieee754dp x) return ieee754dp_nanxcpt(y, "neg"); } + if (ieee754dp_isnan(x)) /* but not infinity */ + return ieee754dp_nanxcpt(x, "neg", x); return x; } @@ -74,12 +76,15 @@ ieee754dp ieee754dp_abs(ieee754dp x) CLEARCX; FLUSHXDP; - /* Clear sign ALWAYS, irrespective of NaN */ - DPSIGN(x) = 0; - if (xc == IEEE754_CLASS_SNAN) { - return ieee754dp_nanxcpt(ieee754dp_indef(), "abs"); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); } + if (ieee754dp_isnan(x)) /* but not infinity */ + return ieee754dp_nanxcpt(x, "abs", x); + + /* quick fix up */ + DPSIGN(x) = 0; return x; } diff --git a/trunk/arch/mips/math-emu/sp_simple.c b/trunk/arch/mips/math-emu/sp_simple.c index 3175477d36f6..770f0f4677cd 100644 --- a/trunk/arch/mips/math-emu/sp_simple.c +++ b/trunk/arch/mips/math-emu/sp_simple.c @@ -62,6 +62,8 @@ ieee754sp ieee754sp_neg(ieee754sp x) return ieee754sp_nanxcpt(y, "neg"); } + if (ieee754sp_isnan(x)) /* but not infinity */ + return ieee754sp_nanxcpt(x, "neg", x); return x; } @@ -74,12 +76,15 @@ ieee754sp ieee754sp_abs(ieee754sp x) CLEARCX; FLUSHXSP; - /* Clear sign ALWAYS, irrespective of NaN */ - SPSIGN(x) = 0; - if (xc == IEEE754_CLASS_SNAN) { + SETCX(IEEE754_INVALID_OPERATION); return ieee754sp_nanxcpt(ieee754sp_indef(), "abs"); } + if (ieee754sp_isnan(x)) /* but not infinity */ + return ieee754sp_nanxcpt(x, "abs", x); + + /* quick fix up */ + SPSIGN(x) = 0; return x; } diff --git a/trunk/arch/mips/mm/init.c b/trunk/arch/mips/mm/init.c index 8d1f4f363049..15aa1902a788 100644 --- a/trunk/arch/mips/mm/init.c +++ b/trunk/arch/mips/mm/init.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -133,10 +132,7 @@ void *kmap_coherent(struct page *page, unsigned long addr) inc_preempt_count(); idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); #ifdef CONFIG_MIPS_MT_SMTC - idx += FIX_N_COLOURS * smp_processor_id() + - (in_interrupt() ? (FIX_N_COLOURS * NR_CPUS) : 0); -#else - idx += in_interrupt() ? FIX_N_COLOURS : 0; + idx += FIX_N_COLOURS * smp_processor_id(); #endif vaddr = __fix_to_virt(FIX_CMAP_END - idx); pte = mk_pte(page, PAGE_KERNEL); diff --git a/trunk/arch/mips/mti-malta/malta-amon.c b/trunk/arch/mips/mti-malta/malta-amon.c index 469d9b0cee6d..df9e526312a2 100644 --- a/trunk/arch/mips/mti-malta/malta-amon.c +++ b/trunk/arch/mips/mti-malta/malta-amon.c @@ -70,12 +70,11 @@ void amon_cpu_start(int cpu, launch->sp = sp; launch->a0 = a0; - smp_wmb(); /* Target must see parameters before go */ - launch->flags |= LAUNCH_FGO; - smp_wmb(); /* Target must see go before we poll */ + /* Make sure target sees parameters before the go bit */ + smp_mb(); + launch->flags |= LAUNCH_FGO; while ((launch->flags & LAUNCH_FGONE) == 0) ; - smp_rmb(); /* Target will be updating flags soon */ pr_debug("launch: cpu%d gone!\n", cpu); } diff --git a/trunk/arch/mips/mti-malta/malta-int.c b/trunk/arch/mips/mti-malta/malta-int.c index 4c3fca18a171..3e0a9b35ba5c 100644 --- a/trunk/arch/mips/mti-malta/malta-int.c +++ b/trunk/arch/mips/mti-malta/malta-int.c @@ -87,7 +87,7 @@ static inline int mips_pcibios_iack(void) dummy = BONITO_PCIMAP_CFG; iob(); /* sync */ - irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); + irq = readl((u32 *)_pcictrl_bonito_pcicfg); iob(); /* sync */ irq &= 0xff; BONITO_PCIMAP_CFG = 0; @@ -379,43 +379,38 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = { static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); +#if defined(CONFIG_MIPS_MT_SMP) /* * This GIC specific tabular array defines the association between External * Interrupts and CPUs/Core Interrupts. The nature of the External * Interrupts is also defined here - polarity/trigger. */ - -#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { - { X, X, X, X, 0 }, - { X, X, X, X, 0 }, - { X, X, X, X, 0 }, - { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { X, X, X, X, 0 }, - { X, X, X, X, 0 }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { X, X, X, X, 0 }, - /* The remainder of this table is initialised by fill_ipi_map */ + { GIC_EXT_INTR(0), X, X, X, X, 0 }, + { GIC_EXT_INTR(1), X, X, X, X, 0 }, + { GIC_EXT_INTR(2), X, X, X, X, 0 }, + { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(10), X, X, X, X, 0 }, + { GIC_EXT_INTR(11), X, X, X, X, 0 }, + { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(15), X, X, X, X, 0 }, +/* This is the end of the general interrupts now we do IPI ones */ }; +#endif /* * GCMP needs to be detected before any SMP initialisation */ int __init gcmp_probe(unsigned long addr, unsigned long size) { - if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) { - gcmp_present = 0; - return gcmp_present; - } - if (gcmp_present >= 0) return gcmp_present; @@ -424,35 +419,20 @@ int __init gcmp_probe(unsigned long addr, unsigned long size) gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; if (gcmp_present) - pr_debug("GCMP present\n"); + printk(KERN_DEBUG "GCMP present\n"); return gcmp_present; } -/* Return the number of IOCU's present */ -int __init gcmp_niocu(void) -{ - return gcmp_present ? - (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF : - 0; -} - -/* Set GCMP region attributes */ -void __init gcmp_setregion(int region, unsigned long base, - unsigned long mask, int type) -{ - GCMPGCBn(CMxBASE, region) = base; - GCMPGCBn(CMxMASK, region) = mask | type; -} - #if defined(CONFIG_MIPS_MT_SMP) static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) { int intr = baseintr + cpu; + gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr); gic_intr_map[intr].cpunum = cpu; gic_intr_map[intr].pin = cpupin; gic_intr_map[intr].polarity = GIC_POL_POS; gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; - gic_intr_map[intr].flags = GIC_FLAG_IPI; + gic_intr_map[intr].ipiflag = 1; ipi_map[cpu] |= (1 << (cpupin + 2)); } @@ -467,12 +447,6 @@ static void __init fill_ipi_map(void) } #endif -void __init arch_init_ipiirq(int irq, struct irqaction *action) -{ - setup_irq(irq, action); - set_irq_handler(irq, handle_percpu_irq); -} - void __init arch_init_irq(void) { init_i8259_irqs(); @@ -484,17 +458,12 @@ void __init arch_init_irq(void) GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; } else { - if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { - _msc01_biu_base = (unsigned long) - ioremap_nocache(MSC01_BIU_REG_BASE, - MSC01_BIU_ADDRSPACE_SZ); - gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & - MSC01_SC_CFG_GICPRES_MSK) >> - MSC01_SC_CFG_GICPRES_SHF; - } + _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); + gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & + MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; } if (gic_present) - pr_debug("GIC present\n"); + printk(KERN_DEBUG "GIC present\n"); switch (mips_revision_sconid) { case MIPS_REVISION_SCON_SOCIT: @@ -557,16 +526,16 @@ void __init arch_init_irq(void) &corehi_irqaction); } +#if defined(CONFIG_MIPS_MT_SMP) if (gic_present) { /* FIXME */ int i; -#if defined(CONFIG_MIPS_MT_SMP) + gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; gic_resched_int_base = gic_call_int_base - NR_CPUS; + fill_ipi_map(); -#endif - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, - ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); + gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); if (!gcmp_present) { /* Enable the GIC */ i = REG(_msc01_biu_base, MSC01_SC_CFG); @@ -574,7 +543,7 @@ void __init arch_init_irq(void) (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); pr_debug("GIC Enabled\n"); } -#if defined(CONFIG_MIPS_MT_SMP) + /* set up ipi interrupts */ if (cpu_has_vint) { set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); @@ -587,14 +556,16 @@ void __init arch_init_irq(void) write_c0_status(0x1100dc00); printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); for (i = 0; i < NR_CPUS; i++) { - arch_init_ipiirq(MIPS_GIC_IRQ_BASE + - GIC_RESCHED_INT(i), &irq_resched); - arch_init_ipiirq(MIPS_GIC_IRQ_BASE + - GIC_CALL_INT(i), &irq_call); + setup_irq(MIPS_GIC_IRQ_BASE + + GIC_RESCHED_INT(i), &irq_resched); + setup_irq(MIPS_GIC_IRQ_BASE + + GIC_CALL_INT(i), &irq_call); + set_irq_handler(MIPS_GIC_IRQ_BASE + + GIC_RESCHED_INT(i), handle_percpu_irq); + set_irq_handler(MIPS_GIC_IRQ_BASE + + GIC_CALL_INT(i), handle_percpu_irq); } -#endif } else { -#if defined(CONFIG_MIPS_MT_SMP) /* set up ipi interrupts */ if (cpu_has_veic) { set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); @@ -609,10 +580,14 @@ void __init arch_init_irq(void) cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; } - arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); - arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); -#endif + + setup_irq(cpu_ipi_resched_irq, &irq_resched); + setup_irq(cpu_ipi_call_irq, &irq_call); + + set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); + set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); } +#endif } void malta_be_init(void) diff --git a/trunk/arch/mips/mti-malta/malta-pci.c b/trunk/arch/mips/mti-malta/malta-pci.c index 2fbfa1a8c3a9..b9743190609a 100644 --- a/trunk/arch/mips/mti-malta/malta-pci.c +++ b/trunk/arch/mips/mti-malta/malta-pci.c @@ -27,7 +27,7 @@ #include #include -#include + #include #include #include @@ -201,11 +201,7 @@ void __init mips_pcibios_init(void) msc_mem_resource.start = start & mask; msc_mem_resource.end = (start & mask) | ~mask; msc_controller.mem_offset = (start & mask) - (map & mask); -#ifdef CONFIG_MIPS_CMP - if (gcmp_niocu()) - gcmp_setregion(0, start, mask, - GCMP_GCB_GCMPB_CMDEFTGT_IOCU1); -#endif + MSC_READ(MSC01_PCI_SC2PIOBASL, start); MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); MSC_READ(MSC01_PCI_SC2PIOMAPL, map); @@ -213,11 +209,7 @@ void __init mips_pcibios_init(void) msc_io_resource.end = (map & mask) | ~mask; msc_controller.io_offset = 0; ioport_resource.end = ~mask; -#ifdef CONFIG_MIPS_CMP - if (gcmp_niocu()) - gcmp_setregion(1, start, mask, - GCMP_GCB_GCMPB_CMDEFTGT_IOCU1); -#endif + /* If ranges overlap I/O takes precedence. */ start = start & mask; end = start | ~mask; @@ -249,16 +241,3 @@ void __init mips_pcibios_init(void) register_pci_controller(controller); } - -/* Enable PCI 2.1 compatibility in PIIX4 */ -static void __init quirk_dlcsetup(struct pci_dev *dev) -{ - u8 odlc, ndlc; - (void) pci_read_config_byte(dev, 0x82, &odlc); - /* Enable passive releases and delayed transaction */ - ndlc = odlc | 7; - (void) pci_write_config_byte(dev, 0x82, ndlc); -} - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, - quirk_dlcsetup); diff --git a/trunk/arch/mips/nxp/pnx8550/common/int.c b/trunk/arch/mips/nxp/pnx8550/common/int.c index 7aca7d5375e5..f080f114a1bf 100644 --- a/trunk/arch/mips/nxp/pnx8550/common/int.c +++ b/trunk/arch/mips/nxp/pnx8550/common/int.c @@ -172,7 +172,7 @@ static struct irqaction gic_action = { static struct irqaction timer_action = { .handler = no_action, - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_DISABLED, .name = "Timer", }; diff --git a/trunk/arch/mips/nxp/pnx8550/common/time.c b/trunk/arch/mips/nxp/pnx8550/common/time.c index 8836c6203df0..18b192784877 100644 --- a/trunk/arch/mips/nxp/pnx8550/common/time.c +++ b/trunk/arch/mips/nxp/pnx8550/common/time.c @@ -59,7 +59,7 @@ static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id) static struct irqaction pnx8xxx_timer_irq = { .handler = pnx8xxx_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "pnx8xxx_timer", }; @@ -72,7 +72,7 @@ static irqreturn_t monotonic_interrupt(int irq, void *dev_id) static struct irqaction monotonic_irqaction = { .handler = monotonic_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_DISABLED, .name = "Monotonic timer", }; diff --git a/trunk/arch/mips/oprofile/op_model_loongson2.c b/trunk/arch/mips/oprofile/op_model_loongson2.c index 575cd1473475..deed1d5d4982 100644 --- a/trunk/arch/mips/oprofile/op_model_loongson2.c +++ b/trunk/arch/mips/oprofile/op_model_loongson2.c @@ -22,7 +22,7 @@ * otherwise, the oprofile tool will not recognize this and complain about * "cpu_type 'unset' is not valid". */ -#define LOONGSON2_CPU_TYPE "mips/loongson2" +#define LOONGSON2_CPU_TYPE "mips/godson2" #define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5) #define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9) diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index d6802d6d1f82..6d0e59ffba2e 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -105,7 +105,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) struct irqaction hub_rt_irqaction = { .handler = hub_rt_counter_handler, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "hub-rt", }; diff --git a/trunk/arch/mips/sni/time.c b/trunk/arch/mips/sni/time.c index f3b60e671207..62df6a598e0a 100644 --- a/trunk/arch/mips/sni/time.c +++ b/trunk/arch/mips/sni/time.c @@ -67,7 +67,7 @@ static irqreturn_t a20r_interrupt(int irq, void *dev_id) static struct irqaction a20r_irqaction = { .handler = a20r_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "a20r-timer", }; diff --git a/trunk/arch/mips/txx9/generic/setup.c b/trunk/arch/mips/txx9/generic/setup.c index e10184c1b3e1..c860810722c0 100644 --- a/trunk/arch/mips/txx9/generic/setup.c +++ b/trunk/arch/mips/txx9/generic/setup.c @@ -85,7 +85,7 @@ int txx9_ccfg_toeon __initdata = 1; struct clk *clk_get(struct device *dev, const char *id) { if (!strcmp(id, "spi-baseclk")) - return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2); + return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 4); if (!strcmp(id, "imbus_clk")) return (struct clk *)((unsigned long)txx9_gbus_clock / 2); return ERR_PTR(-ENOENT); @@ -817,8 +817,7 @@ void __init txx9_iocled_init(unsigned long baseaddr, out_pdev: platform_device_put(pdev); out_gpio: - if (gpiochip_remove(&iocled->chip)) - return; + gpio_remove(&iocled->chip); out_unmap: iounmap(iocled->mmioaddr); out_free: diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 10a0a5488a44..2ba14e77296c 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -414,6 +414,10 @@ config ARCH_SPARSEMEM_DEFAULT config ARCH_POPULATES_NODE_MAP def_bool y +config SYS_SUPPORTS_HUGETLBFS + def_bool y + depends on PPC_BOOK3S_64 + source "mm/Kconfig" config ARCH_MEMORY_PROBE diff --git a/trunk/arch/s390/include/asm/cputime.h b/trunk/arch/s390/include/asm/cputime.h index f23961ada7fb..24b1244aadb9 100644 --- a/trunk/arch/s390/include/asm/cputime.h +++ b/trunk/arch/s390/include/asm/cputime.h @@ -78,7 +78,7 @@ cputime64_to_jiffies64(cputime64_t cputime) static inline unsigned int cputime_to_msecs(const cputime_t cputime) { - return cputime_div(cputime, 4096000); + return __div(cputime, 4096000); } static inline cputime_t @@ -160,7 +160,7 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value) static inline clock_t cputime_to_clock_t(cputime_t cputime) { - return cputime_div(cputime, 4096000000ULL / USER_HZ); + return __div(cputime, 4096000000ULL / USER_HZ); } static inline cputime_t @@ -175,7 +175,7 @@ clock_t_to_cputime(unsigned long x) static inline clock_t cputime64_to_clock_t(cputime64_t cputime) { - return cputime_div(cputime, 4096000000ULL / USER_HZ); + return __div(cputime, 4096000000ULL / USER_HZ); } struct s390_idle_data { diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c index 4890ac6d7faa..ee57a42e6e93 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -1595,9 +1595,10 @@ static void stop_run(struct shutdown_trigger *trigger) { if (strcmp(trigger->name, ON_PANIC_STR) == 0) disabled_wait((unsigned long) __builtin_return_address(0)); - while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) - cpu_relax(); - for (;;); + else { + signal_processor(smp_processor_id(), sigp_stop); + for (;;); + } } static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR, diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 93e52039321b..c932caa5e850 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -76,6 +76,7 @@ static int cpu_stopped(int cpu) __u32 status; switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { + case sigp_order_code_accepted: case sigp_status_stored: /* Check for stopped and check stop state */ if (status & 0x50) @@ -637,8 +638,6 @@ void __cpu_die(unsigned int cpu) /* Wait until target cpu is down */ while (!cpu_stopped(cpu)) cpu_relax(); - while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy) - udelay(10); smp_free_lowcore(cpu); pr_info("Processor %d stopped\n", cpu); } @@ -646,8 +645,8 @@ void __cpu_die(unsigned int cpu) void cpu_die(void) { idle_task_exit(); - while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) - cpu_relax(); + signal_processor(smp_processor_id(), sigp_stop); + BUG(); for (;;); } diff --git a/trunk/arch/s390/kernel/swsusp_asm64.S b/trunk/arch/s390/kernel/swsusp_asm64.S index 0c26cc1898ec..7c8653e27db6 100644 --- a/trunk/arch/s390/kernel/swsusp_asm64.S +++ b/trunk/arch/s390/kernel/swsusp_asm64.S @@ -199,7 +199,6 @@ pgm_check_entry: brc 2,4b /* busy, try again */ 5: sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */ - brc 2,5b /* busy, try again */ 6: j 6b restart_suspend: @@ -207,7 +206,6 @@ restart_suspend: llgh %r2,0(%r1) 7: sigp %r9,%r2,__SIGP_SENSE /* Wait for resume CPU */ - brc 8,7b /* accepted, status 0, still running */ brc 2,7b /* busy, try again */ tmll %r9,0x40 /* Test if resume CPU is stopped */ jz 7b diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 72ace9515a07..07e01149e3bf 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1443,8 +1443,12 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config CC_STACKPROTECTOR_ALL + bool + config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" + select CC_STACKPROTECTOR_ALL ---help--- This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of functions, a canary value on diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index 2649840d888f..f2824fb8c79c 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -400,7 +400,7 @@ config X86_TSC config X86_CMPXCHG64 def_bool y - depends on !M386 && !M486 + depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM # this should be set for all -march=.. options where the compiler # generates cmov. diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index d2d24c9ee64d..a012ee8ef803 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -76,6 +76,7 @@ ifdef CONFIG_CC_STACKPROTECTOR cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y) stackp-y := -fstack-protector + stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all KBUILD_CFLAGS += $(stackp-y) else $(warning stack protector enabled but no compiler support) diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index 581b0568fe19..1733f9f65e82 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -204,7 +204,7 @@ sysexit_from_sys_call: movl RDI-ARGOFFSET(%rsp),%r8d /* reload 5th syscall arg */ .endm - .macro auditsys_exit exit + .macro auditsys_exit exit,ebpsave=RBP testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) jnz ia32_ret_from_sys_call TRACE_IRQS_ON @@ -217,6 +217,7 @@ sysexit_from_sys_call: call audit_syscall_exit GET_THREAD_INFO(%r10) movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall return value */ + movl \ebpsave-ARGOFFSET(%rsp),%ebp /* reload user register value */ movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi cli TRACE_IRQS_OFF @@ -350,7 +351,7 @@ cstar_auditsys: jmp cstar_dispatch sysretl_audit: - auditsys_exit sysretl_from_sys_call + auditsys_exit sysretl_from_sys_call, RCX /* user %ebp in RCX slot */ #endif cstar_tracesys: diff --git a/trunk/arch/x86/include/asm/amd_iommu.h b/trunk/arch/x86/include/asm/amd_iommu.h index 4b180897e6b5..ac95995b7bad 100644 --- a/trunk/arch/x86/include/asm/amd_iommu.h +++ b/trunk/arch/x86/include/asm/amd_iommu.h @@ -31,7 +31,6 @@ extern irqreturn_t amd_iommu_int_handler(int irq, void *data); extern void amd_iommu_flush_all_domains(void); extern void amd_iommu_flush_all_devices(void); extern void amd_iommu_shutdown(void); -extern void amd_iommu_apply_erratum_63(u16 devid); #else static inline int amd_iommu_init(void) { return -ENODEV; } static inline void amd_iommu_detect(void) { } diff --git a/trunk/arch/x86/include/asm/desc.h b/trunk/arch/x86/include/asm/desc.h index 617bd56b3070..e8de2f6f5ca5 100644 --- a/trunk/arch/x86/include/asm/desc.h +++ b/trunk/arch/x86/include/asm/desc.h @@ -288,7 +288,7 @@ static inline void load_LDT(mm_context_t *pc) static inline unsigned long get_desc_base(const struct desc_struct *desc) { - return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24)); + return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); } static inline void set_desc_base(struct desc_struct *desc, unsigned long base) diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h index c9786480f0fe..c3429e8b2424 100644 --- a/trunk/arch/x86/include/asm/processor.h +++ b/trunk/arch/x86/include/asm/processor.h @@ -1000,7 +1000,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) -extern unsigned long KSTK_ESP(struct task_struct *task); +#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ #endif /* CONFIG_X86_64 */ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, diff --git a/trunk/arch/x86/include/asm/topology.h b/trunk/arch/x86/include/asm/topology.h index 40e37b10c6c0..d823c245f63b 100644 --- a/trunk/arch/x86/include/asm/topology.h +++ b/trunk/arch/x86/include/asm/topology.h @@ -143,7 +143,7 @@ extern unsigned long node_remap_size[]; | 1*SD_BALANCE_FORK \ | 0*SD_BALANCE_WAKE \ | 1*SD_WAKE_AFFINE \ - | 0*SD_PREFER_LOCAL \ + | 1*SD_PREFER_LOCAL \ | 0*SD_SHARE_CPUPOWER \ | 0*SD_POWERSAVINGS_BALANCE \ | 0*SD_SHARE_PKG_RESOURCES \ diff --git a/trunk/arch/x86/kernel/amd_iommu.c b/trunk/arch/x86/kernel/amd_iommu.c index 0285521e0a99..98f230f6a28d 100644 --- a/trunk/arch/x86/kernel/amd_iommu.c +++ b/trunk/arch/x86/kernel/amd_iommu.c @@ -1220,8 +1220,6 @@ static void __detach_device(struct protection_domain *domain, u16 devid) amd_iommu_dev_table[devid].data[1] = 0; amd_iommu_dev_table[devid].data[2] = 0; - amd_iommu_apply_erratum_63(devid); - /* decrease reference counter */ domain->dev_cnt -= 1; diff --git a/trunk/arch/x86/kernel/amd_iommu_init.c b/trunk/arch/x86/kernel/amd_iommu_init.c index c20001e4f556..b4b61d462dcc 100644 --- a/trunk/arch/x86/kernel/amd_iommu_init.c +++ b/trunk/arch/x86/kernel/amd_iommu_init.c @@ -240,7 +240,7 @@ static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit) writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET); } -static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit) +static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit) { u32 ctrl; @@ -519,26 +519,6 @@ static void set_dev_entry_bit(u16 devid, u8 bit) amd_iommu_dev_table[devid].data[i] |= (1 << _bit); } -static int get_dev_entry_bit(u16 devid, u8 bit) -{ - int i = (bit >> 5) & 0x07; - int _bit = bit & 0x1f; - - return (amd_iommu_dev_table[devid].data[i] & (1 << _bit)) >> _bit; -} - - -void amd_iommu_apply_erratum_63(u16 devid) -{ - int sysmgt; - - sysmgt = get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT1) | - (get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT2) << 1); - - if (sysmgt == 0x01) - set_dev_entry_bit(devid, DEV_ENTRY_IW); -} - /* Writes the specific IOMMU for a device into the rlookup table */ static void __init set_iommu_for_device(struct amd_iommu *iommu, u16 devid) { @@ -567,8 +547,6 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu, if (flags & ACPI_DEVFLAG_LINT1) set_dev_entry_bit(devid, DEV_ENTRY_LINT1_PASS); - amd_iommu_apply_erratum_63(devid); - set_iommu_for_device(iommu, devid); } diff --git a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c index 73c86db5acbe..315738c74aad 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -846,7 +846,7 @@ int __init mtrr_cleanup(unsigned address_bits) sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); range_sums = sum_ranges(range, nr_range); - printk(KERN_INFO "total RAM covered: %ldM\n", + printk(KERN_INFO "total RAM coverred: %ldM\n", range_sums >> (20 - PAGE_SHIFT)); if (mtrr_chunk_size && mtrr_gran_size) { diff --git a/trunk/arch/x86/kernel/crash_dump_32.c b/trunk/arch/x86/kernel/crash_dump_32.c index cd97ce18c29d..f7cdb3b457aa 100644 --- a/trunk/arch/x86/kernel/crash_dump_32.c +++ b/trunk/arch/x86/kernel/crash_dump_32.c @@ -16,22 +16,6 @@ static void *kdump_buf_page; /* Stores the physical address of elf header of crash image. */ unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; -static inline bool is_crashed_pfn_valid(unsigned long pfn) -{ -#ifndef CONFIG_X86_PAE - /* - * non-PAE kdump kernel executed from a PAE one will crop high pte - * bits and poke unwanted space counting again from address 0, we - * don't want that. pte must fit into unsigned long. In fact the - * test checks high 12 bits for being zero (pfn will be shifted left - * by PAGE_SHIFT). - */ - return pte_pfn(pfn_pte(pfn, __pgprot(0))) == pfn; -#else - return true; -#endif -} - /** * copy_oldmem_page - copy one page from "oldmem" * @pfn: page frame number to be copied @@ -57,9 +41,6 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - if (!is_crashed_pfn_valid(pfn)) - return -EFAULT; - vaddr = kmap_atomic_pfn(pfn, KM_PTE0); if (!userbuf) { diff --git a/trunk/arch/x86/kernel/efi.c b/trunk/arch/x86/kernel/efi.c index cdcfb122f256..ad5bd988fb79 100644 --- a/trunk/arch/x86/kernel/efi.c +++ b/trunk/arch/x86/kernel/efi.c @@ -454,10 +454,8 @@ void __init efi_init(void) if (add_efi_memmap) do_add_efi_memmap(); -#ifdef CONFIG_X86_32 x86_platform.get_wallclock = efi_get_time; x86_platform.set_wallclock = efi_set_rtc_mmss; -#endif /* Setup for EFI runtime service */ reboot_type = BOOT_EFI; diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index eb62cbcaa490..ad535b683170 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -664,8 +664,3 @@ long sys_arch_prctl(int code, unsigned long addr) return do_arch_prctl(current, code, addr); } -unsigned long KSTK_ESP(struct task_struct *task) -{ - return (test_tsk_thread_flag(task, TIF_IA32)) ? - (task_pt_regs(task)->sp) : ((task)->thread.usersp); -} diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c index f93078746e00..a1a3cdda06e1 100644 --- a/trunk/arch/x86/kernel/reboot.c +++ b/trunk/arch/x86/kernel/reboot.c @@ -436,14 +436,6 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"), }, }, - { /* Handle problems with rebooting on Apple Macmini3,1 */ - .callback = set_pci_reboot, - .ident = "Apple Macmini3,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"), - }, - }, { } }; diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index dfbf70e65860..23a4d80fb39e 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -178,7 +178,6 @@ static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; static void xen_cpuid(unsigned int *ax, unsigned int *bx, unsigned int *cx, unsigned int *dx) { - unsigned maskebx = ~0; unsigned maskecx = ~0; unsigned maskedx = ~0; @@ -186,16 +185,9 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, * Mask out inconvenient features, to try and disable as many * unsupported kernel subsystems as possible. */ - switch (*ax) { - case 1: + if (*ax == 1) { maskecx = cpuid_leaf1_ecx_mask; maskedx = cpuid_leaf1_edx_mask; - break; - - case 0xb: - /* Suppress extended topology stuff */ - maskebx = 0; - break; } asm(XEN_EMULATE_PREFIX "cpuid" @@ -205,7 +197,6 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, "=d" (*dx) : "0" (*ax), "2" (*cx)); - *bx &= maskebx; *cx &= maskecx; *dx &= maskedx; } diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index aa1e9535e358..069a61017c02 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -196,7 +196,6 @@ enum cfqq_state_flags { CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ CFQ_CFQQ_FLAG_sync, /* synchronous queue */ CFQ_CFQQ_FLAG_coop, /* has done a coop jump of the queue */ - CFQ_CFQQ_FLAG_coop_preempt, /* coop preempt */ }; #define CFQ_CFQQ_FNS(name) \ @@ -223,7 +222,6 @@ CFQ_CFQQ_FNS(prio_changed); CFQ_CFQQ_FNS(slice_new); CFQ_CFQQ_FNS(sync); CFQ_CFQQ_FNS(coop); -CFQ_CFQQ_FNS(coop_preempt); #undef CFQ_CFQQ_FNS #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ @@ -947,13 +945,10 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd, { if (!cfqq) { cfqq = cfq_get_next_queue(cfqd); - if (cfqq && !cfq_cfqq_coop_preempt(cfqq)) + if (cfqq) cfq_clear_cfqq_coop(cfqq); } - if (cfqq) - cfq_clear_cfqq_coop_preempt(cfqq); - __cfq_set_active_queue(cfqd, cfqq); return cfqq; } @@ -2056,7 +2051,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, * it's a metadata request and the current queue is doing regular IO. */ if (rq_is_meta(rq) && !cfqq->meta_pending) - return true; + return false; /* * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. @@ -2071,16 +2066,8 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, * if this request is as-good as one we would expect from the * current cfqq, let it preempt */ - if (cfq_rq_close(cfqd, rq) && (!cfq_cfqq_coop(new_cfqq) || - cfqd->busy_queues == 1)) { - /* - * Mark new queue coop_preempt, so its coop flag will not be - * cleared when new queue gets scheduled at the very first time - */ - cfq_mark_cfqq_coop_preempt(new_cfqq); - cfq_mark_cfqq_coop(new_cfqq); + if (cfq_rq_close(cfqd, rq)) return true; - } return false; } diff --git a/trunk/crypto/async_tx/async_pq.c b/trunk/crypto/async_tx/async_pq.c index 6b5cc4fba59f..b88db6d1dc65 100644 --- a/trunk/crypto/async_tx/async_pq.c +++ b/trunk/crypto/async_tx/async_pq.c @@ -26,10 +26,14 @@ #include /** - * pq_scribble_page - space to hold throwaway P or Q buffer for - * synchronous gen_syndrome + * scribble - space to hold throwaway P buffer for synchronous gen_syndrome */ -static struct page *pq_scribble_page; +static struct page *scribble; + +static bool is_raid6_zero_block(struct page *p) +{ + return p == (void *) raid6_empty_zero_page; +} /* the struct page *blocks[] parameter passed to async_gen_syndrome() * and async_syndrome_val() contains the 'P' destination address at @@ -79,7 +83,7 @@ do_async_gen_syndrome(struct dma_chan *chan, struct page **blocks, * sources and update the coefficients accordingly */ for (i = 0, idx = 0; i < src_cnt; i++) { - if (blocks[i] == NULL) + if (is_raid6_zero_block(blocks[i])) continue; dma_src[idx] = dma_map_page(dma->dev, blocks[i], offset, len, DMA_TO_DEVICE); @@ -156,9 +160,9 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks, srcs = (void **) blocks; for (i = 0; i < disks; i++) { - if (blocks[i] == NULL) { + if (is_raid6_zero_block(blocks[i])) { BUG_ON(i > disks - 3); /* P or Q can't be zero */ - srcs[i] = (void*)raid6_empty_zero_page; + srcs[i] = blocks[i]; } else srcs[i] = page_address(blocks[i]) + offset; } @@ -182,14 +186,10 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks, * blocks[disks-1] to NULL. When P or Q is omitted 'len' must be <= * PAGE_SIZE as a temporary buffer of this size is used in the * synchronous path. 'disks' always accounts for both destination - * buffers. If any source buffers (blocks[i] where i < disks - 2) are - * set to NULL those buffers will be replaced with the raid6_zero_page - * in the synchronous path and omitted in the hardware-asynchronous - * path. + * buffers. * * 'blocks' note: if submit->scribble is NULL then the contents of - * 'blocks' may be overwritten to perform address conversions - * (dma_map_page() or page_address()). + * 'blocks' may be overridden */ struct dma_async_tx_descriptor * async_gen_syndrome(struct page **blocks, unsigned int offset, int disks, @@ -227,11 +227,11 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks, async_tx_quiesce(&submit->depend_tx); if (!P(blocks, disks)) { - P(blocks, disks) = pq_scribble_page; + P(blocks, disks) = scribble; BUG_ON(len + offset > PAGE_SIZE); } if (!Q(blocks, disks)) { - Q(blocks, disks) = pq_scribble_page; + Q(blocks, disks) = scribble; BUG_ON(len + offset > PAGE_SIZE); } do_sync_gen_syndrome(blocks, offset, disks, len, submit); @@ -265,10 +265,8 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks, len); struct dma_device *device = chan ? chan->device : NULL; struct dma_async_tx_descriptor *tx; - unsigned char coefs[disks-2]; enum dma_ctrl_flags dma_flags = submit->cb_fn ? DMA_PREP_INTERRUPT : 0; dma_addr_t *dma_src = NULL; - int src_cnt = 0; BUG_ON(disks < 4); @@ -287,32 +285,22 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks, __func__, disks, len); if (!P(blocks, disks)) dma_flags |= DMA_PREP_PQ_DISABLE_P; - else - pq[0] = dma_map_page(dev, P(blocks, disks), - offset, len, - DMA_TO_DEVICE); if (!Q(blocks, disks)) dma_flags |= DMA_PREP_PQ_DISABLE_Q; - else - pq[1] = dma_map_page(dev, Q(blocks, disks), - offset, len, - DMA_TO_DEVICE); - if (submit->flags & ASYNC_TX_FENCE) dma_flags |= DMA_PREP_FENCE; - for (i = 0; i < disks-2; i++) + for (i = 0; i < disks; i++) if (likely(blocks[i])) { - dma_src[src_cnt] = dma_map_page(dev, blocks[i], - offset, len, - DMA_TO_DEVICE); - coefs[src_cnt] = raid6_gfexp[i]; - src_cnt++; + BUG_ON(is_raid6_zero_block(blocks[i])); + dma_src[i] = dma_map_page(dev, blocks[i], + offset, len, + DMA_TO_DEVICE); } for (;;) { tx = device->device_prep_dma_pq_val(chan, pq, dma_src, - src_cnt, - coefs, + disks - 2, + raid6_gfexp, len, pqres, dma_flags); if (likely(tx)) @@ -385,9 +373,9 @@ EXPORT_SYMBOL_GPL(async_syndrome_val); static int __init async_pq_init(void) { - pq_scribble_page = alloc_page(GFP_KERNEL); + scribble = alloc_page(GFP_KERNEL); - if (pq_scribble_page) + if (scribble) return 0; pr_err("%s: failed to allocate required spare page\n", __func__); @@ -397,7 +385,7 @@ static int __init async_pq_init(void) static void __exit async_pq_exit(void) { - put_page(pq_scribble_page); + put_page(scribble); } module_init(async_pq_init); diff --git a/trunk/crypto/async_tx/async_raid6_recov.c b/trunk/crypto/async_tx/async_raid6_recov.c index 943f2abac9b4..6d73dde4786d 100644 --- a/trunk/crypto/async_tx/async_raid6_recov.c +++ b/trunk/crypto/async_tx/async_raid6_recov.c @@ -131,8 +131,8 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len, } static struct dma_async_tx_descriptor * -__2data_recov_4(int disks, size_t bytes, int faila, int failb, - struct page **blocks, struct async_submit_ctl *submit) +__2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks, + struct async_submit_ctl *submit) { struct dma_async_tx_descriptor *tx = NULL; struct page *p, *q, *a, *b; @@ -143,8 +143,8 @@ __2data_recov_4(int disks, size_t bytes, int faila, int failb, void *cb_param = submit->cb_param; void *scribble = submit->scribble; - p = blocks[disks-2]; - q = blocks[disks-1]; + p = blocks[4-2]; + q = blocks[4-1]; a = blocks[faila]; b = blocks[failb]; @@ -170,8 +170,8 @@ __2data_recov_4(int disks, size_t bytes, int faila, int failb, } static struct dma_async_tx_descriptor * -__2data_recov_5(int disks, size_t bytes, int faila, int failb, - struct page **blocks, struct async_submit_ctl *submit) +__2data_recov_5(size_t bytes, int faila, int failb, struct page **blocks, + struct async_submit_ctl *submit) { struct dma_async_tx_descriptor *tx = NULL; struct page *p, *q, *g, *dp, *dq; @@ -181,22 +181,21 @@ __2data_recov_5(int disks, size_t bytes, int faila, int failb, dma_async_tx_callback cb_fn = submit->cb_fn; void *cb_param = submit->cb_param; void *scribble = submit->scribble; - int good_srcs, good, i; + int uninitialized_var(good); + int i; - good_srcs = 0; - good = -1; - for (i = 0; i < disks-2; i++) { - if (blocks[i] == NULL) - continue; + for (i = 0; i < 3; i++) { if (i == faila || i == failb) continue; - good = i; - good_srcs++; + else { + good = i; + break; + } } - BUG_ON(good_srcs > 1); + BUG_ON(i >= 3); - p = blocks[disks-2]; - q = blocks[disks-1]; + p = blocks[5-2]; + q = blocks[5-1]; g = blocks[good]; /* Compute syndrome with zero for the missing data pages @@ -264,10 +263,10 @@ __2data_recov_n(int disks, size_t bytes, int faila, int failb, * delta p and delta q */ dp = blocks[faila]; - blocks[faila] = NULL; + blocks[faila] = (void *)raid6_empty_zero_page; blocks[disks-2] = dp; dq = blocks[failb]; - blocks[failb] = NULL; + blocks[failb] = (void *)raid6_empty_zero_page; blocks[disks-1] = dq; init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble); @@ -324,8 +323,6 @@ struct dma_async_tx_descriptor * async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb, struct page **blocks, struct async_submit_ctl *submit) { - int non_zero_srcs, i; - BUG_ON(faila == failb); if (failb < faila) swap(faila, failb); @@ -337,13 +334,11 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb, */ if (!submit->scribble) { void **ptrs = (void **) blocks; + int i; async_tx_quiesce(&submit->depend_tx); for (i = 0; i < disks; i++) - if (blocks[i] == NULL) - ptrs[i] = (void *) raid6_empty_zero_page; - else - ptrs[i] = page_address(blocks[i]); + ptrs[i] = page_address(blocks[i]); raid6_2data_recov(disks, bytes, faila, failb, ptrs); @@ -352,30 +347,19 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb, return NULL; } - non_zero_srcs = 0; - for (i = 0; i < disks-2 && non_zero_srcs < 4; i++) - if (blocks[i]) - non_zero_srcs++; - switch (non_zero_srcs) { - case 0: - case 1: - /* There must be at least 2 sources - the failed devices. */ - BUG(); - - case 2: + switch (disks) { + case 4: /* dma devices do not uniformly understand a zero source pq * operation (in contrast to the synchronous case), so - * explicitly handle the special case of a 4 disk array with - * both data disks missing. + * explicitly handle the 4 disk special case */ - return __2data_recov_4(disks, bytes, faila, failb, blocks, submit); - case 3: + return __2data_recov_4(bytes, faila, failb, blocks, submit); + case 5: /* dma devices do not uniformly understand a single * source pq operation (in contrast to the synchronous - * case), so explicitly handle the special case of a 5 disk - * array with 2 of 3 data disks missing. + * case), so explicitly handle the 5 disk special case */ - return __2data_recov_5(disks, bytes, faila, failb, blocks, submit); + return __2data_recov_5(bytes, faila, failb, blocks, submit); default: return __2data_recov_n(disks, bytes, faila, failb, blocks, submit); } @@ -401,7 +385,6 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila, dma_async_tx_callback cb_fn = submit->cb_fn; void *cb_param = submit->cb_param; void *scribble = submit->scribble; - int good_srcs, good, i; struct page *srcs[2]; pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes); @@ -411,13 +394,11 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila, */ if (!scribble) { void **ptrs = (void **) blocks; + int i; async_tx_quiesce(&submit->depend_tx); for (i = 0; i < disks; i++) - if (blocks[i] == NULL) - ptrs[i] = (void*)raid6_empty_zero_page; - else - ptrs[i] = page_address(blocks[i]); + ptrs[i] = page_address(blocks[i]); raid6_datap_recov(disks, bytes, faila, ptrs); @@ -426,20 +407,6 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila, return NULL; } - good_srcs = 0; - good = -1; - for (i = 0; i < disks-2; i++) { - if (i == faila) - continue; - if (blocks[i]) { - good = i; - good_srcs++; - if (good_srcs > 1) - break; - } - } - BUG_ON(good_srcs == 0); - p = blocks[disks-2]; q = blocks[disks-1]; @@ -447,13 +414,14 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila, * Use the dead data page as temporary storage for delta q */ dq = blocks[faila]; - blocks[faila] = NULL; + blocks[faila] = (void *)raid6_empty_zero_page; blocks[disks-1] = dq; - /* in the 4-disk case we only need to perform a single source - * multiplication with the one good data block. + /* in the 4 disk case we only need to perform a single source + * multiplication */ - if (good_srcs == 1) { + if (disks == 4) { + int good = faila == 0 ? 1 : 0; struct page *g = blocks[good]; init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, diff --git a/trunk/crypto/async_tx/async_xor.c b/trunk/crypto/async_tx/async_xor.c index 79182dcb91b7..b459a9034aac 100644 --- a/trunk/crypto/async_tx/async_xor.c +++ b/trunk/crypto/async_tx/async_xor.c @@ -44,23 +44,20 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list, void *cb_param_orig = submit->cb_param; enum async_tx_flags flags_orig = submit->flags; enum dma_ctrl_flags dma_flags; - int xor_src_cnt = 0; + int xor_src_cnt; dma_addr_t dma_dest; /* map the dest bidrectional in case it is re-used as a source */ dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_BIDIRECTIONAL); for (i = 0; i < src_cnt; i++) { /* only map the dest once */ - if (!src_list[i]) - continue; if (unlikely(src_list[i] == dest)) { - dma_src[xor_src_cnt++] = dma_dest; + dma_src[i] = dma_dest; continue; } - dma_src[xor_src_cnt++] = dma_map_page(dma->dev, src_list[i], offset, - len, DMA_TO_DEVICE); + dma_src[i] = dma_map_page(dma->dev, src_list[i], offset, + len, DMA_TO_DEVICE); } - src_cnt = xor_src_cnt; while (src_cnt) { submit->flags = flags_orig; @@ -126,7 +123,7 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset, int src_cnt, size_t len, struct async_submit_ctl *submit) { int i; - int xor_src_cnt = 0; + int xor_src_cnt; int src_off = 0; void *dest_buf; void **srcs; @@ -138,9 +135,8 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset, /* convert to buffer pointers */ for (i = 0; i < src_cnt; i++) - if (src_list[i]) - srcs[xor_src_cnt++] = page_address(src_list[i]) + offset; - src_cnt = xor_src_cnt; + srcs[i] = page_address(src_list[i]) + offset; + /* set destination address */ dest_buf = page_address(dest) + offset; diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index a3241a1a710b..a06f5d6375a8 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -2718,30 +2718,6 @@ static bool ahci_sb600_enable_64bit(struct pci_dev *pdev) }, .driver_data = "20071026", /* yyyymmdd */ }, - /* - * All BIOS versions for the MSI K9A2 Platinum (MS-7376) - * support 64bit DMA. - * - * BIOS versions earlier than 1.5 had the Manufacturer DMI - * fields as "MICRO-STAR INTERANTIONAL CO.,LTD". - * This spelling mistake was fixed in BIOS version 1.5, so - * 1.5 and later have the Manufacturer as - * "MICRO-STAR INTERNATIONAL CO.,LTD". - * So try to match on DMI_BOARD_VENDOR of "MICRO-STAR INTER". - * - * BIOS versions earlier than 1.9 had a Board Product Name - * DMI field of "MS-7376". This was changed to be - * "K9A2 Platinum (MS-7376)" in version 1.9, but we can still - * match on DMI_BOARD_NAME of "MS-7376". - */ - { - .ident = "MSI K9A2 Platinum", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, - "MICRO-STAR INTER"), - DMI_MATCH(DMI_BOARD_NAME, "MS-7376"), - }, - }, { } }; const struct dmi_system_id *match; @@ -2753,24 +2729,18 @@ static bool ahci_sb600_enable_64bit(struct pci_dev *pdev) !match) return false; - if (!match->driver_data) - goto enable_64bit; - dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); - if (strcmp(buf, match->driver_data) >= 0) - goto enable_64bit; - else { + if (strcmp(buf, match->driver_data) >= 0) { + dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n", + match->ident); + return true; + } else { dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " "forcing 32bit DMA, update BIOS\n", match->ident); return false; } - -enable_64bit: - dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n", - match->ident); - return true; } static bool ahci_broken_system_poweroff(struct pci_dev *pdev) diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index dc72690ed5db..d7f0f1b1ae3e 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -4919,11 +4919,10 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev) */ void ata_qc_free(struct ata_queued_cmd *qc) { - struct ata_port *ap; + struct ata_port *ap = qc->ap; unsigned int tag; WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ - ap = qc->ap; qc->flags = 0; tag = qc->tag; @@ -4935,13 +4934,11 @@ void ata_qc_free(struct ata_queued_cmd *qc) void __ata_qc_complete(struct ata_queued_cmd *qc) { - struct ata_port *ap; - struct ata_link *link; + struct ata_port *ap = qc->ap; + struct ata_link *link = qc->dev->link; WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE)); - ap = qc->ap; - link = qc->dev->link; if (likely(qc->flags & ATA_QCFLAG_DMAMAP)) ata_sg_clean(qc); diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 02efd9a83d26..bdd43c7f432e 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -93,6 +93,7 @@ static const struct pci_device_id svia_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x7372), vt6420 }, { PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */ { PCI_VDEVICE(VIA, 0x9000), vt8251 }, + { PCI_VDEVICE(VIA, 0x9040), vt8251 }, { } /* terminate list */ }; diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 63c143e54a57..973bf2ad4e0d 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -689,19 +689,15 @@ int bus_add_driver(struct device_driver *drv) printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", __func__, drv->name); } - - if (!drv->suppress_bind_attrs) { - error = add_bind_files(drv); - if (error) { - /* Ditto */ - printk(KERN_ERR "%s: add_bind_files(%s) failed\n", - __func__, drv->name); - } + error = add_bind_files(drv); + if (error) { + /* Ditto */ + printk(KERN_ERR "%s: add_bind_files(%s) failed\n", + __func__, drv->name); } kobject_uevent(&priv->kobj, KOBJ_ADD); return 0; - out_unregister: kfree(drv->p); drv->p = NULL; @@ -724,8 +720,7 @@ void bus_remove_driver(struct device_driver *drv) if (!drv->bus) return; - if (!drv->suppress_bind_attrs) - remove_bind_files(drv); + remove_bind_files(drv); driver_remove_attrs(drv->bus, drv); driver_remove_file(drv, &driver_attr_uevent); klist_remove(&drv->p->knode_bus); diff --git a/trunk/drivers/base/driver.c b/trunk/drivers/base/driver.c index f367885a7646..ed2ebd3c287d 100644 --- a/trunk/drivers/base/driver.c +++ b/trunk/drivers/base/driver.c @@ -236,7 +236,7 @@ int driver_register(struct device_driver *drv) put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); - return -EBUSY; + return -EEXIST; } ret = bus_add_driver(drv); diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 4fa954b07ac4..ed156a13aa40 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -521,15 +521,11 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, { int retval, code; - /* make sure driver won't have bind/unbind attributes */ - drv->driver.suppress_bind_attrs = true; - /* temporary section violation during probe() */ drv->probe = probe; retval = code = platform_driver_register(drv); - /* - * Fixup that section violation, being paranoid about code scanning + /* Fixup that section violation, being paranoid about code scanning * the list of drivers in order to probe new devices. Check to see * if the probe was successful, and make sure any forced probes of * new devices fail. diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 8aa2443182d5..e0dc4071e088 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -511,7 +511,6 @@ static void dpm_complete(pm_message_t state) INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); - transition_started = false; while (!list_empty(&dpm_list)) { struct device *dev = to_device(dpm_list.prev); diff --git a/trunk/drivers/base/power/runtime.c b/trunk/drivers/base/power/runtime.c index a770498a74ec..38556f6cc22d 100644 --- a/trunk/drivers/base/power/runtime.c +++ b/trunk/drivers/base/power/runtime.c @@ -51,6 +51,8 @@ static int __pm_runtime_idle(struct device *dev) { int retval = 0; + dev_dbg(dev, "__pm_runtime_idle()!\n"); + if (dev->power.runtime_error) retval = -EINVAL; else if (dev->power.idle_notification) @@ -91,6 +93,8 @@ static int __pm_runtime_idle(struct device *dev) wake_up_all(&dev->power.wait_queue); out: + dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval); + return retval; } diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 6aad99ec4e0f..08a6f50ae791 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -323,7 +323,7 @@ config SPECIALIX config SX tristate "Specialix SX (and SI) card support" - depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN + depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) help This is a driver for the SX and SI multiport serial cards. Please read the file for details. @@ -334,7 +334,7 @@ config SX config RIO tristate "Specialix RIO system support" - depends on SERIAL_NONSTANDARD && BROKEN + depends on SERIAL_NONSTANDARD help This is a driver for the Specialix RIO, a smart serial card which drives an outboard box that can support up to 128 ports. Product @@ -395,7 +395,7 @@ config NOZOMI config A2232 tristate "Commodore A2232 serial support (EXPERIMENTAL)" - depends on EXPERIMENTAL && ZORRO && BROKEN + depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP ---help--- This option supports the 2232 7-port serial card shipped with the Amiga 2000 and other Zorro-bus machines, dating from 1989. At diff --git a/trunk/drivers/char/hvc_xen.c b/trunk/drivers/char/hvc_xen.c index a6ee32b599a8..eba999f8598d 100644 --- a/trunk/drivers/char/hvc_xen.c +++ b/trunk/drivers/char/hvc_xen.c @@ -55,7 +55,7 @@ static inline void notify_daemon(void) notify_remote_via_evtchn(xen_start_info->console.domU.evtchn); } -static int __write_console(const char *data, int len) +static int write_console(uint32_t vtermno, const char *data, int len) { struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -76,29 +76,6 @@ static int __write_console(const char *data, int len) return sent; } -static int write_console(uint32_t vtermno, const char *data, int len) -{ - int ret = len; - - /* - * Make sure the whole buffer is emitted, polling if - * necessary. We don't ever want to rely on the hvc daemon - * because the most interesting console output is when the - * kernel is crippled. - */ - while (len) { - int sent = __write_console(data, len); - - data += sent; - len -= sent; - - if (unlikely(len)) - HYPERVISOR_sched_op(SCHEDOP_yield, NULL); - } - - return ret; -} - static int read_console(uint32_t vtermno, char *buf, int len) { struct xencons_interface *intf = xencons_interface(); diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index a38831c82649..d4560d9d5a83 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -2254,7 +2254,7 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, { u32 ec = ERROR_CODE(info->nbsl); u32 xec = EXT_ERROR_CODE(info->nbsl); - int ecc_type = (info->nbsh >> 13) & 0x3; + int ecc_type = info->nbsh & (0x3 << 13); /* Bail early out if this was an 'observed' error */ if (PP(ec) == K8_NBSL_PP_OBS) @@ -3163,7 +3163,7 @@ static int __init amd64_edac_init(void) opstate_init(); if (cache_k8_northbridges() < 0) - return err; + goto err_exit; err = pci_register_driver(&amd64_pci_driver); if (err) @@ -3189,6 +3189,8 @@ static int __init amd64_edac_init(void) err_2nd_stage: debugf0("2nd stage failed\n"); + +err_exit: pci_unregister_driver(&amd64_pci_driver); return err; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index e5b138be45fa..92aeb918e0c0 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1227,7 +1227,8 @@ static int i915_load_modeset_init(struct drm_device *dev, goto out; /* Try to set up FBC with a reasonable compressed buffer size */ - if (I915_HAS_FBC(dev) && i915_powersave) { + if (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev) || IS_GM45(dev)) && + i915_powersave) { int cfb_size; /* Try to get an 8M buffer... */ diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 7f436ec075f6..b93814c0d3e2 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -89,8 +89,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) pci_set_power_state(dev->pdev, PCI_D3hot); } - /* Modeset on resume, not lid events */ - dev_priv->modeset_on_lid = 0; + dev_priv->suspended = 1; return 0; } @@ -125,7 +124,7 @@ static int i915_resume(struct drm_device *dev) drm_helper_resume_force_mode(dev); } - dev_priv->modeset_on_lid = 0; + dev_priv->suspended = 0; return ret; } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 57204e298975..6035d3dae851 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -274,7 +274,7 @@ typedef struct drm_i915_private { struct drm_i915_display_funcs display; /* Register state */ - bool modeset_on_lid; + bool suspended; u8 saveLBB; u32 saveDSPACNTR; u32 saveDSPBCNTR; @@ -296,12 +296,6 @@ typedef struct drm_i915_private { u32 saveVBLANK_A; u32 saveVSYNC_A; u32 saveBCLRPAT_A; - u32 saveTRANS_HTOTAL_A; - u32 saveTRANS_HBLANK_A; - u32 saveTRANS_HSYNC_A; - u32 saveTRANS_VTOTAL_A; - u32 saveTRANS_VBLANK_A; - u32 saveTRANS_VSYNC_A; u32 savePIPEASTAT; u32 saveDSPASTRIDE; u32 saveDSPASIZE; @@ -310,11 +304,8 @@ typedef struct drm_i915_private { u32 saveDSPASURF; u32 saveDSPATILEOFF; u32 savePFIT_PGM_RATIOS; - u32 saveBLC_HIST_CTL; u32 saveBLC_PWM_CTL; u32 saveBLC_PWM_CTL2; - u32 saveBLC_CPU_PWM_CTL; - u32 saveBLC_CPU_PWM_CTL2; u32 saveFPB0; u32 saveFPB1; u32 saveDPLL_B; @@ -326,12 +317,6 @@ typedef struct drm_i915_private { u32 saveVBLANK_B; u32 saveVSYNC_B; u32 saveBCLRPAT_B; - u32 saveTRANS_HTOTAL_B; - u32 saveTRANS_HBLANK_B; - u32 saveTRANS_HSYNC_B; - u32 saveTRANS_VTOTAL_B; - u32 saveTRANS_VBLANK_B; - u32 saveTRANS_VSYNC_B; u32 savePIPEBSTAT; u32 saveDSPBSTRIDE; u32 saveDSPBSIZE; @@ -357,7 +342,6 @@ typedef struct drm_i915_private { u32 savePFIT_CONTROL; u32 save_palette_a[256]; u32 save_palette_b[256]; - u32 saveDPFC_CB_BASE; u32 saveFBC_CFB_BASE; u32 saveFBC_LL_BASE; u32 saveFBC_CONTROL; @@ -365,12 +349,6 @@ typedef struct drm_i915_private { u32 saveIER; u32 saveIIR; u32 saveIMR; - u32 saveDEIER; - u32 saveDEIMR; - u32 saveGTIER; - u32 saveGTIMR; - u32 saveFDI_RXA_IMR; - u32 saveFDI_RXB_IMR; u32 saveCACHE_MODE_0; u32 saveD_STATE; u32 saveDSPCLK_GATE_D; @@ -404,16 +382,6 @@ typedef struct drm_i915_private { u32 savePIPEB_DP_LINK_M; u32 savePIPEA_DP_LINK_N; u32 savePIPEB_DP_LINK_N; - u32 saveFDI_RXA_CTL; - u32 saveFDI_TXA_CTL; - u32 saveFDI_RXB_CTL; - u32 saveFDI_TXB_CTL; - u32 savePFA_CTL_1; - u32 savePFB_CTL_1; - u32 savePFA_WIN_SZ; - u32 savePFB_WIN_SZ; - u32 savePFA_WIN_POS; - u32 savePFB_WIN_POS; struct { struct drm_mm gtt_space; @@ -524,8 +492,6 @@ typedef struct drm_i915_private { struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; } mm; struct sdvo_device_mapping sdvo_mappings[2]; - /* indicate whether the LVDS_BORDER should be enabled or not */ - unsigned int lvds_border_bits; /* Reclocking support */ bool render_reclock_avail; @@ -1015,10 +981,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev)) #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) -#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \ - (IS_I9XX(dev) || IS_GM45(dev)) && \ - !IS_IGD(dev) && \ - !IS_IGDNG(dev)) +#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev))) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 1687edf68795..0466ddbeba32 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -968,8 +968,6 @@ #define LVDS_PORT_EN (1 << 31) /* Selects pipe B for LVDS data. Must be set on pre-965. */ #define LVDS_PIPEB_SELECT (1 << 30) -/* Enable border for unscaled (or aspect-scaled) display */ -#define LVDS_BORDER_ENABLE (1 << 15) /* * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per * pixel. @@ -1080,8 +1078,6 @@ #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) -#define BLC_HIST_CTL 0x61260 - /* TV port control */ #define TV_CTL 0x68000 /** Enables the TV encoder */ @@ -1784,11 +1780,6 @@ #define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ #define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) #define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) -#define PIPE_BPC_MASK (7 << 5) /* Ironlake */ -#define PIPE_8BPC (0 << 5) -#define PIPE_10BPC (1 << 5) -#define PIPE_6BPC (2 << 5) -#define PIPE_12BPC (3 << 5) #define DSPARB 0x70030 #define DSPARB_CSTART_MASK (0x7f << 7) @@ -1799,29 +1790,17 @@ #define DSPARB_AEND_SHIFT 0 #define DSPFW1 0x70034 -#define DSPFW_SR_SHIFT 23 -#define DSPFW_CURSORB_SHIFT 16 -#define DSPFW_PLANEB_SHIFT 8 #define DSPFW2 0x70038 -#define DSPFW_CURSORA_MASK 0x00003f00 -#define DSPFW_CURSORA_SHIFT 16 #define DSPFW3 0x7003c -#define DSPFW_HPLL_SR_EN (1<<31) -#define DSPFW_CURSOR_SR_SHIFT 24 #define IGD_SELF_REFRESH_EN (1<<30) /* FIFO watermark sizes etc */ -#define G4X_FIFO_LINE_SIZE 64 #define I915_FIFO_LINE_SIZE 64 #define I830_FIFO_LINE_SIZE 32 - -#define G4X_FIFO_SIZE 127 #define I945_FIFO_SIZE 127 /* 945 & 965 */ #define I915_FIFO_SIZE 95 #define I855GM_FIFO_SIZE 127 /* In cachelines */ #define I830_FIFO_SIZE 95 - -#define G4X_MAX_WM 0x3f #define I915_MAX_WM 0x3f #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ @@ -2051,11 +2030,6 @@ #define PFA_CTL_1 0x68080 #define PFB_CTL_1 0x68880 #define PF_ENABLE (1<<31) -#define PF_FILTER_MASK (3<<23) -#define PF_FILTER_PROGRAMMED (0<<23) -#define PF_FILTER_MED_3x3 (1<<23) -#define PF_FILTER_EDGE_ENHANCE (2<<23) -#define PF_FILTER_EDGE_SOFTEN (3<<23) #define PFA_WIN_SZ 0x68074 #define PFB_WIN_SZ 0x68874 #define PFA_WIN_POS 0x68070 @@ -2175,11 +2149,11 @@ #define DREF_CPU_SOURCE_OUTPUT_MASK (3<<13) #define DREF_SSC_SOURCE_DISABLE (0<<11) #define DREF_SSC_SOURCE_ENABLE (2<<11) -#define DREF_SSC_SOURCE_MASK (3<<11) +#define DREF_SSC_SOURCE_MASK (2<<11) #define DREF_NONSPREAD_SOURCE_DISABLE (0<<9) #define DREF_NONSPREAD_CK505_ENABLE (1<<9) #define DREF_NONSPREAD_SOURCE_ENABLE (2<<9) -#define DREF_NONSPREAD_SOURCE_MASK (3<<9) +#define DREF_NONSPREAD_SOURCE_MASK (2<<9) #define DREF_SUPERSPREAD_SOURCE_DISABLE (0<<7) #define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7) #define DREF_SSC4_DOWNSPREAD (0<<6) diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 992d5617e798..bd6d8d91ca9f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -32,15 +32,11 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpll_reg; - if (IS_IGDNG(dev)) { - dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; - } else { - dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; - } - - return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE); + if (pipe == PIPE_A) + return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); + else + return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); } static void i915_save_palette(struct drm_device *dev, enum pipe pipe) @@ -53,9 +49,6 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe) if (!i915_pipe_enabled(dev, pipe)) return; - if (IS_IGDNG(dev)) - reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; - if (pipe == PIPE_A) array = dev_priv->save_palette_a; else @@ -75,9 +68,6 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) if (!i915_pipe_enabled(dev, pipe)) return; - if (IS_IGDNG(dev)) - reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; - if (pipe == PIPE_A) array = dev_priv->save_palette_a; else @@ -242,16 +232,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) /* Pipe & plane A info */ dev_priv->savePIPEACONF = I915_READ(PIPEACONF); dev_priv->savePIPEASRC = I915_READ(PIPEASRC); - if (IS_IGDNG(dev)) { - dev_priv->saveFPA0 = I915_READ(PCH_FPA0); - dev_priv->saveFPA1 = I915_READ(PCH_FPA1); - dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); - } else { - dev_priv->saveFPA0 = I915_READ(FPA0); - dev_priv->saveFPA1 = I915_READ(FPA1); - dev_priv->saveDPLL_A = I915_READ(DPLL_A); - } - if (IS_I965G(dev) && !IS_IGDNG(dev)) + dev_priv->saveFPA0 = I915_READ(FPA0); + dev_priv->saveFPA1 = I915_READ(FPA1); + dev_priv->saveDPLL_A = I915_READ(DPLL_A); + if (IS_I965G(dev)) dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); @@ -259,24 +243,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); - if (!IS_IGDNG(dev)) - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); - - if (IS_IGDNG(dev)) { - dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); - dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); - - dev_priv->savePFA_CTL_1 = I915_READ(PFA_CTL_1); - dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); - dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); - - dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); - dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); - dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); - dev_priv->saveTRANS_VTOTAL_A = I915_READ(TRANS_VTOTAL_A); - dev_priv->saveTRANS_VBLANK_A = I915_READ(TRANS_VBLANK_A); - dev_priv->saveTRANS_VSYNC_A = I915_READ(TRANS_VSYNC_A); - } + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); @@ -293,16 +260,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) /* Pipe & plane B info */ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); - if (IS_IGDNG(dev)) { - dev_priv->saveFPB0 = I915_READ(PCH_FPB0); - dev_priv->saveFPB1 = I915_READ(PCH_FPB1); - dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); - } else { - dev_priv->saveFPB0 = I915_READ(FPB0); - dev_priv->saveFPB1 = I915_READ(FPB1); - dev_priv->saveDPLL_B = I915_READ(DPLL_B); - } - if (IS_I965G(dev) && !IS_IGDNG(dev)) + dev_priv->saveFPB0 = I915_READ(FPB0); + dev_priv->saveFPB1 = I915_READ(FPB1); + dev_priv->saveDPLL_B = I915_READ(DPLL_B); + if (IS_I965G(dev)) dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); @@ -310,24 +271,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); - if (!IS_IGDNG(dev)) - dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); - - if (IS_IGDNG(dev)) { - dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); - dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); - - dev_priv->savePFB_CTL_1 = I915_READ(PFB_CTL_1); - dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); - dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); - - dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); - dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); - dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); - dev_priv->saveTRANS_VTOTAL_B = I915_READ(TRANS_VTOTAL_B); - dev_priv->saveTRANS_VBLANK_B = I915_READ(TRANS_VBLANK_B); - dev_priv->saveTRANS_VSYNC_B = I915_READ(TRANS_VSYNC_B); - } + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); @@ -346,41 +290,23 @@ static void i915_save_modeset_reg(struct drm_device *dev) static void i915_restore_modeset_reg(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int dpll_a_reg, fpa0_reg, fpa1_reg; - int dpll_b_reg, fpb0_reg, fpb1_reg; if (drm_core_check_feature(dev, DRIVER_MODESET)) return; - if (IS_IGDNG(dev)) { - dpll_a_reg = PCH_DPLL_A; - dpll_b_reg = PCH_DPLL_B; - fpa0_reg = PCH_FPA0; - fpb0_reg = PCH_FPB0; - fpa1_reg = PCH_FPA1; - fpb1_reg = PCH_FPB1; - } else { - dpll_a_reg = DPLL_A; - dpll_b_reg = DPLL_B; - fpa0_reg = FPA0; - fpb0_reg = FPB0; - fpa1_reg = FPA1; - fpb1_reg = FPB1; - } - /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { - I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE); DRM_UDELAY(150); } - I915_WRITE(fpa0_reg, dev_priv->saveFPA0); - I915_WRITE(fpa1_reg, dev_priv->saveFPA1); + I915_WRITE(FPA0, dev_priv->saveFPA0); + I915_WRITE(FPA1, dev_priv->saveFPA1); /* Actually enable it */ - I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); DRM_UDELAY(150); - if (IS_I965G(dev) && !IS_IGDNG(dev)) + if (IS_I965G(dev)) I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); DRM_UDELAY(150); @@ -391,24 +317,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); - if (!IS_IGDNG(dev)) - I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); - - if (IS_IGDNG(dev)) { - I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); - I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); - - I915_WRITE(PFA_CTL_1, dev_priv->savePFA_CTL_1); - I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); - I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); - - I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); - I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); - I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); - I915_WRITE(TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A); - I915_WRITE(TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A); - I915_WRITE(TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A); - } + I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); /* Restore plane info */ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); @@ -430,14 +339,14 @@ static void i915_restore_modeset_reg(struct drm_device *dev) /* Pipe & plane B info */ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { - I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE); DRM_UDELAY(150); } - I915_WRITE(fpb0_reg, dev_priv->saveFPB0); - I915_WRITE(fpb1_reg, dev_priv->saveFPB1); + I915_WRITE(FPB0, dev_priv->saveFPB0); + I915_WRITE(FPB1, dev_priv->saveFPB1); /* Actually enable it */ - I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); DRM_UDELAY(150); if (IS_I965G(dev)) I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); @@ -450,24 +359,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); - if (!IS_IGDNG(dev)) - I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); - - if (IS_IGDNG(dev)) { - I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); - I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); - - I915_WRITE(PFB_CTL_1, dev_priv->savePFB_CTL_1); - I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); - I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); - - I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); - I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); - I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); - I915_WRITE(TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B); - I915_WRITE(TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B); - I915_WRITE(TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B); - } + I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); /* Restore plane info */ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); @@ -512,43 +404,21 @@ void i915_save_display(struct drm_device *dev) dev_priv->saveCURSIZE = I915_READ(CURSIZE); /* CRT state */ - if (IS_IGDNG(dev)) { - dev_priv->saveADPA = I915_READ(PCH_ADPA); - } else { - dev_priv->saveADPA = I915_READ(ADPA); - } + dev_priv->saveADPA = I915_READ(ADPA); /* LVDS state */ - if (IS_IGDNG(dev)) { - dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); - dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL); - dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2); - dev_priv->saveLVDS = I915_READ(PCH_LVDS); - } else { - dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); - dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); - if (IS_I965G(dev)) - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); - if (IS_MOBILE(dev) && !IS_I830(dev)) - dev_priv->saveLVDS = I915_READ(LVDS); - } - - if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev)) + dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); + dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); + if (IS_I965G(dev)) + dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); + if (IS_MOBILE(dev) && !IS_I830(dev)) + dev_priv->saveLVDS = I915_READ(LVDS); + if (!IS_I830(dev) && !IS_845G(dev)) dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); - - if (IS_IGDNG(dev)) { - dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); - dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); - dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); - } else { - dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); - dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); - dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); - } + dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); + dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); + dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); /* Display Port state */ if (SUPPORTS_INTEGRATED_DP(dev)) { @@ -567,23 +437,16 @@ void i915_save_display(struct drm_device *dev) /* FIXME: save TV & SDVO state */ /* FBC state */ - if (IS_GM45(dev)) { - dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); - } else { - dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); - dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); - dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); - dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); - } + dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); + dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); + dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); + dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); /* VGA state */ dev_priv->saveVGA0 = I915_READ(VGA0); dev_priv->saveVGA1 = I915_READ(VGA1); dev_priv->saveVGA_PD = I915_READ(VGA_PD); - if (IS_IGDNG(dev)) - dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); - else - dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); i915_save_vga(dev); } @@ -622,41 +485,22 @@ void i915_restore_display(struct drm_device *dev) I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); /* CRT state */ - if (IS_IGDNG(dev)) - I915_WRITE(PCH_ADPA, dev_priv->saveADPA); - else - I915_WRITE(ADPA, dev_priv->saveADPA); + I915_WRITE(ADPA, dev_priv->saveADPA); /* LVDS state */ - if (IS_I965G(dev) && !IS_IGDNG(dev)) + if (IS_I965G(dev)) I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); - - if (IS_IGDNG(dev)) { - I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); - } else if (IS_MOBILE(dev) && !IS_I830(dev)) + if (IS_MOBILE(dev) && !IS_I830(dev)) I915_WRITE(LVDS, dev_priv->saveLVDS); - - if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev)) + if (!IS_I830(dev) && !IS_845G(dev)) I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); - if (IS_IGDNG(dev)) { - I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); - I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); - I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); - I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); - I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); - I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); - } else { - I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); - I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL); - I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); - I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); - I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); - I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - } + I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); + I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); + I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); + I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); + I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); + I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); /* Display Port state */ if (SUPPORTS_INTEGRATED_DP(dev)) { @@ -667,22 +511,13 @@ void i915_restore_display(struct drm_device *dev) /* FIXME: restore TV & SDVO state */ /* FBC info */ - if (IS_GM45(dev)) { - g4x_disable_fbc(dev); - I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); - } else { - i8xx_disable_fbc(dev); - I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); - I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); - I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); - I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); - } + I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); + I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); + I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); + I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); /* VGA state */ - if (IS_IGDNG(dev)) - I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); - else - I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); + I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); I915_WRITE(VGA0, dev_priv->saveVGA0); I915_WRITE(VGA1, dev_priv->saveVGA1); I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); @@ -708,17 +543,8 @@ int i915_save_state(struct drm_device *dev) i915_save_display(dev); /* Interrupt state */ - if (IS_IGDNG(dev)) { - dev_priv->saveDEIER = I915_READ(DEIER); - dev_priv->saveDEIMR = I915_READ(DEIMR); - dev_priv->saveGTIER = I915_READ(GTIER); - dev_priv->saveGTIMR = I915_READ(GTIMR); - dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR); - dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR); - } else { - dev_priv->saveIER = I915_READ(IER); - dev_priv->saveIMR = I915_READ(IMR); - } + dev_priv->saveIER = I915_READ(IER); + dev_priv->saveIMR = I915_READ(IMR); /* Clock gating state */ dev_priv->saveD_STATE = I915_READ(D_STATE); @@ -783,17 +609,8 @@ int i915_restore_state(struct drm_device *dev) i915_restore_display(dev); /* Interrupt state */ - if (IS_IGDNG(dev)) { - I915_WRITE(DEIER, dev_priv->saveDEIER); - I915_WRITE(DEIMR, dev_priv->saveDEIMR); - I915_WRITE(GTIER, dev_priv->saveGTIER); - I915_WRITE(GTIMR, dev_priv->saveGTIMR); - I915_WRITE(FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR); - I915_WRITE(FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR); - } else { - I915_WRITE (IER, dev_priv->saveIER); - I915_WRITE (IMR, dev_priv->saveIMR); - } + I915_WRITE (IER, dev_priv->saveIER); + I915_WRITE (IMR, dev_priv->saveIMR); /* Clock gating state */ I915_WRITE (D_STATE, dev_priv->saveD_STATE); diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index 96cd256e60e6..4337414846b6 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -351,18 +351,20 @@ parse_driver_features(struct drm_i915_private *dev_priv, struct drm_device *dev = dev_priv->dev; struct bdb_driver_features *driver; + /* set default for chips without eDP */ + if (!SUPPORTS_EDP(dev)) { + dev_priv->edp_support = 0; + return; + } + driver = find_section(bdb, BDB_DRIVER_FEATURES); if (!driver) return; - if (driver && SUPPORTS_EDP(dev) && - driver->lvds_config == BDB_DRIVER_FEATURE_EDP) { + if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) dev_priv->edp_support = 1; - } else { - dev_priv->edp_support = 0; - } - if (driver && driver->dual_frequency) + if (driver->dual_frequency) dev_priv->render_reclock_avail = true; } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 3ba6546b7c7f..3c14240cc002 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -943,7 +943,6 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); clock.p = (clock.p1 * clock.p2); clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; - clock.vco = 0; memcpy(best_clock, &clock, sizeof(intel_clock_t)); return true; } @@ -1261,11 +1260,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - /* Install a fence for tiled scan-out. Pre-i965 always needs a fence, - * whereas 965+ only requires a fence if using framebuffer compression. - * For simplicity, we always install a fence as the cost is not that onerous. - */ - if (obj_priv->fence_reg == I915_FENCE_REG_NONE && + /* Pre-i965 needs to install a fence for tiled scan-out */ + if (!IS_I965G(dev) && + obj_priv->fence_reg == I915_FENCE_REG_NONE && obj_priv->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj); if (ret != 0) { @@ -1516,7 +1513,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { temp = I915_READ(pf_ctl_reg); - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE); /* currently full aspect */ I915_WRITE(pf_win_pos, 0); @@ -1804,8 +1801,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: - intel_update_watermarks(dev); - /* Enable the DPLL */ temp = I915_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) == 0) { @@ -1843,6 +1838,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) /* Give the overlay scaler a chance to enable if it's on this pipe */ //intel_crtc_dpms_video(crtc, true); TODO + intel_update_watermarks(dev); break; case DRM_MODE_DPMS_OFF: intel_update_watermarks(dev); @@ -2086,7 +2082,7 @@ fdi_reduce_ratio(u32 *num, u32 *den) #define LINK_N 0x80000 static void -igdng_compute_m_n(int bits_per_pixel, int nlanes, +igdng_compute_m_n(int bytes_per_pixel, int nlanes, int pixel_clock, int link_clock, struct fdi_m_n *m_n) { @@ -2096,8 +2092,7 @@ igdng_compute_m_n(int bits_per_pixel, int nlanes, temp = (u64) DATA_N * pixel_clock; temp = div_u64(temp, link_clock); - m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); - m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ + m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); m_n->gmch_n = DATA_N; fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); @@ -2145,13 +2140,6 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = { IGD_CURSOR_GUARD_WM, IGD_FIFO_LINE_SIZE }; -static struct intel_watermark_params g4x_wm_info = { - G4X_FIFO_SIZE, - G4X_MAX_WM, - G4X_MAX_WM, - 2, - G4X_FIFO_LINE_SIZE, -}; static struct intel_watermark_params i945_wm_info = { I945_FIFO_SIZE, I915_MAX_WM, @@ -2442,74 +2430,17 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) return size; } -static void g4x_update_wm(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size) +static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, + int unused3, int unused4) { struct drm_i915_private *dev_priv = dev->dev_private; - int total_size, cacheline_size; - int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr; - struct intel_watermark_params planea_params, planeb_params; - unsigned long line_time_us; - int sr_clock, sr_entries = 0, entries_required; - - /* Create copies of the base settings for each pipe */ - planea_params = planeb_params = g4x_wm_info; - - /* Grab a couple of global values before we overwrite them */ - total_size = planea_params.fifo_size; - cacheline_size = planea_params.cacheline_size; - - /* - * Note: we need to make sure we don't overflow for various clock & - * latency values. - * clocks go from a few thousand to several hundred thousand. - * latency is usually a few thousand - */ - entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) / - 1000; - entries_required /= G4X_FIFO_LINE_SIZE; - planea_wm = entries_required + planea_params.guard_size; - - entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) / - 1000; - entries_required /= G4X_FIFO_LINE_SIZE; - planeb_wm = entries_required + planeb_params.guard_size; - - cursora_wm = cursorb_wm = 16; - cursor_sr = 32; - - DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); - - /* Calc sr entries for one plane configs */ - if (sr_hdisplay && (!planea_clock || !planeb_clock)) { - /* self-refresh has much higher latency */ - const static int sr_latency_ns = 12000; - - sr_clock = planea_clock ? planea_clock : planeb_clock; - line_time_us = ((sr_hdisplay * 1000) / sr_clock); - - /* Use ns/us then divide to preserve precision */ - sr_entries = (((sr_latency_ns / line_time_us) + 1) * - pixel_size * sr_hdisplay) / 1000; - sr_entries = roundup(sr_entries / cacheline_size, 1); - DRM_DEBUG("self-refresh entries: %d\n", sr_entries); - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); - } - - DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", - planea_wm, planeb_wm, sr_entries); + u32 fw_blc_self = I915_READ(FW_BLC_SELF); - planea_wm &= 0x3f; - planeb_wm &= 0x3f; - - I915_WRITE(DSPFW1, (sr_entries << DSPFW_SR_SHIFT) | - (cursorb_wm << DSPFW_CURSORB_SHIFT) | - (planeb_wm << DSPFW_PLANEB_SHIFT) | planea_wm); - I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | - (cursora_wm << DSPFW_CURSORA_SHIFT)); - /* HPLL off in SR has some issues on G4x... disable it */ - I915_WRITE(DSPFW3, (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | - (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); + if (i915_powersave) + fw_blc_self |= FW_BLC_SELF_EN; + else + fw_blc_self &= ~FW_BLC_SELF_EN; + I915_WRITE(FW_BLC_SELF, fw_blc_self); } static void i965_update_wm(struct drm_device *dev, int unused, int unused2, @@ -2655,9 +2586,6 @@ static void intel_update_watermarks(struct drm_device *dev) unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; int enabled = 0, pixel_size = 0; - if (!dev_priv->display.update_wm) - return; - /* Get the clock config from both planes */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { intel_crtc = to_intel_crtc(crtc); @@ -2835,7 +2763,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* FDI link */ if (IS_IGDNG(dev)) { - int lane, link_bw, bpp; + int lane, link_bw; /* eDP doesn't require FDI link, so just set DP M/N according to current link config */ if (is_edp) { @@ -2854,72 +2782,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, lane = 4; link_bw = 270000; } - - /* determine panel color depth */ - temp = I915_READ(pipeconf_reg); - - switch (temp & PIPE_BPC_MASK) { - case PIPE_8BPC: - bpp = 24; - break; - case PIPE_10BPC: - bpp = 30; - break; - case PIPE_6BPC: - bpp = 18; - break; - case PIPE_12BPC: - bpp = 36; - break; - default: - DRM_ERROR("unknown pipe bpc value\n"); - bpp = 24; - } - - igdng_compute_m_n(bpp, lane, target_clock, + igdng_compute_m_n(3, lane, target_clock, link_bw, &m_n); } - /* Ironlake: try to setup display ref clock before DPLL - * enabling. This is only under driver's control after - * PCH B stepping, previous chipset stepping should be - * ignoring this setting. - */ - if (IS_IGDNG(dev)) { - temp = I915_READ(PCH_DREF_CONTROL); - /* Always enable nonspread source */ - temp &= ~DREF_NONSPREAD_SOURCE_MASK; - temp |= DREF_NONSPREAD_SOURCE_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - - temp &= ~DREF_SSC_SOURCE_MASK; - temp |= DREF_SSC_SOURCE_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - - udelay(200); - - if (is_edp) { - if (dev_priv->lvds_use_ssc) { - temp |= DREF_SSC1_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - - udelay(200); - - temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - } else { - temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - } - } - } - if (IS_IGD(dev)) { fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; if (has_reduced_clock) @@ -3070,8 +2936,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, lvds = I915_READ(lvds_reg); lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; - /* set the corresponsding LVDS_BORDER bit */ - lvds |= dev_priv->lvds_border_bits; /* Set the B0-B3 data pairs corresponding to whether we're going to * set the DPLLs for dual-channel mode or not. */ @@ -4260,9 +4124,7 @@ void intel_init_clock_gating(struct drm_device *dev) * Disable clock gating reported to work incorrectly according to the * specs, but enable as much else as we can. */ - if (IS_IGDNG(dev)) { - return; - } else if (IS_G4X(dev)) { + if (IS_G4X(dev)) { uint32_t dspclk_gate; I915_WRITE(RENCLK_GATE_D1, 0); I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | @@ -4350,9 +4212,7 @@ static void intel_init_display(struct drm_device *dev) i830_get_display_clock_speed; /* For FIFO watermark updates */ - if (IS_IGDNG(dev)) - dev_priv->display.update_wm = NULL; - else if (IS_G4X(dev)) + if (IS_G4X(dev)) dev_priv->display.update_wm = g4x_update_wm; else if (IS_I965G(dev)) dev_priv->display.update_wm = i965_update_wm; diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index d83447557f9b..f4856a510476 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -400,7 +400,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) { struct intel_dp_priv *dp_priv = intel_output->dev_priv; - DRM_DEBUG_KMS("i2c_init %s\n", name); + DRM_ERROR("i2c_init %s\n", name); dp_priv->algo.running = false; dp_priv->algo.address = 0; dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 05598ae10c4b..98ae3d73577e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -380,7 +380,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, adjusted_mode->crtc_vblank_start + vsync_pos; /* keep the vsync width constant */ adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vsync_start + vsync_width; + adjusted_mode->crtc_vblank_start + vsync_width; border = 1; break; case DRM_MODE_SCALE_ASPECT: @@ -525,14 +525,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, out: lvds_priv->pfit_control = pfit_control; lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; - /* - * When there exists the border, it means that the LVDS_BORDR - * should be enabled. - */ - if (border) - dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE; - else - dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE); /* * XXX: It would be nice to support lower refresh rates on the * panels to reduce power consumption, and perhaps match the @@ -664,15 +656,6 @@ static int intel_lvds_get_modes(struct drm_connector *connector) return 0; } -/* - * Lid events. Note the use of 'modeset_on_lid': - * - we set it on lid close, and reset it on open - * - we use it as a "only once" bit (ie we ignore - * duplicate events where it was already properly - * set/reset) - * - the suspend/resume paths will also set it to - * zero, since they restore the mode ("lid open"). - */ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, void *unused) { @@ -680,19 +663,13 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, container_of(nb, struct drm_i915_private, lid_notifier); struct drm_device *dev = dev_priv->dev; - if (!acpi_lid_open()) { - dev_priv->modeset_on_lid = 1; - return NOTIFY_OK; + if (acpi_lid_open() && !dev_priv->suspended) { + mutex_lock(&dev->mode_config.mutex); + drm_helper_resume_force_mode(dev); + mutex_unlock(&dev->mode_config.mutex); } - if (!dev_priv->modeset_on_lid) - return NOTIFY_OK; - - dev_priv->modeset_on_lid = 0; - - mutex_lock(&dev->mode_config.mutex); - drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); + drm_sysfs_hotplug_event(dev_priv->dev); return NOTIFY_OK; } diff --git a/trunk/drivers/i2c/busses/i2c-imx.c b/trunk/drivers/i2c/busses/i2c-imx.c index e3654d683e15..4afba3ec2a61 100644 --- a/trunk/drivers/i2c/busses/i2c-imx.c +++ b/trunk/drivers/i2c/busses/i2c-imx.c @@ -120,26 +120,19 @@ struct imx_i2c_struct { wait_queue_head_t queue; unsigned long i2csr; unsigned int disable_delay; - int stopped; - unsigned int ifdr; /* IMX_I2C_IFDR */ }; /** Functions for IMX I2C adapter driver *************************************** *******************************************************************************/ -static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) +static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx) { unsigned long orig_jiffies = jiffies; - unsigned int temp; dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - while (1) { - temp = readb(i2c_imx->base + IMX_I2C_I2SR); - if (for_busy && (temp & I2SR_IBB)) - break; - if (!for_busy && !(temp & I2SR_IBB)) - break; + /* wait for bus not busy */ + while (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_IBB) { if (signal_pending(current)) { dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C Interrupted\n", __func__); @@ -186,62 +179,41 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx) return 0; } -static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) +static void i2c_imx_start(struct imx_i2c_struct *i2c_imx) { unsigned int temp = 0; - int result; dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - clk_enable(i2c_imx->clk); - writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR); /* Enable I2C controller */ - writeb(0, i2c_imx->base + IMX_I2C_I2SR); writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR); - - /* Wait controller to be stable */ - udelay(50); - /* Start I2C transaction */ temp = readb(i2c_imx->base + IMX_I2C_I2CR); temp |= I2CR_MSTA; writeb(temp, i2c_imx->base + IMX_I2C_I2CR); - result = i2c_imx_bus_busy(i2c_imx, 1); - if (result) - return result; - i2c_imx->stopped = 0; - temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK; writeb(temp, i2c_imx->base + IMX_I2C_I2CR); - return result; } static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) { unsigned int temp = 0; - if (!i2c_imx->stopped) { - /* Stop I2C transaction */ - dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - temp = readb(i2c_imx->base + IMX_I2C_I2CR); - temp &= ~(I2CR_MSTA | I2CR_MTX); - writeb(temp, i2c_imx->base + IMX_I2C_I2CR); - i2c_imx->stopped = 1; - } - if (cpu_is_mx1()) { - /* - * This delay caused by an i.MXL hardware bug. - * If no (or too short) delay, no "STOP" bit will be generated. - */ - udelay(i2c_imx->disable_delay); - } - - if (!i2c_imx->stopped) - i2c_imx_bus_busy(i2c_imx, 0); - + /* Stop I2C transaction */ + dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); + temp = readb(i2c_imx->base + IMX_I2C_I2CR); + temp &= ~I2CR_MSTA; + writeb(temp, i2c_imx->base + IMX_I2C_I2CR); + /* setup chip registers to defaults */ + writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR); + writeb(0, i2c_imx->base + IMX_I2C_I2SR); + /* + * This delay caused by an i.MXL hardware bug. + * If no (or too short) delay, no "STOP" bit will be generated. + */ + udelay(i2c_imx->disable_delay); /* Disable I2C controller */ writeb(0, i2c_imx->base + IMX_I2C_I2CR); - clk_disable(i2c_imx->clk); } static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, @@ -261,8 +233,8 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, else for (i = 0; i2c_clk_div[i][0] < div; i++); - /* Store divider value */ - i2c_imx->ifdr = i2c_clk_div[i][1]; + /* Write divider value to register */ + writeb(i2c_clk_div[i][1], i2c_imx->base + IMX_I2C_IFDR); /* * There dummy delay is calculated. @@ -369,15 +341,11 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) if (result) return result; if (i == (msgs->len - 1)) { - /* It must generate STOP before read I2DR to prevent - controller from generating another clock cycle */ dev_dbg(&i2c_imx->adapter.dev, "<%s> clear MSTA\n", __func__); temp = readb(i2c_imx->base + IMX_I2C_I2CR); - temp &= ~(I2CR_MSTA | I2CR_MTX); + temp &= ~I2CR_MSTA; writeb(temp, i2c_imx->base + IMX_I2C_I2CR); - i2c_imx_bus_busy(i2c_imx, 0); - i2c_imx->stopped = 1; } else if (i == (msgs->len - 2)) { dev_dbg(&i2c_imx->adapter.dev, "<%s> set TXAK\n", __func__); @@ -402,11 +370,14 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter, dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - /* Start I2C transfer */ - result = i2c_imx_start(i2c_imx); + /* Check if i2c bus is not busy */ + result = i2c_imx_bus_busy(i2c_imx); if (result) goto fail0; + /* Start I2C transfer */ + i2c_imx_start(i2c_imx); + /* read/write data */ for (i = 0; i < num; i++) { if (i) { @@ -415,9 +386,6 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter, temp = readb(i2c_imx->base + IMX_I2C_I2CR); temp |= I2CR_RSTA; writeb(temp, i2c_imx->base + IMX_I2C_I2CR); - result = i2c_imx_bus_busy(i2c_imx, 1); - if (result) - goto fail0; } dev_dbg(&i2c_imx->adapter.dev, "<%s> transfer message: %d\n", __func__, i); @@ -532,6 +500,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev) dev_err(&pdev->dev, "can't get I2C clock\n"); goto fail3; } + clk_enable(i2c_imx->clk); /* Request IRQ */ ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx); @@ -580,6 +549,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev) fail5: free_irq(i2c_imx->irq, i2c_imx); fail4: + clk_disable(i2c_imx->clk); clk_put(i2c_imx->clk); fail3: release_mem_region(i2c_imx->res->start, resource_size(res)); @@ -616,6 +586,8 @@ static int __exit i2c_imx_remove(struct platform_device *pdev) if (pdata && pdata->exit) pdata->exit(&pdev->dev); + /* Disable I2C clock */ + clk_disable(i2c_imx->clk); clk_put(i2c_imx->clk); release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res)); diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index f627001108b8..d325e86e3103 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -365,6 +365,9 @@ static int mpc_write(struct mpc_i2c *i2c, int target, unsigned timeout = i2c->adap.timeout; u32 flags = restart ? CCR_RSTA : 0; + /* Start with MEN */ + if (!restart) + writeccr(i2c, CCR_MEN); /* Start as master */ writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); /* Write target byte */ @@ -393,6 +396,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target, int i, result; u32 flags = restart ? CCR_RSTA : 0; + /* Start with MEN */ + if (!restart) + writeccr(i2c, CCR_MEN); /* Switch to read - restart */ writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); /* Write target address byte - this time with the read flag set */ @@ -419,9 +425,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target, /* Generate txack on next to last byte */ if (i == length - 2) writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK); - /* Do not generate stop on last byte */ + /* Generate stop on last byte */ if (i == length - 1) - writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX); + writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK); data[i] = readb(i2c->base + MPC_I2C_DR); } diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 4452eabbee6d..a6512372c7a3 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -233,7 +233,6 @@ struct atkbd { */ static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); static void *atkbd_platform_fixup_data; -static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)); @@ -394,9 +393,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, input_event(dev, EV_MSC, MSC_RAW, code); - if (atkbd_platform_scancode_fixup) - code = atkbd_platform_scancode_fixup(atkbd, code); - if (atkbd->translated) { if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) { @@ -926,22 +922,6 @@ static unsigned int atkbd_volume_forced_release_keys[] = { 0xae, 0xb0, -1U }; -/* - * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas - * they should be generating e4-e6 (0x80 | code). - */ -static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd, - unsigned int code) -{ - if (atkbd->translated && atkbd->emul == 1 && - (code == 0x64 || code == 0x65 || code == 0x66)) { - atkbd->emul = 0; - code |= 0x80; - } - - return code; -} - /* * atkbd_set_keycode_table() initializes keyboard's keycode table * according to the selected scancode set @@ -1547,13 +1527,6 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) return 0; } -static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) -{ - atkbd_platform_scancode_fixup = id->driver_data; - - return 0; -} - static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { { .ident = "Dell Laptop", @@ -1690,15 +1663,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { .callback = atkbd_setup_forced_release, .driver_data = atkdb_soltech_ta12_forced_release_keys, }, - { - .ident = "OQO Model 01+", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "OQO"), - DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), - }, - .callback = atkbd_setup_scancode_fixup, - .driver_data = atkbd_oqo_01plus_scancode_fixup, - }, { } }; diff --git a/trunk/drivers/input/keyboard/gpio_keys.c b/trunk/drivers/input/keyboard/gpio_keys.c index 77d130914259..a88aff3816a0 100644 --- a/trunk/drivers/input/keyboard/gpio_keys.c +++ b/trunk/drivers/input/keyboard/gpio_keys.c @@ -147,7 +147,6 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) } error = request_irq(irq, gpio_keys_isr, - IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, button->desc ? button->desc : "gpio_keys", bdata); diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index a9bb2544b2de..02f4f8f1db6f 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -227,7 +227,6 @@ config INPUT_WINBOND_CIR depends on X86 && PNP select NEW_LEDS select LEDS_CLASS - select LEDS_TRIGGERS select BITREVERSE help Say Y here if you want to use the IR remote functionality found diff --git a/trunk/drivers/input/serio/i8042.c b/trunk/drivers/input/serio/i8042.c index 1df02d25aca5..a31578170ccc 100644 --- a/trunk/drivers/input/serio/i8042.c +++ b/trunk/drivers/input/serio/i8042.c @@ -836,32 +836,17 @@ static int i8042_controller_selftest(void) static int i8042_controller_init(void) { unsigned long flags; - int n = 0; - unsigned char ctr[2]; /* - * Save the CTR for restore on unload / reboot. + * Save the CTR for restoral on unload / reboot. */ - do { - if (n >= 10) { - printk(KERN_ERR - "i8042.c: Unable to get stable CTR read.\n"); - return -EIO; - } - - if (n != 0) - udelay(50); - - if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { - printk(KERN_ERR - "i8042.c: Can't read CTR while initializing i8042.\n"); - return -EIO; - } - - } while (n < 2 || ctr[0] != ctr[1]); + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { + printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n"); + return -EIO; + } - i8042_initial_ctr = i8042_ctr = ctr[0]; + i8042_initial_ctr = i8042_ctr; /* * Disable the keyboard interface and interrupt. @@ -910,12 +895,6 @@ static int i8042_controller_init(void) return -EIO; } -/* - * Flush whatever accumulated while we were disabling keyboard port. - */ - - i8042_flush(); - return 0; } @@ -935,7 +914,7 @@ static void i8042_controller_reset(void) i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); - if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) + if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n"); /* diff --git a/trunk/drivers/md/Makefile b/trunk/drivers/md/Makefile index e355e7f6a536..1dc4185bd781 100644 --- a/trunk/drivers/md/Makefile +++ b/trunk/drivers/md/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o obj-$(CONFIG_DM_ZERO) += dm-zero.o quiet_cmd_unroll = UNROLL $@ - cmd_unroll = $(AWK) -f$(srctree)/$(src)/unroll.awk -vN=$(UNROLL) \ + cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \ < $< > $@ || ( rm -f $@ && exit 1 ) ifeq ($(CONFIG_ALTIVEC),y) @@ -59,56 +59,56 @@ endif targets += raid6int1.c $(obj)/raid6int1.c: UNROLL := 1 -$(obj)/raid6int1.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE +$(obj)/raid6int1.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) targets += raid6int2.c $(obj)/raid6int2.c: UNROLL := 2 -$(obj)/raid6int2.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE +$(obj)/raid6int2.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) targets += raid6int4.c $(obj)/raid6int4.c: UNROLL := 4 -$(obj)/raid6int4.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE +$(obj)/raid6int4.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) targets += raid6int8.c $(obj)/raid6int8.c: UNROLL := 8 -$(obj)/raid6int8.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE +$(obj)/raid6int8.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) targets += raid6int16.c $(obj)/raid6int16.c: UNROLL := 16 -$(obj)/raid6int16.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE +$(obj)/raid6int16.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) targets += raid6int32.c $(obj)/raid6int32.c: UNROLL := 32 -$(obj)/raid6int32.c: $(src)/raid6int.uc $(src)/unroll.awk FORCE +$(obj)/raid6int32.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) CFLAGS_raid6altivec1.o += $(altivec_flags) targets += raid6altivec1.c $(obj)/raid6altivec1.c: UNROLL := 1 -$(obj)/raid6altivec1.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE +$(obj)/raid6altivec1.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) CFLAGS_raid6altivec2.o += $(altivec_flags) targets += raid6altivec2.c $(obj)/raid6altivec2.c: UNROLL := 2 -$(obj)/raid6altivec2.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE +$(obj)/raid6altivec2.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) CFLAGS_raid6altivec4.o += $(altivec_flags) targets += raid6altivec4.c $(obj)/raid6altivec4.c: UNROLL := 4 -$(obj)/raid6altivec4.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE +$(obj)/raid6altivec4.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) CFLAGS_raid6altivec8.o += $(altivec_flags) targets += raid6altivec8.c $(obj)/raid6altivec8.c: UNROLL := 8 -$(obj)/raid6altivec8.c: $(src)/raid6altivec.uc $(src)/unroll.awk FORCE +$(obj)/raid6altivec8.c: $(src)/raid6altivec.uc $(src)/unroll.pl FORCE $(call if_changed,unroll) quiet_cmd_mktable = TABLE $@ diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 60e2b322db11..6986b0059d23 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1624,11 +1624,10 @@ int bitmap_create(mddev_t *mddev) bitmap->offset = mddev->bitmap_offset; if (file) { get_file(file); - /* As future accesses to this file will use bmap, - * and bypass the page cache, we must sync the file - * first. - */ - vfs_fsync(file, file->f_dentry, 1); + do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX, + SYNC_FILE_RANGE_WAIT_BEFORE | + SYNC_FILE_RANGE_WRITE | + SYNC_FILE_RANGE_WAIT_AFTER); } /* read superblock from bitmap file (this sets bitmap->chunksize) */ err = bitmap_read_sb(bitmap); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 10eb1fce975e..26ba42a79129 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -2631,7 +2631,7 @@ static void analyze_sbs(mddev_t * mddev) rdev->desc_nr = i++; rdev->raid_disk = rdev->desc_nr; set_bit(In_sync, &rdev->flags); - } else if (rdev->raid_disk >= (mddev->raid_disks - min(0, mddev->delta_disks))) { + } else if (rdev->raid_disk >= mddev->raid_disks) { rdev->raid_disk = -1; clear_bit(In_sync, &rdev->flags); } diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index a053423785c9..d1b9bd5fd4f6 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -64,7 +64,7 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) /* allocate a r1bio with room for raid_disks entries in the bios array */ r1_bio = kzalloc(size, gfp_flags); - if (!r1_bio && pi->mddev) + if (!r1_bio) unplug_slaves(pi->mddev); return r1_bio; @@ -1683,7 +1683,6 @@ static void raid1d(mddev_t *mddev) generic_make_request(bio); } } - cond_resched(); } if (unplug) unplug_slaves(mddev); @@ -1979,14 +1978,13 @@ static int run(mddev_t *mddev) conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL); if (!conf->poolinfo) goto out_no_mem; - conf->poolinfo->mddev = NULL; + conf->poolinfo->mddev = mddev; conf->poolinfo->raid_disks = mddev->raid_disks; conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc, r1bio_pool_free, conf->poolinfo); if (!conf->r1bio_pool) goto out_no_mem; - conf->poolinfo->mddev = mddev; spin_lock_init(&conf->device_lock); mddev->queue->queue_lock = &conf->device_lock; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index c2cb7b87b440..51c4c5c4d87a 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -68,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data) /* allocate a r10bio with room for raid_disks entries in the bios array */ r10_bio = kzalloc(size, gfp_flags); - if (!r10_bio && conf->mddev) + if (!r10_bio) unplug_slaves(conf->mddev); return r10_bio; @@ -1632,7 +1632,6 @@ static void raid10d(mddev_t *mddev) generic_make_request(bio); } } - cond_resched(); } if (unplug) unplug_slaves(mddev); @@ -2096,6 +2095,7 @@ static int run(mddev_t *mddev) if (!conf->tmppage) goto out_free_conf; + conf->mddev = mddev; conf->raid_disks = mddev->raid_disks; conf->near_copies = nc; conf->far_copies = fc; @@ -2132,7 +2132,6 @@ static int run(mddev_t *mddev) goto out_free_conf; } - conf->mddev = mddev; spin_lock_init(&conf->device_lock); mddev->queue->queue_lock = &conf->device_lock; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 81abefc172d9..94829804ab7f 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -156,16 +156,13 @@ static inline int raid6_next_disk(int disk, int raid_disks) static int raid6_idx_to_slot(int idx, struct stripe_head *sh, int *count, int syndrome_disks) { - int slot = *count; + int slot; - if (sh->ddf_layout) - (*count)++; if (idx == sh->pd_idx) return syndrome_disks; if (idx == sh->qd_idx) return syndrome_disks + 1; - if (!sh->ddf_layout) - (*count)++; + slot = (*count)++; return slot; } @@ -720,7 +717,7 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh) int i; for (i = 0; i < disks; i++) - srcs[i] = NULL; + srcs[i] = (void *)raid6_empty_zero_page; count = 0; i = d0_idx; @@ -730,8 +727,9 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh) srcs[slot] = sh->dev[i].page; i = raid6_next_disk(i, disks); } while (i != d0_idx); + BUG_ON(count != syndrome_disks); - return syndrome_disks; + return count; } static struct dma_async_tx_descriptor * @@ -816,7 +814,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) * slot number conversion for 'faila' and 'failb' */ for (i = 0; i < disks ; i++) - blocks[i] = NULL; + blocks[i] = (void *)raid6_empty_zero_page; count = 0; i = d0_idx; do { @@ -830,6 +828,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) failb = slot; i = raid6_next_disk(i, disks); } while (i != d0_idx); + BUG_ON(count != syndrome_disks); BUG_ON(faila == failb); if (failb < faila) @@ -846,7 +845,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) init_async_submit(&submit, ASYNC_TX_FENCE, NULL, ops_complete_compute, sh, to_addr_conv(sh, percpu)); - return async_gen_syndrome(blocks, 0, syndrome_disks+2, + return async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE, &submit); } else { struct page *dest; @@ -1140,7 +1139,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu &sh->ops.zero_sum_result, percpu->spare_page, &submit); } -static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request) +static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) { int overlap_clear = 0, i, disks = sh->disks; struct dma_async_tx_descriptor *tx = NULL; @@ -1205,55 +1204,22 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request) put_cpu(); } -#ifdef CONFIG_MULTICORE_RAID456 -static void async_run_ops(void *param, async_cookie_t cookie) -{ - struct stripe_head *sh = param; - unsigned long ops_request = sh->ops.request; - - clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state); - wake_up(&sh->ops.wait_for_ops); - - __raid_run_ops(sh, ops_request); - release_stripe(sh); -} - -static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) -{ - /* since handle_stripe can be called outside of raid5d context - * we need to ensure sh->ops.request is de-staged before another - * request arrives - */ - wait_event(sh->ops.wait_for_ops, - !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state)); - sh->ops.request = ops_request; - - atomic_inc(&sh->count); - async_schedule(async_run_ops, sh); -} -#else -#define raid_run_ops __raid_run_ops -#endif - static int grow_one_stripe(raid5_conf_t *conf) { struct stripe_head *sh; - int disks = max(conf->raid_disks, conf->previous_raid_disks); sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL); if (!sh) return 0; - memset(sh, 0, sizeof(*sh) + (disks-1)*sizeof(struct r5dev)); + memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev)); sh->raid_conf = conf; spin_lock_init(&sh->lock); - #ifdef CONFIG_MULTICORE_RAID456 - init_waitqueue_head(&sh->ops.wait_for_ops); - #endif - if (grow_buffers(sh, disks)) { - shrink_buffers(sh, disks); + if (grow_buffers(sh, conf->raid_disks)) { + shrink_buffers(sh, conf->raid_disks); kmem_cache_free(conf->slab_cache, sh); return 0; } + sh->disks = conf->raid_disks; /* we just created an active stripe so... */ atomic_set(&sh->count, 1); atomic_inc(&conf->active_stripes); @@ -1265,7 +1231,7 @@ static int grow_one_stripe(raid5_conf_t *conf) static int grow_stripes(raid5_conf_t *conf, int num) { struct kmem_cache *sc; - int devs = max(conf->raid_disks, conf->previous_raid_disks); + int devs = conf->raid_disks; sprintf(conf->cache_name[0], "raid%d-%s", conf->level, mdname(conf->mddev)); @@ -1363,9 +1329,6 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) nsh->raid_conf = conf; spin_lock_init(&nsh->lock); - #ifdef CONFIG_MULTICORE_RAID456 - init_waitqueue_head(&nsh->ops.wait_for_ops); - #endif list_add(&nsh->lru, &newstripes); } @@ -1936,15 +1899,10 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) case ALGORITHM_PARITY_N: break; case ALGORITHM_ROTATING_N_CONTINUE: - /* Like left_symmetric, but P is before Q */ if (sh->pd_idx == 0) i--; /* P D D D Q */ - else { - /* D D Q P D */ - if (i < sh->pd_idx) - i += raid_disks; - i -= (sh->pd_idx + 1); - } + else if (i > sh->pd_idx) + i -= 2; /* D D Q P D */ break; case ALGORITHM_LEFT_ASYMMETRIC_6: case ALGORITHM_RIGHT_ASYMMETRIC_6: @@ -2938,7 +2896,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh, * */ -static void handle_stripe5(struct stripe_head *sh) +static bool handle_stripe5(struct stripe_head *sh) { raid5_conf_t *conf = sh->raid_conf; int disks = sh->disks, i; @@ -3209,9 +3167,11 @@ static void handle_stripe5(struct stripe_head *sh) ops_run_io(sh, &s); return_io(return_bi); + + return blocked_rdev == NULL; } -static void handle_stripe6(struct stripe_head *sh) +static bool handle_stripe6(struct stripe_head *sh) { raid5_conf_t *conf = sh->raid_conf; int disks = sh->disks; @@ -3495,14 +3455,17 @@ static void handle_stripe6(struct stripe_head *sh) ops_run_io(sh, &s); return_io(return_bi); + + return blocked_rdev == NULL; } -static void handle_stripe(struct stripe_head *sh) +/* returns true if the stripe was handled */ +static bool handle_stripe(struct stripe_head *sh) { if (sh->raid_conf->level == 6) - handle_stripe6(sh); + return handle_stripe6(sh); else - handle_stripe5(sh); + return handle_stripe5(sh); } static void raid5_activate_delayed(raid5_conf_t *conf) @@ -3540,10 +3503,9 @@ static void unplug_slaves(mddev_t *mddev) { raid5_conf_t *conf = mddev->private; int i; - int devs = max(conf->raid_disks, conf->previous_raid_disks); rcu_read_lock(); - for (i = 0; i < devs; i++) { + for (i = 0; i < conf->raid_disks; i++) { mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { struct request_queue *r_queue = bdev_get_queue(rdev->bdev); @@ -4315,7 +4277,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski clear_bit(STRIPE_INSYNC, &sh->state); spin_unlock(&sh->lock); - handle_stripe(sh); + /* wait for any blocked device to be handled */ + while (unlikely(!handle_stripe(sh))) + ; release_stripe(sh); return STRIPE_SECTORS; @@ -4385,6 +4349,37 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) return handled; } +#ifdef CONFIG_MULTICORE_RAID456 +static void __process_stripe(void *param, async_cookie_t cookie) +{ + struct stripe_head *sh = param; + + handle_stripe(sh); + release_stripe(sh); +} + +static void process_stripe(struct stripe_head *sh, struct list_head *domain) +{ + async_schedule_domain(__process_stripe, sh, domain); +} + +static void synchronize_stripe_processing(struct list_head *domain) +{ + async_synchronize_full_domain(domain); +} +#else +static void process_stripe(struct stripe_head *sh, struct list_head *domain) +{ + handle_stripe(sh); + release_stripe(sh); + cond_resched(); +} + +static void synchronize_stripe_processing(struct list_head *domain) +{ +} +#endif + /* * This is our raid5 kernel thread. @@ -4398,6 +4393,7 @@ static void raid5d(mddev_t *mddev) struct stripe_head *sh; raid5_conf_t *conf = mddev->private; int handled; + LIST_HEAD(raid_domain); pr_debug("+++ raid5d active\n"); @@ -4434,9 +4430,7 @@ static void raid5d(mddev_t *mddev) spin_unlock_irq(&conf->device_lock); handled++; - handle_stripe(sh); - release_stripe(sh); - cond_resched(); + process_stripe(sh, &raid_domain); spin_lock_irq(&conf->device_lock); } @@ -4444,6 +4438,7 @@ static void raid5d(mddev_t *mddev) spin_unlock_irq(&conf->device_lock); + synchronize_stripe_processing(&raid_domain); async_tx_issue_pending_all(); unplug_slaves(mddev); @@ -4563,9 +4558,13 @@ raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks) if (!sectors) sectors = mddev->dev_sectors; - if (!raid_disks) + if (!raid_disks) { /* size is defined by the smallest of previous and new size */ - raid_disks = min(conf->raid_disks, conf->previous_raid_disks); + if (conf->raid_disks < conf->previous_raid_disks) + raid_disks = conf->raid_disks; + else + raid_disks = conf->previous_raid_disks; + } sectors &= ~((sector_t)mddev->chunk_sectors - 1); sectors &= ~((sector_t)mddev->new_chunk_sectors - 1); @@ -4666,7 +4665,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf) } per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page; } - scribble = kmalloc(conf->scribble_len, GFP_KERNEL); + scribble = kmalloc(scribble_len(conf->raid_disks), GFP_KERNEL); if (!scribble) { err = -ENOMEM; break; @@ -4687,7 +4686,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf) static raid5_conf_t *setup_conf(mddev_t *mddev) { raid5_conf_t *conf; - int raid_disk, memory, max_disks; + int raid_disk, memory; mdk_rdev_t *rdev; struct disk_info *disk; @@ -4723,28 +4722,15 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL); if (conf == NULL) goto abort; - spin_lock_init(&conf->device_lock); - init_waitqueue_head(&conf->wait_for_stripe); - init_waitqueue_head(&conf->wait_for_overlap); - INIT_LIST_HEAD(&conf->handle_list); - INIT_LIST_HEAD(&conf->hold_list); - INIT_LIST_HEAD(&conf->delayed_list); - INIT_LIST_HEAD(&conf->bitmap_list); - INIT_LIST_HEAD(&conf->inactive_list); - atomic_set(&conf->active_stripes, 0); - atomic_set(&conf->preread_active_stripes, 0); - atomic_set(&conf->active_aligned_reads, 0); - conf->bypass_threshold = BYPASS_THRESHOLD; conf->raid_disks = mddev->raid_disks; + conf->scribble_len = scribble_len(conf->raid_disks); if (mddev->reshape_position == MaxSector) conf->previous_raid_disks = mddev->raid_disks; else conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks; - max_disks = max(conf->raid_disks, conf->previous_raid_disks); - conf->scribble_len = scribble_len(max_disks); - conf->disks = kzalloc(max_disks * sizeof(struct disk_info), + conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info), GFP_KERNEL); if (!conf->disks) goto abort; @@ -4758,11 +4744,24 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) if (raid5_alloc_percpu(conf) != 0) goto abort; + spin_lock_init(&conf->device_lock); + init_waitqueue_head(&conf->wait_for_stripe); + init_waitqueue_head(&conf->wait_for_overlap); + INIT_LIST_HEAD(&conf->handle_list); + INIT_LIST_HEAD(&conf->hold_list); + INIT_LIST_HEAD(&conf->delayed_list); + INIT_LIST_HEAD(&conf->bitmap_list); + INIT_LIST_HEAD(&conf->inactive_list); + atomic_set(&conf->active_stripes, 0); + atomic_set(&conf->preread_active_stripes, 0); + atomic_set(&conf->active_aligned_reads, 0); + conf->bypass_threshold = BYPASS_THRESHOLD; + pr_debug("raid5: run(%s) called.\n", mdname(mddev)); list_for_each_entry(rdev, &mddev->disks, same_set) { raid_disk = rdev->raid_disk; - if (raid_disk >= max_disks + if (raid_disk >= conf->raid_disks || raid_disk < 0) continue; disk = conf->disks + raid_disk; @@ -4794,7 +4793,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) } memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + - max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; + conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; if (grow_stripes(conf, conf->max_nr_stripes)) { printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory); @@ -4919,8 +4918,7 @@ static int run(mddev_t *mddev) test_bit(In_sync, &rdev->flags)) working_disks++; - mddev->degraded = (max(conf->raid_disks, conf->previous_raid_disks) - - working_disks); + mddev->degraded = conf->raid_disks - working_disks; if (mddev->degraded > conf->max_degraded) { printk(KERN_ERR "raid5: not enough operational devices for %s" diff --git a/trunk/drivers/md/raid5.h b/trunk/drivers/md/raid5.h index dd708359b451..2390e0e83daf 100644 --- a/trunk/drivers/md/raid5.h +++ b/trunk/drivers/md/raid5.h @@ -214,20 +214,12 @@ struct stripe_head { int disks; /* disks in stripe */ enum check_states check_state; enum reconstruct_states reconstruct_state; - /** - * struct stripe_operations + /* stripe_operations * @target - STRIPE_OP_COMPUTE_BLK target - * @target2 - 2nd compute target in the raid6 case - * @zero_sum_result - P and Q verification flags - * @request - async service request flags for raid_run_ops */ struct stripe_operations { int target, target2; enum sum_check_flags zero_sum_result; - #ifdef CONFIG_MULTICORE_RAID456 - unsigned long request; - wait_queue_head_t wait_for_ops; - #endif } ops; struct r5dev { struct bio req; @@ -302,8 +294,6 @@ struct r6_state { #define STRIPE_FULL_WRITE 13 /* all blocks are set to be overwritten */ #define STRIPE_BIOFILL_RUN 14 #define STRIPE_COMPUTE_RUN 15 -#define STRIPE_OPS_REQ_PENDING 16 - /* * Operation request flags */ @@ -488,7 +478,7 @@ static inline int algorithm_valid_raid6(int layout) { return (layout >= 0 && layout <= 5) || - (layout >= 8 && layout <= 10) + (layout == 8 || layout == 10) || (layout >= 16 && layout <= 20); } diff --git a/trunk/drivers/md/raid6altivec.uc b/trunk/drivers/md/raid6altivec.uc index 2654d5c854be..699dfeee4944 100644 --- a/trunk/drivers/md/raid6altivec.uc +++ b/trunk/drivers/md/raid6altivec.uc @@ -15,7 +15,7 @@ * * $#-way unrolled portable integer math RAID-6 instruction set * - * This file is postprocessed using unroll.awk + * This file is postprocessed using unroll.pl * * hpa: in process, * you can just "steal" the vec unit with enable_kernel_altivec() (but diff --git a/trunk/drivers/md/raid6int.uc b/trunk/drivers/md/raid6int.uc index d1e276a14fab..f9bf9cba357f 100644 --- a/trunk/drivers/md/raid6int.uc +++ b/trunk/drivers/md/raid6int.uc @@ -15,7 +15,7 @@ * * $#-way unrolled portable integer math RAID-6 instruction set * - * This file is postprocessed using unroll.awk + * This file is postprocessed using unroll.pl */ #include diff --git a/trunk/drivers/md/raid6test/Makefile b/trunk/drivers/md/raid6test/Makefile index 2874cbef529d..58ffdf4f5161 100644 --- a/trunk/drivers/md/raid6test/Makefile +++ b/trunk/drivers/md/raid6test/Makefile @@ -7,7 +7,7 @@ CC = gcc OPTFLAGS = -O2 # Adjust as desired CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS) LD = ld -AWK = awk +PERL = perl AR = ar RANLIB = ranlib @@ -35,35 +35,35 @@ raid6.a: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \ raid6test: test.c raid6.a $(CC) $(CFLAGS) -o raid6test $^ -raid6altivec1.c: raid6altivec.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=1 < raid6altivec.uc > $@ +raid6altivec1.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 1 < raid6altivec.uc > $@ -raid6altivec2.c: raid6altivec.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=2 < raid6altivec.uc > $@ +raid6altivec2.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 2 < raid6altivec.uc > $@ -raid6altivec4.c: raid6altivec.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=4 < raid6altivec.uc > $@ +raid6altivec4.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 4 < raid6altivec.uc > $@ -raid6altivec8.c: raid6altivec.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=8 < raid6altivec.uc > $@ +raid6altivec8.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 8 < raid6altivec.uc > $@ -raid6int1.c: raid6int.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=1 < raid6int.uc > $@ +raid6int1.c: raid6int.uc ../unroll.pl + $(PERL) ../unroll.pl 1 < raid6int.uc > $@ -raid6int2.c: raid6int.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=2 < raid6int.uc > $@ +raid6int2.c: raid6int.uc ../unroll.pl + $(PERL) ../unroll.pl 2 < raid6int.uc > $@ -raid6int4.c: raid6int.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=4 < raid6int.uc > $@ +raid6int4.c: raid6int.uc ../unroll.pl + $(PERL) ../unroll.pl 4 < raid6int.uc > $@ -raid6int8.c: raid6int.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=8 < raid6int.uc > $@ +raid6int8.c: raid6int.uc ../unroll.pl + $(PERL) ../unroll.pl 8 < raid6int.uc > $@ -raid6int16.c: raid6int.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=16 < raid6int.uc > $@ +raid6int16.c: raid6int.uc ../unroll.pl + $(PERL) ../unroll.pl 16 < raid6int.uc > $@ -raid6int32.c: raid6int.uc ../unroll.awk - $(AWK) ../unroll.awk -vN=32 < raid6int.uc > $@ +raid6int32.c: raid6int.uc ../unroll.pl + $(PERL) ../unroll.pl 32 < raid6int.uc > $@ raid6tables.c: mktables ./mktables > raid6tables.c diff --git a/trunk/drivers/md/unroll.awk b/trunk/drivers/md/unroll.awk deleted file mode 100644 index c6aa03631df8..000000000000 --- a/trunk/drivers/md/unroll.awk +++ /dev/null @@ -1,20 +0,0 @@ - -# This filter requires one command line option of form -vN=n -# where n must be a decimal number. -# -# Repeat each input line containing $$ n times, replacing $$ with 0...n-1. -# Replace each $# with n, and each $* with a single $. - -BEGIN { - n = N + 0 -} -{ - if (/\$\$/) { rep = n } else { rep = 1 } - for (i = 0; i < rep; ++i) { - tmp = $0 - gsub(/\$\$/, i, tmp) - gsub(/\$\#/, n, tmp) - gsub(/\$\*/, "$", tmp) - print tmp - } -} diff --git a/trunk/drivers/md/unroll.pl b/trunk/drivers/md/unroll.pl new file mode 100644 index 000000000000..3acc710a20ea --- /dev/null +++ b/trunk/drivers/md/unroll.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +# +# Take a piece of C code and for each line which contains the sequence $$ +# repeat n times with $ replaced by 0...n-1; the sequence $# is replaced +# by the unrolling factor, and $* with a single $ +# + +($n) = @ARGV; +$n += 0; + +while ( defined($line = ) ) { + if ( $line =~ /\$\$/ ) { + $rep = $n; + } else { + $rep = 1; + } + for ( $i = 0 ; $i < $rep ; $i++ ) { + $tmp = $line; + $tmp =~ s/\$\$/$i/g; + $tmp =~ s/\$\#/$n/g; + $tmp =~ s/\$\*/\$/g; + print $tmp; + } +} diff --git a/trunk/drivers/misc/sgi-gru/gruprocfs.c b/trunk/drivers/misc/sgi-gru/gruprocfs.c index 3f2375c5ba5b..ccd4408a26c7 100644 --- a/trunk/drivers/misc/sgi-gru/gruprocfs.c +++ b/trunk/drivers/misc/sgi-gru/gruprocfs.c @@ -161,15 +161,14 @@ static int options_show(struct seq_file *s, void *p) static ssize_t options_write(struct file *file, const char __user *userbuf, size_t count, loff_t *data) { - char buf[20]; + unsigned long val; + char buf[80]; - if (count >= sizeof(buf)) - return -EINVAL; - if (copy_from_user(buf, userbuf, count)) + if (strncpy_from_user(buf, userbuf, sizeof(buf) - 1) < 0) return -EFAULT; - buf[count] = '\0'; - if (strict_strtoul(buf, 0, &gru_options)) - return -EINVAL; + buf[count - 1] = '\0'; + if (!strict_strtoul(buf, 10, &val)) + gru_options = val; return count; } diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 3c29a20b751e..5d2f48f02251 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1427,31 +1427,19 @@ static int e100_phy_init(struct nic *nic) } else DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); + /* Isolate all the PHY ids */ + for (addr = 0; addr < 32; addr++) + mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); + /* Select the discovered PHY */ + bmcr &= ~BMCR_ISOLATE; + mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); + /* Get phy ID */ id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1); id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2); nic->phy = (u32)id_hi << 16 | (u32)id_lo; DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); - /* Select the phy and isolate the rest */ - for (addr = 0; addr < 32; addr++) { - if (addr != nic->mii.phy_id) { - mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); - } else if (nic->phy != phy_82552_v) { - bmcr = mdio_read(netdev, addr, MII_BMCR); - mdio_write(netdev, addr, MII_BMCR, - bmcr & ~BMCR_ISOLATE); - } - } - /* - * Workaround for 82552: - * Clear the ISOLATE bit on selected phy_id last (mirrored on all - * other phy_id's) using bmcr value from addr discovery loop above. - */ - if (nic->phy == phy_82552_v) - mdio_write(netdev, nic->mii.phy_id, MII_BMCR, - bmcr & ~BMCR_ISOLATE); - /* Handle National tx phys */ #define NCS_PHY_MODEL_MASK 0xFFF0FFFF if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { diff --git a/trunk/drivers/net/e1000e/defines.h b/trunk/drivers/net/e1000e/defines.h index 1190167a8b3d..c0f185beb8bc 100644 --- a/trunk/drivers/net/e1000e/defines.h +++ b/trunk/drivers/net/e1000e/defines.h @@ -76,7 +76,6 @@ /* Extended Device Control */ #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ -#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 @@ -348,7 +347,6 @@ /* Extended Configuration Control and Size */ #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 #define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 -#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 #define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 diff --git a/trunk/drivers/net/e1000e/e1000.h b/trunk/drivers/net/e1000e/e1000.h index 189dfa2d6c76..405a144ebcad 100644 --- a/trunk/drivers/net/e1000e/e1000.h +++ b/trunk/drivers/net/e1000e/e1000.h @@ -141,20 +141,6 @@ struct e1000_info; #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ #define HV_TNCRS_LOWER PHY_REG(778, 30) -/* BM PHY Copper Specific Status */ -#define BM_CS_STATUS 17 -#define BM_CS_STATUS_LINK_UP 0x0400 -#define BM_CS_STATUS_RESOLVED 0x0800 -#define BM_CS_STATUS_SPEED_MASK 0xC000 -#define BM_CS_STATUS_SPEED_1000 0x8000 - -/* 82577 Mobile Phy Status Register */ -#define HV_M_STATUS 26 -#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 -#define HV_M_STATUS_SPEED_MASK 0x0300 -#define HV_M_STATUS_SPEED_1000 0x0200 -#define HV_M_STATUS_LINK_UP 0x0040 - enum e1000_boards { board_82571, board_82572, diff --git a/trunk/drivers/net/e1000e/hw.h b/trunk/drivers/net/e1000e/hw.h index aaea41ef794d..7b05cf47f7f5 100644 --- a/trunk/drivers/net/e1000e/hw.h +++ b/trunk/drivers/net/e1000e/hw.h @@ -903,7 +903,6 @@ struct e1000_shadow_ram { struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; - bool nvm_k1_enabled; }; struct e1000_hw { diff --git a/trunk/drivers/net/e1000e/ich8lan.c b/trunk/drivers/net/e1000e/ich8lan.c index 51ddb04ab195..b6388b9535fd 100644 --- a/trunk/drivers/net/e1000e/ich8lan.c +++ b/trunk/drivers/net/e1000e/ich8lan.c @@ -124,25 +124,11 @@ #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */ -/* SMBus Address Phy Register */ -#define HV_SMB_ADDR PHY_REG(768, 26) -#define HV_SMB_ADDR_PEC_EN 0x0200 -#define HV_SMB_ADDR_VALID 0x0080 - -/* Strapping Option Register - RO */ -#define E1000_STRAP 0x0000C -#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 -#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 - /* OEM Bits Phy Register */ #define HV_OEM_BITS PHY_REG(768, 25) #define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ -#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ #define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ -#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ -#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ - /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { @@ -222,9 +208,6 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); static s32 e1000_led_on_pchlan(struct e1000_hw *hw); static s32 e1000_led_off_pchlan(struct e1000_hw *hw); static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); -static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); -static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); -static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) { @@ -500,6 +483,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) goto out; } + if (hw->mac.type == e1000_pchlan) { + ret_val = e1000e_write_kmrn_reg(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + E1000_KMRNCTRLSTA_K1_ENABLE); + if (ret_val) + goto out; + } + /* * First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex @@ -509,12 +500,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) goto out; - if (hw->mac.type == e1000_pchlan) { - ret_val = e1000_k1_gig_workaround_hv(hw, link); - if (ret_val) - goto out; - } - if (!link) goto out; /* No link detected */ @@ -808,326 +793,6 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) return 0; } -/** - * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration - * @hw: pointer to the HW structure - * - * SW should configure the LCD from the NVM extended configuration region - * as a workaround for certain parts. - **/ -static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; - s32 ret_val; - u16 word_addr, reg_data, reg_addr, phy_page = 0; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - - /* - * Initialize the PHY from the NVM on ICH platforms. This - * is needed due to an issue where the NVM configuration is - * not properly autoloaded after power transitions. - * Therefore, after each PHY reset, we will load the - * configuration data out of the NVM manually. - */ - if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) || - (hw->mac.type == e1000_pchlan)) { - struct e1000_adapter *adapter = hw->adapter; - - /* Check if SW needs to configure the PHY */ - if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || - (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || - (hw->mac.type == e1000_pchlan)) - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; - else - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; - - data = er32(FEXTNVM); - if (!(data & sw_cfg_mask)) - goto out; - - /* Wait for basic configuration completes before proceeding */ - e1000_lan_init_done_ich8lan(hw); - - /* - * Make sure HW does not configure LCD from PHY - * extended configuration before SW configuration - */ - data = er32(EXTCNF_CTRL); - if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) - goto out; - - cnf_size = er32(EXTCNF_SIZE); - cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; - cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; - if (!cnf_size) - goto out; - - cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; - cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; - - if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && - (hw->mac.type == e1000_pchlan)) { - /* - * HW configures the SMBus address and LEDs when the - * OEM and LCD Write Enable bits are set in the NVM. - * When both NVM bits are cleared, SW will configure - * them instead. - */ - data = er32(STRAP); - data &= E1000_STRAP_SMBUS_ADDRESS_MASK; - reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; - reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; - ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, - reg_data); - if (ret_val) - goto out; - - data = er32(LEDCTL); - ret_val = e1000_write_phy_reg_hv_locked(hw, - HV_LED_CONFIG, - (u16)data); - if (ret_val) - goto out; - } - /* Configure LCD from extended configuration region. */ - - /* cnf_base_addr is in DWORD */ - word_addr = (u16)(cnf_base_addr << 1); - - for (i = 0; i < cnf_size; i++) { - ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, - ®_data); - if (ret_val) - goto out; - - ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1), - 1, ®_addr); - if (ret_val) - goto out; - - /* Save off the PHY page for future writes. */ - if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { - phy_page = reg_data; - continue; - } - - reg_addr &= PHY_REG_MASK; - reg_addr |= phy_page; - - ret_val = phy->ops.write_phy_reg_locked(hw, - (u32)reg_addr, - reg_data); - if (ret_val) - goto out; - } - } - -out: - hw->phy.ops.release_phy(hw); - return ret_val; -} - -/** - * e1000_k1_gig_workaround_hv - K1 Si workaround - * @hw: pointer to the HW structure - * @link: link up bool flag - * - * If K1 is enabled for 1Gbps, the MAC might stall when transitioning - * from a lower speed. This workaround disables K1 whenever link is at 1Gig - * If link is down, the function will restore the default K1 setting located - * in the NVM. - **/ -static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) -{ - s32 ret_val = 0; - u16 status_reg = 0; - bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled; - - if (hw->mac.type != e1000_pchlan) - goto out; - - /* Wrap the whole flow with the sw flag */ - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - - /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ - if (link) { - if (hw->phy.type == e1000_phy_82578) { - ret_val = hw->phy.ops.read_phy_reg_locked(hw, - BM_CS_STATUS, - &status_reg); - if (ret_val) - goto release; - - status_reg &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; - - if (status_reg == (BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_1000)) - k1_enable = false; - } - - if (hw->phy.type == e1000_phy_82577) { - ret_val = hw->phy.ops.read_phy_reg_locked(hw, - HV_M_STATUS, - &status_reg); - if (ret_val) - goto release; - - status_reg &= HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_MASK; - - if (status_reg == (HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_1000)) - k1_enable = false; - } - - /* Link stall fix for link up */ - ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19), - 0x0100); - if (ret_val) - goto release; - - } else { - /* Link stall fix for link down */ - ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19), - 0x4100); - if (ret_val) - goto release; - } - - ret_val = e1000_configure_k1_ich8lan(hw, k1_enable); - -release: - hw->phy.ops.release_phy(hw); -out: - return ret_val; -} - -/** - * e1000_configure_k1_ich8lan - Configure K1 power state - * @hw: pointer to the HW structure - * @enable: K1 state to configure - * - * Configure the K1 power state based on the provided parameter. - * Assumes semaphore already acquired. - * - * Success returns 0, Failure returns -E1000_ERR_PHY (-2) - **/ -static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) -{ - s32 ret_val = 0; - u32 ctrl_reg = 0; - u32 ctrl_ext = 0; - u32 reg = 0; - u16 kmrn_reg = 0; - - ret_val = e1000e_read_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - &kmrn_reg); - if (ret_val) - goto out; - - if (k1_enable) - kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE; - else - kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE; - - ret_val = e1000e_write_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg); - if (ret_val) - goto out; - - udelay(20); - ctrl_ext = er32(CTRL_EXT); - ctrl_reg = er32(CTRL); - - reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); - reg |= E1000_CTRL_FRCSPD; - ew32(CTRL, reg); - - ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); - udelay(20); - ew32(CTRL, ctrl_reg); - ew32(CTRL_EXT, ctrl_ext); - udelay(20); - -out: - return ret_val; -} - -/** - * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration - * @hw: pointer to the HW structure - * @d0_state: boolean if entering d0 or d3 device state - * - * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are - * collectively called OEM bits. The OEM Write Enable bit and SW Config bit - * in NVM determines whether HW should configure LPLU and Gbe Disable. - **/ -static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) -{ - s32 ret_val = 0; - u32 mac_reg; - u16 oem_reg; - - if (hw->mac.type != e1000_pchlan) - return ret_val; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - - mac_reg = er32(EXTCNF_CTRL); - if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) - goto out; - - mac_reg = er32(FEXTNVM); - if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) - goto out; - - mac_reg = er32(PHY_CTRL); - - ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg); - if (ret_val) - goto out; - - oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); - - if (d0_state) { - if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE) - oem_reg |= HV_OEM_BITS_GBE_DIS; - - if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) - oem_reg |= HV_OEM_BITS_LPLU; - } else { - if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE) - oem_reg |= HV_OEM_BITS_GBE_DIS; - - if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU) - oem_reg |= HV_OEM_BITS_LPLU; - } - /* Restart auto-neg to activate the bits */ - oem_reg |= HV_OEM_BITS_RESTART_AN; - ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); - -out: - hw->phy.ops.release_phy(hw); - - return ret_val; -} - - /** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. @@ -1168,20 +833,10 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) ret_val = hw->phy.ops.acquire_phy(hw); if (ret_val) return ret_val; - hw->phy.addr = 1; - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); - if (ret_val) - goto out; + e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); hw->phy.ops.release_phy(hw); - /* - * Configure the K1 Si workaround during phy reset assuming there is - * link so that it disables K1 if link is in 1Gbps. - */ - ret_val = e1000_k1_gig_workaround_hv(hw, true); - -out: return ret_val; } @@ -1227,8 +882,11 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) { - s32 ret_val = 0; - u16 reg; + struct e1000_phy_info *phy = &hw->phy; + u32 i; + u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; + s32 ret_val; + u16 reg, word_addr, reg_data, reg_addr, phy_page = 0; ret_val = e1000e_phy_hw_reset_generic(hw); if (ret_val) @@ -1247,16 +905,81 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) e1e_rphy(hw, BM_WUC, ®); - /* Configure the LCD with the extended configuration region in NVM */ - ret_val = e1000_sw_lcd_config_ich8lan(hw); - if (ret_val) - goto out; + /* + * Initialize the PHY from the NVM on ICH platforms. This + * is needed due to an issue where the NVM configuration is + * not properly autoloaded after power transitions. + * Therefore, after each PHY reset, we will load the + * configuration data out of the NVM manually. + */ + if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { + struct e1000_adapter *adapter = hw->adapter; - /* Configure the LCD with the OEM bits in NVM */ - if (hw->mac.type == e1000_pchlan) - ret_val = e1000_oem_bits_config_ich8lan(hw, true); + /* Check if SW needs configure the PHY */ + if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || + (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M)) + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; + else + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + + data = er32(FEXTNVM); + if (!(data & sw_cfg_mask)) + return 0; + + /* Wait for basic configuration completes before proceeding */ + e1000_lan_init_done_ich8lan(hw); + + /* + * Make sure HW does not configure LCD from PHY + * extended configuration before SW configuration + */ + data = er32(EXTCNF_CTRL); + if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) + return 0; + + cnf_size = er32(EXTCNF_SIZE); + cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; + cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; + if (!cnf_size) + return 0; + + cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; + cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; + + /* Configure LCD from extended configuration region. */ + + /* cnf_base_addr is in DWORD */ + word_addr = (u16)(cnf_base_addr << 1); + + for (i = 0; i < cnf_size; i++) { + ret_val = e1000_read_nvm(hw, + (word_addr + i * 2), + 1, + ®_data); + if (ret_val) + return ret_val; + + ret_val = e1000_read_nvm(hw, + (word_addr + i * 2 + 1), + 1, + ®_addr); + if (ret_val) + return ret_val; + + /* Save off the PHY page for future writes. */ + if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { + phy_page = reg_data; + continue; + } + + reg_addr |= phy_page; + + ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data); + if (ret_val) + return ret_val; + } + } -out: return 0; } @@ -2583,7 +2306,6 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { - struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; u16 reg; u32 ctrl, icr, kab; s32 ret_val; @@ -2619,18 +2341,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ew32(PBS, E1000_PBS_16K); } - if (hw->mac.type == e1000_pchlan) { - /* Save the NVM K1 bit setting*/ - ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, ®); - if (ret_val) - return ret_val; - - if (reg & E1000_NVM_K1_ENABLE) - dev_spec->nvm_k1_enabled = true; - else - dev_spec->nvm_k1_enabled = false; - } - ctrl = er32(CTRL); if (!e1000_check_reset_block(hw)) { @@ -2676,15 +2386,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) e1e_rphy(hw, BM_WUC, ®); - ret_val = e1000_sw_lcd_config_ich8lan(hw); - if (ret_val) - goto out; - - if (hw->mac.type == e1000_pchlan) { - ret_val = e1000_oem_bits_config_ich8lan(hw, true); - if (ret_val) - goto out; - } /* * For PCH, this write will make sure that any noise * will be detected as a CRC error and be dropped rather than show up @@ -2703,7 +2404,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pchlan) ret_val = e1000_hv_phy_workarounds_ich8lan(hw); -out: return ret_val; } @@ -3008,6 +2708,14 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, if (ret_val) return ret_val; + if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) { + ret_val = e1000e_write_kmrn_reg(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + E1000_KMRNCTRLSTA_K1_DISABLE); + if (ret_val) + return ret_val; + } + if ((hw->mac.type == e1000_ich8lan) && (hw->phy.type == e1000_phy_igp_3) && (*speed == SPEED_1000)) { diff --git a/trunk/drivers/net/e1000e/phy.c b/trunk/drivers/net/e1000e/phy.c index 03175b3a2c9e..f9d33ab05e97 100644 --- a/trunk/drivers/net/e1000e/phy.c +++ b/trunk/drivers/net/e1000e/phy.c @@ -95,6 +95,13 @@ static const u16 e1000_igp_2_cable_length_table[] = /* BM PHY Copper Specific Control 1 */ #define BM_CS_CTRL1 16 +/* BM PHY Copper Specific Status */ +#define BM_CS_STATUS 17 +#define BM_CS_STATUS_LINK_UP 0x0400 +#define BM_CS_STATUS_RESOLVED 0x0800 +#define BM_CS_STATUS_SPEED_MASK 0xC000 +#define BM_CS_STATUS_SPEED_1000 0x8000 + #define HV_MUX_DATA_CTRL PHY_REG(776, 16) #define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400 #define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004 @@ -556,7 +563,7 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) } /** - * e1000e_read_kmrn_reg_locked - Read kumeran register + * e1000_read_kmrn_reg_locked - Read kumeran register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data @@ -565,7 +572,7 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) * information retrieved is stored in data. * Assumes semaphore already acquired. **/ -s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) { return __e1000_read_kmrn_reg(hw, offset, data, true); } @@ -624,7 +631,7 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) } /** - * e1000e_write_kmrn_reg_locked - Write kumeran register + * e1000_write_kmrn_reg_locked - Write kumeran register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset @@ -632,7 +639,7 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) * Write the data to PHY register at the offset using the kumeran interface. * Assumes semaphore already acquired. **/ -s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) { return __e1000_write_kmrn_reg(hw, offset, data, true); } diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 94c9ad2746bc..bd3447f04902 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -1760,7 +1760,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b), PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index fa4935678488..f98ef523f525 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -3379,7 +3379,7 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) { /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, rx_buf_sz + 1); + RTL_W16(RxMaxSize, rx_buf_sz); } static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 6a10d7ba5877..2ab5c39f33ca 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -4538,8 +4538,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_netdev; } - netif_carrier_off(dev); - netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); err = request_irq(pdev->irq, sky2_intr, diff --git a/trunk/drivers/net/tokenring/ibmtr.c b/trunk/drivers/net/tokenring/ibmtr.c index 75fa32e34fd0..36cb2423bcf1 100644 --- a/trunk/drivers/net/tokenring/ibmtr.c +++ b/trunk/drivers/net/tokenring/ibmtr.c @@ -1144,16 +1144,9 @@ static void dir_open_adapter (struct net_device *dev) } else { char **prphase = printphase; char **prerror = printerror; - int pnr = err / 16 - 1; - int enr = err % 16 - 1; DPRINTK("TR Adapter misc open failure, error code = "); - if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) || - enr < 0 || - enr >= ARRAY_SIZE(printerror)) - printk("0x%x, invalid Phase/Error.", err); - else - printk("0x%x, Phase: %s, Error: %s\n", err, - prphase[pnr], prerror[enr]); + printk("0x%x, Phase: %s, Error: %s\n", + err, prphase[err/16 -1], prerror[err%16 -1]); printk(" retrying after %ds delay...\n", TR_RETRY_INTERVAL/HZ); } diff --git a/trunk/drivers/net/usb/rndis_host.c b/trunk/drivers/net/usb/rndis_host.c index f56dec6119c3..0caa8008c51c 100644 --- a/trunk/drivers/net/usb/rndis_host.c +++ b/trunk/drivers/net/usb/rndis_host.c @@ -362,12 +362,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) retval = -EINVAL; goto halt_fail_and_release; } + dev->hard_mtu = tmp; + net->mtu = dev->hard_mtu - net->hard_header_len; dev_warn(&intf->dev, "dev can't take %u byte packets (max %u), " "adjusting MTU to %u\n", - dev->hard_mtu, tmp, tmp - net->hard_header_len); - dev->hard_mtu = tmp; - net->mtu = dev->hard_mtu - net->hard_header_len; + dev->hard_mtu, tmp, net->mtu); } /* REVISIT: peripheral "alignment" request is ignored ... */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index 1895d63aad0a..16a271787b85 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -679,7 +679,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, return rate; if (rate_table->info[rate].valid_single_stream && - !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) + !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)); return rate; /* This should not happen */ diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index de4e804bedf0..8701034569fa 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1157,9 +1157,8 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot) } static int dma_tx_fragment(struct b43_dmaring *ring, - struct sk_buff **in_skb) + struct sk_buff *skb) { - struct sk_buff *skb = *in_skb; const struct b43_dma_ops *ops = ring->ops; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); u8 *header; @@ -1225,14 +1224,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring, } memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); - memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb)); - bounce_skb->dev = skb->dev; - skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb)); - info = IEEE80211_SKB_CB(bounce_skb); - dev_kfree_skb_any(skb); skb = bounce_skb; - *in_skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { @@ -1362,11 +1355,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) * static, so we don't need to store it per frame. */ ring->queue_prio = skb_get_queue_mapping(skb); - /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing - * into the skb data or cb now. */ - hdr = NULL; - info = NULL; - err = dma_tx_fragment(ring, &skb); + err = dma_tx_fragment(ring, skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index a741d37fd96f..240cff1e6979 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -6325,10 +6325,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, fail: if (dev) { - if (registered) { - unregister_ieee80211(priv->ieee); + if (registered) unregister_netdev(dev); - } ipw2100_hw_stop_adapter(priv); @@ -6385,7 +6383,6 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) /* Unregister the device first - this results in close() * being called if the device is open. If we free storage * first, then close() will crash. */ - unregister_ieee80211(priv->ieee); unregister_netdev(dev); /* ipw2100_down will ensure that there is no more pending work diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 9b0f2c0646e0..827824d45de9 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11822,7 +11822,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, if (err) { IPW_ERROR("Failed to register promiscuous network " "device (error %d).\n", err); - unregister_ieee80211(priv->ieee); unregister_netdev(priv->net_dev); goto out_remove_sysfs; } @@ -11873,7 +11872,6 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) mutex_unlock(&priv->mutex); - unregister_ieee80211(priv->ieee); unregister_netdev(priv->net_dev); if (priv->rxq) { diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw.h b/trunk/drivers/net/wireless/ipw2x00/libipw.h index f42ade6c2d3e..bf45391172f3 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw.h +++ b/trunk/drivers/net/wireless/ipw2x00/libipw.h @@ -1020,7 +1020,6 @@ static inline int libipw_is_cck_rate(u8 rate) /* ieee80211.c */ extern void free_ieee80211(struct net_device *dev, int monitor); extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); -extern void unregister_ieee80211(struct libipw_device *ieee); extern int libipw_change_mtu(struct net_device *dev, int new_mtu); extern void libipw_networks_age(struct libipw_device *ieee, diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c index be5b809ec97a..a0e9f6aed7da 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c @@ -235,19 +235,16 @@ void free_ieee80211(struct net_device *dev, int monitor) libipw_networks_free(ieee); /* free cfg80211 resources */ - if (!monitor) + if (!monitor) { + wiphy_unregister(ieee->wdev.wiphy); + kfree(ieee->a_band.channels); + kfree(ieee->bg_band.channels); wiphy_free(ieee->wdev.wiphy); + } free_netdev(dev); } -void unregister_ieee80211(struct libipw_device *ieee) -{ - wiphy_unregister(ieee->wdev.wiphy); - kfree(ieee->a_band.channels); - kfree(ieee->bg_band.channels); -} - #ifdef CONFIG_LIBIPW_DEBUG static int debug = 0; @@ -333,4 +330,3 @@ module_init(libipw_init); EXPORT_SYMBOL(alloc_ieee80211); EXPORT_SYMBOL(free_ieee80211); -EXPORT_SYMBOL(unregister_ieee80211); diff --git a/trunk/drivers/net/wireless/libertas/if_usb.c b/trunk/drivers/net/wireless/libertas/if_usb.c index 3fac4efa5ac8..92bc8c5f1ca2 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.c +++ b/trunk/drivers/net/wireless/libertas/if_usb.c @@ -508,7 +508,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, /* Fill the receive configuration URB and initialise the Rx call back */ usb_fill_bulk_urb(cardp->rx_urb, cardp->udev, usb_rcvbulkpipe(cardp->udev, cardp->ep_in), - skb->data + IPFIELD_ALIGN_OFFSET, + (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET), MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 14e7bb210075..b8f5ee33445e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -2389,13 +2389,10 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, /* MSI */ - { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, - /* Ovislink */ - { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, /* Ralink */ { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, @@ -2423,8 +2420,6 @@ static struct usb_device_id rt73usb_device_table[] = { /* Planex */ { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, - /* WideTell */ - { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) }, /* Zcom */ { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, /* ZyXEL */ diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index 698d75cda084..934d4bee39a0 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -98,13 +98,10 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem); * These functions check for the appropriate struct pcmcia_soket arrays, * and pass them to the low-level functions pcmcia_{suspend,resume}_socket */ -static int socket_early_resume(struct pcmcia_socket *skt); -static int socket_late_resume(struct pcmcia_socket *skt); static int socket_resume(struct pcmcia_socket *skt); static int socket_suspend(struct pcmcia_socket *skt); -static void pcmcia_socket_dev_run(struct device *dev, - int (*cb)(struct pcmcia_socket *)) +int pcmcia_socket_dev_suspend(struct device *dev) { struct pcmcia_socket *socket; @@ -113,34 +110,29 @@ static void pcmcia_socket_dev_run(struct device *dev, if (socket->dev.parent != dev) continue; mutex_lock(&socket->skt_mutex); - cb(socket); + socket_suspend(socket); mutex_unlock(&socket->skt_mutex); } up_read(&pcmcia_socket_list_rwsem); -} -int pcmcia_socket_dev_suspend(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_suspend); return 0; } EXPORT_SYMBOL(pcmcia_socket_dev_suspend); -void pcmcia_socket_dev_early_resume(struct device *dev) +int pcmcia_socket_dev_resume(struct device *dev) { - pcmcia_socket_dev_run(dev, socket_early_resume); -} -EXPORT_SYMBOL(pcmcia_socket_dev_early_resume); + struct pcmcia_socket *socket; -void pcmcia_socket_dev_late_resume(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_late_resume); -} -EXPORT_SYMBOL(pcmcia_socket_dev_late_resume); + down_read(&pcmcia_socket_list_rwsem); + list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { + if (socket->dev.parent != dev) + continue; + mutex_lock(&socket->skt_mutex); + socket_resume(socket); + mutex_unlock(&socket->skt_mutex); + } + up_read(&pcmcia_socket_list_rwsem); -int pcmcia_socket_dev_resume(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_resume); return 0; } EXPORT_SYMBOL(pcmcia_socket_dev_resume); @@ -554,24 +546,29 @@ static int socket_suspend(struct pcmcia_socket *skt) return 0; } -static int socket_early_resume(struct pcmcia_socket *skt) +/* + * Resume a socket. If a card is present, verify its CIS against + * our cached copy. If they are different, the card has been + * replaced, and we need to tell the drivers. + */ +static int socket_resume(struct pcmcia_socket *skt) { + int ret; + + if (!(skt->state & SOCKET_SUSPEND)) + return -EBUSY; + skt->socket = dead_socket; skt->ops->init(skt); skt->ops->set_socket(skt, &skt->socket); - if (skt->state & SOCKET_PRESENT) - skt->resume_status = socket_setup(skt, resume_delay); - return 0; -} -static int socket_late_resume(struct pcmcia_socket *skt) -{ if (!(skt->state & SOCKET_PRESENT)) { skt->state &= ~SOCKET_SUSPEND; return socket_insert(skt); } - if (skt->resume_status == 0) { + ret = socket_setup(skt, resume_delay); + if (ret == 0) { /* * FIXME: need a better check here for cardbus cards. */ @@ -599,20 +596,6 @@ static int socket_late_resume(struct pcmcia_socket *skt) return 0; } -/* - * Resume a socket. If a card is present, verify its CIS against - * our cached copy. If they are different, the card has been - * replaced, and we need to tell the drivers. - */ -static int socket_resume(struct pcmcia_socket *skt) -{ - if (!(skt->state & SOCKET_SUSPEND)) - return -EBUSY; - - socket_early_resume(skt); - return socket_late_resume(skt); -} - static void socket_remove(struct pcmcia_socket *skt) { dev_printk(KERN_NOTICE, &skt->dev, diff --git a/trunk/drivers/pcmcia/yenta_socket.c b/trunk/drivers/pcmcia/yenta_socket.c index 8be4cc447a17..abe0e44c6e9e 100644 --- a/trunk/drivers/pcmcia/yenta_socket.c +++ b/trunk/drivers/pcmcia/yenta_socket.c @@ -1275,26 +1275,16 @@ static int yenta_dev_resume_noirq(struct device *dev) if (socket->type && socket->type->restore_state) socket->type->restore_state(socket); - pcmcia_socket_dev_early_resume(dev); - return 0; -} - -static int yenta_dev_resume(struct device *dev) -{ - pcmcia_socket_dev_late_resume(dev); - return 0; + return pcmcia_socket_dev_resume(dev); } static struct dev_pm_ops yenta_pm_ops = { .suspend_noirq = yenta_dev_suspend_noirq, .resume_noirq = yenta_dev_resume_noirq, - .resume = yenta_dev_resume, .freeze_noirq = yenta_dev_suspend_noirq, .thaw_noirq = yenta_dev_resume_noirq, - .thaw = yenta_dev_resume, .poweroff_noirq = yenta_dev_suspend_noirq, .restore_noirq = yenta_dev_resume_noirq, - .restore = yenta_dev_resume, }; #define YENTA_PM_OPS (¥ta_pm_ops) diff --git a/trunk/drivers/s390/char/sclp_async.c b/trunk/drivers/s390/char/sclp_async.c index b44462a6c6d3..a4f68e5b9c96 100644 --- a/trunk/drivers/s390/char/sclp_async.c +++ b/trunk/drivers/s390/char/sclp_async.c @@ -26,6 +26,7 @@ static struct sclp_async_sccb *sccb; static int sclp_async_send_wait(char *message); static struct ctl_table_header *callhome_sysctl_header; static DEFINE_SPINLOCK(sclp_async_lock); +static char nodename[64]; #define SCLP_NORMAL_WRITE 0x00 struct async_evbuf { @@ -51,10 +52,9 @@ static struct sclp_register sclp_async_register = { static int call_home_on_panic(struct notifier_block *self, unsigned long event, void *data) { - strncat(data, init_utsname()->nodename, - sizeof(init_utsname()->nodename)); - sclp_async_send_wait(data); - return NOTIFY_DONE; + strncat(data, nodename, strlen(nodename)); + sclp_async_send_wait(data); + return NOTIFY_DONE; } static struct notifier_block call_home_panic_nb = { @@ -68,14 +68,15 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write, { unsigned long val; int len, rc; - char buf[3]; + char buf[2]; - if (!*count || (*ppos && !write)) { + if (!*count | (*ppos && !write)) { *count = 0; return 0; } if (!write) { - len = snprintf(buf, sizeof(buf), "%d\n", callhome_enabled); + len = sprintf(buf, "%d\n", callhome_enabled); + buf[len] = '\0'; rc = copy_to_user(buffer, buf, sizeof(buf)); if (rc != 0) return -EFAULT; @@ -170,29 +171,39 @@ static int __init sclp_async_init(void) rc = sclp_register(&sclp_async_register); if (rc) return rc; - rc = -EOPNOTSUPP; - if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) - goto out_sclp; - rc = -ENOMEM; callhome_sysctl_header = register_sysctl_table(kern_dir_table); - if (!callhome_sysctl_header) + if (!callhome_sysctl_header) { + rc = -ENOMEM; + goto out_sclp; + } + if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) { + rc = -EOPNOTSUPP; goto out_sclp; + } + rc = -ENOMEM; request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL); + if (!request) + goto out_sys; sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!request || !sccb) + if (!sccb) goto out_mem; - rc = atomic_notifier_chain_register(&panic_notifier_list, - &call_home_panic_nb); - if (!rc) - goto out; + rc = atomic_notifier_chain_register(&panic_notifier_list, + &call_home_panic_nb); + if (rc) + goto out_mem; + + strncpy(nodename, init_utsname()->nodename, 64); + return 0; + out_mem: kfree(request); free_page((unsigned long) sccb); +out_sys: unregister_sysctl_table(callhome_sysctl_header); out_sclp: sclp_unregister(&sclp_async_register); -out: return rc; + } module_init(sclp_async_init); diff --git a/trunk/drivers/s390/net/smsgiucv.c b/trunk/drivers/s390/net/smsgiucv.c index 3012355f8304..102000d1af6f 100644 --- a/trunk/drivers/s390/net/smsgiucv.c +++ b/trunk/drivers/s390/net/smsgiucv.c @@ -158,12 +158,7 @@ static int smsg_pm_restore_thaw(struct device *dev) smsg_path->flags = 0; rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", NULL, NULL, NULL); -#ifdef CONFIG_PM_DEBUG - if (rc) - printk(KERN_ERR - "iucv_path_connect returned with rc %i\n", rc); -#endif - cpcmd("SET SMSG IUCV", NULL, 0, NULL); + printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc); } return 0; } diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index 496764349c41..7d1aac31ec8d 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -1919,7 +1919,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) size = size>>16; size *= 4; if (size > MAX_MESSAGE_SIZE) { - rcode = -EINVAL; + rcode = EINVAL; goto cleanup; } /* Copy in the user's I2O command */ diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index 7c7914f5fa02..ff4617e21426 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -879,10 +879,10 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ - PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ - PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ - PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ + PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ + PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ + PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ + PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), diff --git a/trunk/drivers/staging/Kconfig b/trunk/drivers/staging/Kconfig index d21b3469f6d7..7df3ba4f1f4d 100644 --- a/trunk/drivers/staging/Kconfig +++ b/trunk/drivers/staging/Kconfig @@ -93,6 +93,8 @@ source "drivers/staging/dst/Kconfig" source "drivers/staging/pohmelfs/Kconfig" +source "drivers/staging/stlc45xx/Kconfig" + source "drivers/staging/b3dfg/Kconfig" source "drivers/staging/phison/Kconfig" diff --git a/trunk/drivers/staging/Makefile b/trunk/drivers/staging/Makefile index 8cbf1aebea2e..747571172269 100644 --- a/trunk/drivers/staging/Makefile +++ b/trunk/drivers/staging/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_ANDROID) += dream/ obj-$(CONFIG_DST) += dst/ obj-$(CONFIG_POHMELFS) += pohmelfs/ +obj-$(CONFIG_STLC45XX) += stlc45xx/ obj-$(CONFIG_B3DFG) += b3dfg/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_PLAN9AUTH) += p9auth/ diff --git a/trunk/drivers/staging/android/Kconfig b/trunk/drivers/staging/android/Kconfig index eb675635ae60..247194992374 100644 --- a/trunk/drivers/staging/android/Kconfig +++ b/trunk/drivers/staging/android/Kconfig @@ -2,7 +2,6 @@ menu "Android" config ANDROID bool "Android Drivers" - depends on BROKEN default N ---help--- Enable support for various drivers needed on the Android platform diff --git a/trunk/drivers/staging/hv/ChannelMgmt.h b/trunk/drivers/staging/hv/ChannelMgmt.h index fa973d86b624..a839d8fe6cec 100644 --- a/trunk/drivers/staging/hv/ChannelMgmt.h +++ b/trunk/drivers/staging/hv/ChannelMgmt.h @@ -26,7 +26,6 @@ #define _CHANNEL_MGMT_H_ #include -#include #include "RingBuffer.h" #include "VmbusChannelInterface.h" #include "VmbusPacketFormat.h" @@ -55,7 +54,7 @@ enum vmbus_channel_message_type { ChannelMessageViewRangeRemove = 18, #endif ChannelMessageCount -}; +} __attribute__((packed)); struct vmbus_channel_message_header { enum vmbus_channel_message_type MessageType; diff --git a/trunk/drivers/staging/hv/NetVsc.c b/trunk/drivers/staging/hv/NetVsc.c index d384c0ddf069..1610b845198f 100644 --- a/trunk/drivers/staging/hv/NetVsc.c +++ b/trunk/drivers/staging/hv/NetVsc.c @@ -1052,7 +1052,7 @@ static void NetVscOnReceive(struct hv_device *Device, */ spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); while (!list_empty(&netDevice->ReceivePacketList)) { - list_move_tail(netDevice->ReceivePacketList.next, &listHead); + list_move_tail(&netDevice->ReceivePacketList, &listHead); if (++count == vmxferpagePacket->RangeCount + 1) break; } @@ -1071,7 +1071,7 @@ static void NetVscOnReceive(struct hv_device *Device, /* Return it to the freelist */ spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); for (i = count; i != 0; i--) { - list_move_tail(listHead.next, + list_move_tail(&listHead, &netDevice->ReceivePacketList); } spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, @@ -1085,7 +1085,8 @@ static void NetVscOnReceive(struct hv_device *Device, } /* Remove the 1st packet to represent the xfer page packet itself */ - xferpagePacket = (struct xferpage_packet*)listHead.next; + xferpagePacket = list_entry(&listHead, struct xferpage_packet, + ListEntry); list_del(&xferpagePacket->ListEntry); /* This is how much we can satisfy */ @@ -1101,7 +1102,8 @@ static void NetVscOnReceive(struct hv_device *Device, /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ for (i = 0; i < (count - 1); i++) { - netvscPacket = (struct hv_netvsc_packet*)listHead.next; + netvscPacket = list_entry(&listHead, struct hv_netvsc_packet, + ListEntry); list_del(&netvscPacket->ListEntry); /* Initialize the netvsc packet */ diff --git a/trunk/drivers/staging/hv/TODO b/trunk/drivers/staging/hv/TODO index dbfbde937a66..4d390b237742 100644 --- a/trunk/drivers/staging/hv/TODO +++ b/trunk/drivers/staging/hv/TODO @@ -1,17 +1,11 @@ TODO: - fix remaining checkpatch warnings and errors - - use of /** when it is not a kerneldoc header - remove RingBuffer.c to us in-kernel ringbuffer functions instead. - audit the vmbus to verify it is working properly with the driver model - - convert vmbus driver interface function pointer tables - to constant, a.k.a vmbus_ops - see if the vmbus can be merged with the other virtual busses in the kernel - audit the network driver - - use existing net_device_stats struct in network device - - checking for carrier inside open is wrong, network device API - confusion?? - audit the block driver - audit the scsi driver diff --git a/trunk/drivers/staging/hv/osd.h b/trunk/drivers/staging/hv/osd.h index ce064e8ea644..9504604c72bd 100644 --- a/trunk/drivers/staging/hv/osd.h +++ b/trunk/drivers/staging/hv/osd.h @@ -25,7 +25,6 @@ #ifndef _OSD_H_ #define _OSD_H_ -#include /* Defines */ #define ALIGN_UP(value, align) (((value) & (align-1)) ? \ diff --git a/trunk/drivers/staging/hv/vmbus_drv.c b/trunk/drivers/staging/hv/vmbus_drv.c index 894eecfc63ca..582318f10222 100644 --- a/trunk/drivers/staging/hv/vmbus_drv.c +++ b/trunk/drivers/staging/hv/vmbus_drv.c @@ -507,12 +507,12 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type, child_device_obj = &child_device_ctx->device_obj; child_device_obj->context = context; - memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid)); - memcpy(&child_device_obj->deviceInstance, instance, + memcpy(&child_device_obj->deviceType, &type, sizeof(struct hv_guid)); + memcpy(&child_device_obj->deviceInstance, &instance, sizeof(struct hv_guid)); - memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid)); - memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid)); + memcpy(&child_device_ctx->class_id, &type, sizeof(struct hv_guid)); + memcpy(&child_device_ctx->device_id, &instance, sizeof(struct hv_guid)); DPRINT_EXIT(VMBUS_DRV); @@ -537,7 +537,18 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", child_device_ctx); - /* Set the device name. Otherwise, device_register() will fail. */ + /* Make sure we are not registered already */ + if (strlen(dev_name(&child_device_ctx->device)) != 0) { + DPRINT_ERR(VMBUS_DRV, + "child device (%p) already registered - busid %s", + child_device_ctx, + dev_name(&child_device_ctx->device)); + + ret = -1; + goto Cleanup; + } + + /* Set the device bus id. Otherwise, device_register()will fail. */ dev_set_name(&child_device_ctx->device, "vmbus_0_%d", atomic_inc_return(&device_num)); @@ -562,6 +573,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, DPRINT_INFO(VMBUS_DRV, "child device (%p) registered", &child_device_ctx->device); +Cleanup: DPRINT_EXIT(VMBUS_DRV); return ret; @@ -611,6 +623,8 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj) static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { struct device_context *device_ctx = device_to_device_context(device); + int i = 0; + int len = 0; int ret; DPRINT_ENTER(VMBUS_DRV); @@ -630,6 +644,8 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) device_ctx->class_id.data[14], device_ctx->class_id.data[15]); + env->envp_idx = i; + env->buflen = len; ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", @@ -675,6 +691,8 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) if (ret) return ret; + env->envp[env->envp_idx] = NULL; + DPRINT_EXIT(VMBUS_DRV); return 0; diff --git a/trunk/drivers/staging/otus/Kconfig b/trunk/drivers/staging/otus/Kconfig index f6cc2625e341..d549d08fd495 100644 --- a/trunk/drivers/staging/otus/Kconfig +++ b/trunk/drivers/staging/otus/Kconfig @@ -1,6 +1,6 @@ config OTUS tristate "Atheros OTUS 802.11n USB wireless support" - depends on USB && WLAN && MAC80211 + depends on USB && WLAN_80211 && MAC80211 default N ---help--- Enable support for Atheros 802.11n USB hardware: diff --git a/trunk/drivers/staging/panel/panel.c b/trunk/drivers/staging/panel/panel.c index 4ce399b6d237..dd7d3fde9699 100644 --- a/trunk/drivers/staging/panel/panel.c +++ b/trunk/drivers/staging/panel/panel.c @@ -2071,15 +2071,11 @@ static void panel_detach(struct parport *port) return; } - if (keypad_enabled && keypad_initialized) { + if (keypad_enabled && keypad_initialized) misc_deregister(&keypad_dev); - keypad_initialized = 0; - } - if (lcd_enabled && lcd_initialized) { + if (lcd_enabled && lcd_initialized) misc_deregister(&lcd_dev); - lcd_initialized = 0; - } parport_release(pprt); parport_unregister_device(pprt); @@ -2215,16 +2211,13 @@ static void __exit panel_cleanup_module(void) del_timer(&scan_timer); if (pprt != NULL) { - if (keypad_enabled) { + if (keypad_enabled) misc_deregister(&keypad_dev); - keypad_initialized = 0; - } if (lcd_enabled) { panel_lcd_print("\x0cLCD driver " PANEL_VERSION "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); misc_deregister(&lcd_dev); - lcd_initialized = 0; } /* TODO: free all input signals */ diff --git a/trunk/drivers/staging/rt2860/Kconfig b/trunk/drivers/staging/rt2860/Kconfig index efe38e25c5ed..7f44e5e72463 100644 --- a/trunk/drivers/staging/rt2860/Kconfig +++ b/trunk/drivers/staging/rt2860/Kconfig @@ -1,5 +1,5 @@ config RT2860 tristate "Ralink 2860 wireless support" - depends on PCI && X86 && WLAN + depends on PCI && X86 && WLAN_80211 ---help--- This is an experimental driver for the Ralink 2860 wireless chip. diff --git a/trunk/drivers/staging/rt2870/Kconfig b/trunk/drivers/staging/rt2870/Kconfig index aea5c8221810..76841f6dea93 100644 --- a/trunk/drivers/staging/rt2870/Kconfig +++ b/trunk/drivers/staging/rt2870/Kconfig @@ -1,5 +1,5 @@ config RT2870 tristate "Ralink 2870/3070 wireless support" - depends on USB && X86 && WLAN + depends on USB && X86 && WLAN_80211 ---help--- This is an experimental driver for the Ralink xx70 wireless chips. diff --git a/trunk/drivers/staging/rt3090/Kconfig b/trunk/drivers/staging/rt3090/Kconfig index 2b3f745d72b7..255e8eaa4836 100644 --- a/trunk/drivers/staging/rt3090/Kconfig +++ b/trunk/drivers/staging/rt3090/Kconfig @@ -1,5 +1,5 @@ config RT3090 tristate "Ralink 3090 wireless support" - depends on PCI && X86 && WLAN + depends on PCI && X86 && WLAN_80211 ---help--- This is an experimental driver for the Ralink 3090 wireless chip. diff --git a/trunk/drivers/staging/rtl8187se/Kconfig b/trunk/drivers/staging/rtl8187se/Kconfig index 203c79b8180f..236e42725447 100644 --- a/trunk/drivers/staging/rtl8187se/Kconfig +++ b/trunk/drivers/staging/rtl8187se/Kconfig @@ -1,6 +1,6 @@ config RTL8187SE tristate "RealTek RTL8187SE Wireless LAN NIC driver" - depends on PCI && WLAN + depends on PCI depends on WIRELESS_EXT default N ---help--- diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index 4c5d63fd5833..013c3e19ae25 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -53,8 +53,10 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, list_del(ptr); - if (entry->ops) + if (entry->ops) { entry->ops->deinit(entry->priv); + module_put(entry->ops->owner); + } kfree(entry); } } diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c index 18392fce487d..6fbe4890cb66 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c @@ -189,8 +189,10 @@ void free_ieee80211(struct net_device *dev) for (i = 0; i < WEP_KEYS; i++) { struct ieee80211_crypt_data *crypt = ieee->crypt[i]; if (crypt) { - if (crypt->ops) + if (crypt->ops) { crypt->ops->deinit(crypt->priv); + module_put(crypt->ops->owner); + } kfree(crypt); ieee->crypt[i] = NULL; } diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 334e4c7ec61b..59b2ab48cdcf 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -2839,12 +2839,16 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, goto skip_host_crypt; ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { + request_module("ieee80211_crypt_wep"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { + request_module("ieee80211_crypt_tkip"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { + request_module("ieee80211_crypt_ccmp"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } if (ops == NULL) { printk("unknown crypto alg '%s'\n", param->u.crypt.alg); param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; @@ -2865,7 +2869,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, } memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; - if (new_crypt->ops) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index a08b97a09512..8d8bdd0a130e 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -331,10 +331,12 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, return -ENOMEM; memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (!new_crypt->ops) + if (!new_crypt->ops) { + request_module("ieee80211_crypt_wep"); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); + } - if (new_crypt->ops) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(key); if (!new_crypt->ops || !new_crypt->priv) { @@ -481,7 +483,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int i, idx, ret = 0; int group_key = 0; - const char *alg; + const char *alg, *module; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; @@ -537,12 +539,15 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, switch (ext->alg) { case IW_ENCODE_ALG_WEP: alg = "WEP"; + module = "ieee80211_crypt_wep"; break; case IW_ENCODE_ALG_TKIP: alg = "TKIP"; + module = "ieee80211_crypt_tkip"; break; case IW_ENCODE_ALG_CCMP: alg = "CCMP"; + module = "ieee80211_crypt_ccmp"; break; default: IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", @@ -553,8 +558,10 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, // printk("8-09-08-9=====>%s, alg name:%s\n",__func__, alg); ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) + if (ops == NULL) { + request_module(module); ops = ieee80211_get_crypto_ops(alg); + } if (ops == NULL) { IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", dev->name, ext->alg); @@ -574,7 +581,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, goto done; } new_crypt->ops = ops; - if (new_crypt->ops) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(idx); if (new_crypt->priv == NULL) { kfree(new_crypt); diff --git a/trunk/drivers/staging/rtl8192e/Kconfig b/trunk/drivers/staging/rtl8192e/Kconfig index 37e4fde45073..3100aa58c940 100644 --- a/trunk/drivers/staging/rtl8192e/Kconfig +++ b/trunk/drivers/staging/rtl8192e/Kconfig @@ -1,6 +1,6 @@ config RTL8192E tristate "RealTek RTL8192E Wireless LAN NIC driver" - depends on PCI && WLAN + depends on PCI depends on WIRELESS_EXT default N ---help--- diff --git a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c index b1c54932da3e..1a8ea8a40c3c 100644 --- a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c +++ b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c @@ -53,8 +53,14 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, list_del(ptr); - if (entry->ops) + if (entry->ops) { entry->ops->deinit(entry->priv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + module_put(entry->ops->owner); +#else + __MOD_DEC_USE_COUNT(entry->ops->owner); +#endif + } kfree(entry); } } diff --git a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index 12c2a18e1fa2..16256a31f993 100644 --- a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -242,8 +242,14 @@ void free_ieee80211(struct net_device *dev) for (i = 0; i < WEP_KEYS; i++) { struct ieee80211_crypt_data *crypt = ieee->crypt[i]; if (crypt) { - if (crypt->ops) + if (crypt->ops) { crypt->ops->deinit(crypt->priv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + module_put(crypt->ops->owner); +#else + __MOD_DEC_USE_COUNT(crypt->ops->owner); +#endif + } kfree(crypt); ieee->crypt[i] = NULL; } diff --git a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index eae7c4579a68..2fc04df872ca 100644 --- a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -3284,14 +3284,17 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, goto skip_host_crypt; ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { + request_module("ieee80211_crypt_wep"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - /* set WEP40 first, it will be modified according to WEP104 or - * WEP40 at other place */ - else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) + //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { + request_module("ieee80211_crypt_tkip"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { + request_module("ieee80211_crypt_ccmp"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } if (ops == NULL) { printk("unknown crypto alg '%s'\n", param->u.crypt.alg); param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; @@ -3312,7 +3315,11 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, } memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; - if (new_crypt->ops) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) +#else + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner)) +#endif new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); diff --git a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index 4e34a1f4c66b..223483126b0e 100644 --- a/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/trunk/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -482,9 +482,15 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, return -ENOMEM; memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (!new_crypt->ops) + if (!new_crypt->ops) { + request_module("ieee80211_crypt_wep"); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (new_crypt->ops) + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) +#else + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner)) +#endif new_crypt->priv = new_crypt->ops->init(key); if (!new_crypt->ops || !new_crypt->priv) { @@ -638,7 +644,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int i, idx; int group_key = 0; - const char *alg; + const char *alg, *module; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; @@ -705,12 +711,15 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, switch (ext->alg) { case IW_ENCODE_ALG_WEP: alg = "WEP"; + module = "ieee80211_crypt_wep"; break; case IW_ENCODE_ALG_TKIP: alg = "TKIP"; + module = "ieee80211_crypt_tkip"; break; case IW_ENCODE_ALG_CCMP: alg = "CCMP"; + module = "ieee80211_crypt_ccmp"; break; default: IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", @@ -721,8 +730,10 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, printk("alg name:%s\n",alg); ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) + if (ops == NULL) { + request_module(module); ops = ieee80211_get_crypto_ops(alg); + } if (ops == NULL) { IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", dev->name, ext->alg); @@ -747,7 +758,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, goto done; } new_crypt->ops = ops; - if (new_crypt->ops) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(idx); if (new_crypt->priv == NULL) { kfree(new_crypt); diff --git a/trunk/drivers/staging/rtl8192su/Kconfig b/trunk/drivers/staging/rtl8192su/Kconfig index b8c95f942069..770f41280f21 100644 --- a/trunk/drivers/staging/rtl8192su/Kconfig +++ b/trunk/drivers/staging/rtl8192su/Kconfig @@ -1,6 +1,6 @@ config RTL8192SU tristate "RealTek RTL8192SU Wireless LAN NIC driver" - depends on PCI && WLAN + depends on PCI depends on WIRELESS_EXT default N ---help--- diff --git a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c index 521e7b989934..d76a54d59d2f 100644 --- a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c +++ b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c @@ -53,8 +53,10 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, list_del(ptr); - if (entry->ops) + if (entry->ops) { entry->ops->deinit(entry->priv); + module_put(entry->ops->owner); + } kfree(entry); } } diff --git a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index c3383bb8b760..68dc8fa094cc 100644 --- a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c @@ -216,8 +216,10 @@ void free_ieee80211(struct net_device *dev) for (i = 0; i < WEP_KEYS; i++) { struct ieee80211_crypt_data *crypt = ieee->crypt[i]; if (crypt) { - if (crypt->ops) + if (crypt->ops) { crypt->ops->deinit(crypt->priv); + module_put(crypt->ops->owner); + } kfree(crypt); ieee->crypt[i] = NULL; } diff --git a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index fd8e11252f1b..c64ae03f68a0 100644 --- a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -3026,14 +3026,17 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, goto skip_host_crypt; ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { + request_module("ieee80211_crypt_wep"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - /* set WEP40 first, it will be modified according to WEP104 or - * WEP40 at other place */ - else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) + //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { + request_module("ieee80211_crypt_tkip"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { + request_module("ieee80211_crypt_ccmp"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } if (ops == NULL) { printk("unknown crypto alg '%s'\n", param->u.crypt.alg); param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; @@ -3055,7 +3058,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; - if (new_crypt->ops) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); diff --git a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c index 6146c6435dde..107759024335 100644 --- a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c +++ b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c @@ -358,9 +358,11 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, return -ENOMEM; memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (!new_crypt->ops) + if (!new_crypt->ops) { + request_module("ieee80211_crypt_wep"); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (new_crypt->ops) + } + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(key); if (!new_crypt->ops || !new_crypt->priv) { @@ -505,7 +507,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int i, idx; int group_key = 0; - const char *alg; + const char *alg, *module; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; @@ -568,12 +570,15 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, switch (ext->alg) { case IW_ENCODE_ALG_WEP: alg = "WEP"; + module = "ieee80211_crypt_wep"; break; case IW_ENCODE_ALG_TKIP: alg = "TKIP"; + module = "ieee80211_crypt_tkip"; break; case IW_ENCODE_ALG_CCMP: alg = "CCMP"; + module = "ieee80211_crypt_ccmp"; break; default: IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", @@ -584,8 +589,10 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, printk("alg name:%s\n",alg); ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) + if (ops == NULL) { + request_module("%s", module); ops = ieee80211_get_crypto_ops(alg); + } if (ops == NULL) { IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", dev->name, ext->alg); @@ -605,7 +612,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, goto done; } new_crypt->ops = ops; - if (new_crypt->ops) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(idx); if (new_crypt->priv == NULL) { kfree(new_crypt); diff --git a/trunk/drivers/staging/stlc45xx/Kconfig b/trunk/drivers/staging/stlc45xx/Kconfig new file mode 100644 index 000000000000..947fb75a9c68 --- /dev/null +++ b/trunk/drivers/staging/stlc45xx/Kconfig @@ -0,0 +1,8 @@ +config STLC45XX + tristate "stlc4550/4560 support" + depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS + ---help--- + This is a driver for stlc4550 and stlc4560 chipsets. + + To compile this driver as a module, choose M here: the module will be + called stlc45xx. If unsure, say N. diff --git a/trunk/drivers/staging/stlc45xx/Makefile b/trunk/drivers/staging/stlc45xx/Makefile new file mode 100644 index 000000000000..7ee32903055a --- /dev/null +++ b/trunk/drivers/staging/stlc45xx/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_STLC45XX) += stlc45xx.o diff --git a/trunk/drivers/staging/stlc45xx/stlc45xx.c b/trunk/drivers/staging/stlc45xx/stlc45xx.c new file mode 100644 index 000000000000..be99eb33d817 --- /dev/null +++ b/trunk/drivers/staging/stlc45xx/stlc45xx.c @@ -0,0 +1,2594 @@ +/* + * This file is part of stlc45xx + * + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Kalle Valo + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "stlc45xx.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stlc45xx_lmac.h" + +/* + * gpios should be handled in board files and provided via platform data, + * but because it's currently impossible for stlc45xx to have a header file + * in include/linux, let's use module paramaters for now + */ +static int stlc45xx_gpio_power = 97; +module_param(stlc45xx_gpio_power, int, 0444); +MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line"); + +static int stlc45xx_gpio_irq = 87; +module_param(stlc45xx_gpio_irq, int, 0444); +MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line"); + +static const u8 default_cal_channels[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09, + 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, + 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00, + 0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, + 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, + 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, + 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, + 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, + 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, + 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, + 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, + 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, + 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, + 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, + 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, + 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, + 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, + 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, + 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, + 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, + 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, + 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, + 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, + 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, + 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, + 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, + 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, + 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, + 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, + 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, + 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, + 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, + 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, + 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, + 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, + 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, + 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, + 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, + 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, + 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, + 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, + 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, + 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, + 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff, + 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, + 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, + 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, + 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, + 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, + 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, + 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, + 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, + 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, + 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, + 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, + 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, + 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, + 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, + 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, + 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, + 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, + 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, + 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, + 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, + 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, + 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, + 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, + 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, + 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, + 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, + 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, + 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, + 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, + 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9, + 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, + 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, + 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, + 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, + 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, + 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, + 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, + 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, + 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, + 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, + 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, + 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, + 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, + 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, + 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, + 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, + 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, + 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, + 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, + 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, + 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, + 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, + 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, + 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, + 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, + 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, + 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, + 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, + 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00, + 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, + 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, + 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, + 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, + 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, + 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, + 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, + 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, + 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, + 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, + 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, + 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, + 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, + 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, + 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, + 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, + 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, + 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, + 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, + 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, + 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, + 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, + 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, + 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, + 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, + 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, + 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, + 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, + 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00, + 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, + 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, + 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, + 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, + 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, + 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, + 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, + 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, + 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, + 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, + 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, + 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, + 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, + 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, + 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, + 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, + 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, + 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, + 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, + 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, + 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, + 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, + 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, + 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, + 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, + 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, + 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, + 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, + 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, + 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, + 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 }; + +static const u8 default_cal_rssi[] = { + 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, + 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, + 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, + 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, + 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, + 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, + 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static void stlc45xx_tx_edcf(struct stlc45xx *stlc); +static void stlc45xx_tx_setup(struct stlc45xx *stlc); +static void stlc45xx_tx_scan(struct stlc45xx *stlc); +static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable); +static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave); +static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave); + +static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct stlc45xx *stlc = dev_get_drvdata(dev); + ssize_t len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + len = PAGE_SIZE; + + mutex_lock(&stlc->mutex); + + if (stlc->cal_rssi) + hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16, + 2, buf, len, 0); + mutex_unlock(&stlc->mutex); + + len = strlen(buf); + + return len; +} + +static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct stlc45xx *stlc = dev_get_drvdata(dev); + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + mutex_lock(&stlc->mutex); + + if (count != RSSI_CAL_ARRAY_LEN) { + stlc45xx_error("invalid cal_rssi length: %zu", count); + count = 0; + goto out_unlock; + } + + kfree(stlc->cal_rssi); + + stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL); + + if (!stlc->cal_rssi) { + stlc45xx_error("failed to allocate memory for cal_rssi"); + count = 0; + goto out_unlock; + } + + out_unlock: + mutex_unlock(&stlc->mutex); + + return count; +} + +static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct stlc45xx *stlc = dev_get_drvdata(dev); + ssize_t len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + len = PAGE_SIZE; + + mutex_lock(&stlc->mutex); + + if (stlc->cal_channels) + hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN, + 16, 2, buf, len, 0); + + mutex_unlock(&stlc->mutex); + + len = strlen(buf); + + return len; +} + +static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct stlc45xx *stlc = dev_get_drvdata(dev); + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + mutex_lock(&stlc->mutex); + + if (count != CHANNEL_CAL_ARRAY_LEN) { + stlc45xx_error("invalid cal_channels size: %zu ", count); + count = 0; + goto out_unlock; + } + + kfree(stlc->cal_channels); + + stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL); + + if (!stlc->cal_channels) { + stlc45xx_error("failed to allocate memory for cal_channels"); + count = 0; + goto out_unlock; + } + +out_unlock: + mutex_unlock(&stlc->mutex); + + return count; +} + +static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct stlc45xx *stlc = dev_get_drvdata(dev); + struct txbuffer *entry; + ssize_t len = 0; + + stlc45xx_debug(DEBUG_FUNC, "%s()", __func__); + + mutex_lock(&stlc->mutex); + + list_for_each_entry(entry, &stlc->tx_sent, tx_list) { + len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n", + entry->handle, entry->start, + entry->end); + } + + mutex_unlock(&stlc->mutex); + + return len; +} + +static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR, + stlc45xx_sysfs_show_cal_rssi, + stlc45xx_sysfs_store_cal_rssi); +static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR, + stlc45xx_sysfs_show_cal_channels, + stlc45xx_sysfs_store_cal_channels); +static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL); + +static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr, + void *buf, size_t len) +{ + struct spi_transfer t[2]; + struct spi_message m; + + /* We first push the address */ + addr = (addr << 8) | ADDR_READ_BIT_15; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &addr; + t[0].len = 2; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = buf; + t[1].len = len; + spi_message_add_tail(&t[1], &m); + + spi_sync(stlc->spi, &m); +} + + +static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr, + void *buf, size_t len) +{ + struct spi_transfer t[3]; + struct spi_message m; + u16 last_word; + + /* We first push the address */ + addr = addr << 8; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &addr; + t[0].len = 2; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = buf; + t[1].len = len; + spi_message_add_tail(&t[1], &m); + + if (len % 2) { + last_word = ((u8 *)buf)[len - 1]; + + t[2].tx_buf = &last_word; + t[2].len = 2; + spi_message_add_tail(&t[2], &m); + } + + spi_sync(stlc->spi, &m); +} + +static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr) +{ + u16 val; + + stlc45xx_spi_read(stlc, addr, &val, sizeof(val)); + + return val; +} + +static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr) +{ + u32 val; + + stlc45xx_spi_read(stlc, addr, &val, sizeof(val)); + + return val; +} + +static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val) +{ + stlc45xx_spi_write(stlc, addr, &val, sizeof(val)); +} + +static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val) +{ + stlc45xx_spi_write(stlc, addr, &val, sizeof(val)); +} + +struct stlc45xx_spi_reg { + u16 address; + u16 length; + char *name; +}; + +/* caller must hold tx_lock */ +static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc) +{ + struct txbuffer *txbuffer; + char *buf, *pos; + int buf_len, l, count; + + if (!(DEBUG_LEVEL & DEBUG_TXBUFFER)) + return; + + stlc45xx_debug(DEBUG_FUNC, "%s()", __func__); + + buf_len = 500; + buf = kmalloc(buf_len, GFP_ATOMIC); + if (!buf) + return; + + pos = buf; + count = 0; + + list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) { + l = snprintf(pos, buf_len, "0x%x-0x%x,", + txbuffer->start, txbuffer->end); + /* drop the null byte */ + pos += l; + buf_len -= l; + count++; + } + + if (count == 0) + *pos = '\0'; + else + *--pos = '\0'; + + stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s", + count, buf); + + kfree(buf); +} + +/* caller must hold tx_lock */ +static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len) +{ + struct txbuffer *txbuffer; + int pos; + + stlc45xx_debug(DEBUG_FUNC, "%s()", __func__); + + pos = FIRMWARE_TXBUFFER_START; + + if (list_empty(&stlc->txbuffer)) + goto out; + + /* + * the entries in txbuffer must be in the same order as they are in + * the real buffer + */ + list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) { + if (pos + len < txbuffer->start) + break; + pos = ALIGN(txbuffer->end + 1, 4); + } + + if (pos + len > FIRMWARE_TXBUFFER_END) + /* not enough room */ + pos = -1; + + stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos); + +out: + return pos; +} + +static int stlc45xx_txbuffer_add(struct stlc45xx *stlc, + struct txbuffer *txbuffer) +{ + struct txbuffer *r, *prev = NULL; + + if (list_empty(&stlc->txbuffer)) { + list_add(&txbuffer->buffer_list, &stlc->txbuffer); + return 0; + } + + r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list); + + if (txbuffer->start < r->start) { + /* add to the beginning of the list */ + list_add(&txbuffer->buffer_list, &stlc->txbuffer); + return 0; + } + + prev = NULL; + list_for_each_entry(r, &stlc->txbuffer, buffer_list) { + /* skip first entry, we checked for that above */ + if (!prev) { + prev = r; + continue; + } + + /* double-check overlaps */ + WARN_ON_ONCE(txbuffer->start >= r->start && + txbuffer->start <= r->end); + WARN_ON_ONCE(txbuffer->end >= r->start && + txbuffer->end <= r->end); + + if (prev->end < txbuffer->start && + txbuffer->end < r->start) { + /* insert at this spot */ + list_add_tail(&txbuffer->buffer_list, &r->buffer_list); + return 0; + } + + prev = r; + } + + /* not found */ + list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer); + + return 0; + +} + +/* caller must hold tx_lock */ +static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc, + size_t frame_len) +{ + struct txbuffer *entry = NULL; + size_t len; + int pos; + + stlc45xx_debug(DEBUG_FUNC, "%s()", __func__); + + len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER; + pos = stlc45xx_txbuffer_find(stlc, len); + + if (pos < 0) + return NULL; + + WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END); + WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START); + + entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry->start = pos; + entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER; + entry->end = entry->start + len - 1; + + stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x", + entry->start, entry->end); + + stlc45xx_txbuffer_add(stlc, entry); + + stlc45xx_txbuffer_dump(stlc); + + return entry; +} + +/* caller must hold tx_lock */ +static void stlc45xx_txbuffer_free(struct stlc45xx *stlc, + struct txbuffer *txbuffer) +{ + stlc45xx_debug(DEBUG_FUNC, "%s()", __func__); + + stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x", + txbuffer->start, txbuffer->end); + + list_del(&txbuffer->buffer_list); + kfree(txbuffer); +} + + +static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask, + u32 expected) +{ + int i; + char buffer[4]; + + for (i = 0; i < 2000; i++) { + stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer)); + if (((*(u32 *)buffer) & mask) == expected) + return 1; + msleep(1); + } + + return 0; +} + +static int stlc45xx_request_firmware(struct stlc45xx *stlc) +{ + const struct firmware *fw; + int ret; + + /* FIXME: should driver use it's own struct device? */ + ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev); + + if (ret < 0) { + stlc45xx_error("request_firmware() failed: %d", ret); + return ret; + } + + if (fw->size % 4) { + stlc45xx_error("firmware size is not multiple of 32bit: %zu", + fw->size); + return -EILSEQ; /* Illegal byte sequence */; + } + + if (fw->size < 1000) { + stlc45xx_error("firmware is too small: %zu", fw->size); + return -EILSEQ; + } + + stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL); + if (!stlc->fw) { + stlc45xx_error("could not allocate memory for firmware"); + return -ENOMEM; + } + + stlc->fw_len = fw->size; + + release_firmware(fw); + + return 0; +} + +static int stlc45xx_upload_firmware(struct stlc45xx *stlc) +{ + struct s_dma_regs dma_regs; + unsigned long fw_len, fw_addr; + long _fw_len; + int ret; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + if (!stlc->fw) { + ret = stlc45xx_request_firmware(stlc); + if (ret < 0) + return ret; + } + + /* stop the device */ + stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT, + SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET + | SPI_CTRL_STAT_START_HALTED); + + msleep(TARGET_BOOT_SLEEP); + + stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT, + SPI_CTRL_STAT_HOST_OVERRIDE + | SPI_CTRL_STAT_START_HALTED); + + msleep(TARGET_BOOT_SLEEP); + + fw_addr = FIRMWARE_ADDRESS; + fw_len = stlc->fw_len; + + while (fw_len > 0) { + _fw_len = (fw_len > SPI_MAX_PACKET_SIZE) + ? SPI_MAX_PACKET_SIZE : fw_len; + dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE; + dma_regs.len = cpu_to_le16(_fw_len); + dma_regs.addr = cpu_to_le32(fw_addr); + + fw_len -= _fw_len; + fw_addr += _fw_len; + + stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd); + + if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL, + HOST_ALLOWED, HOST_ALLOWED) == 0) { + stlc45xx_error("fw_upload not allowed to DMA write"); + return -EAGAIN; + } + + stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len); + stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr); + + stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len); + + /* FIXME: I think this doesn't work if firmware is large, + * this loop goes to second round. fw->data is not + * increased at all! */ + } + + BUG_ON(fw_len != 0); + + /* enable host interrupts */ + stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT); + + /* boot the device */ + stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT, + SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET + | SPI_CTRL_STAT_RAM_BOOT); + + msleep(TARGET_BOOT_SLEEP); + + stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT, + SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT); + msleep(TARGET_BOOT_SLEEP); + + return 0; +} + +/* caller must hold tx_lock */ +static void stlc45xx_check_txsent(struct stlc45xx *stlc) +{ + struct txbuffer *entry, *n; + + list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) { + if (time_after(jiffies, entry->lifetime)) { + if (net_ratelimit()) + stlc45xx_warning("frame 0x%x lifetime exceeded", + entry->start); + list_del(&entry->tx_list); + skb_pull(entry->skb, entry->header_len); + ieee80211_tx_status(stlc->hw, entry->skb); + stlc45xx_txbuffer_free(stlc, entry); + } + } +} + +static void stlc45xx_power_off(struct stlc45xx *stlc) +{ + disable_irq(gpio_to_irq(stlc45xx_gpio_irq)); + gpio_set_value(stlc45xx_gpio_power, 0); +} + +static void stlc45xx_power_on(struct stlc45xx *stlc) +{ + gpio_set_value(stlc45xx_gpio_power, 1); + enable_irq(gpio_to_irq(stlc45xx_gpio_irq)); + + /* + * need to wait a while before device can be accessed, the length + * is just a guess + */ + msleep(10); +} + +/* caller must hold tx_lock */ +static void stlc45xx_flush_queues(struct stlc45xx *stlc) +{ + struct txbuffer *entry; + + while (!list_empty(&stlc->tx_sent)) { + entry = list_first_entry(&stlc->tx_sent, + struct txbuffer, tx_list); + list_del(&entry->tx_list); + dev_kfree_skb(entry->skb); + stlc45xx_txbuffer_free(stlc, entry); + } + + WARN_ON(!list_empty(&stlc->tx_sent)); + + while (!list_empty(&stlc->tx_pending)) { + entry = list_first_entry(&stlc->tx_pending, + struct txbuffer, tx_list); + list_del(&entry->tx_list); + dev_kfree_skb(entry->skb); + stlc45xx_txbuffer_free(stlc, entry); + } + + WARN_ON(!list_empty(&stlc->tx_pending)); + WARN_ON(!list_empty(&stlc->txbuffer)); +} + +static void stlc45xx_work_reset(struct work_struct *work) +{ + struct stlc45xx *stlc = container_of(work, struct stlc45xx, + work_reset); + + mutex_lock(&stlc->mutex); + + if (stlc->fw_state != FW_STATE_RESET) + goto out; + + stlc45xx_power_off(stlc); + + mutex_unlock(&stlc->mutex); + + /* wait that all work_structs have finished, we can't hold + * stlc->mutex to avoid deadlock */ + cancel_work_sync(&stlc->work); + + /* FIXME: find out good value to wait for chip power down */ + msleep(100); + + mutex_lock(&stlc->mutex); + + /* FIXME: we should gracefully handle if the state has changed + * after re-acquiring mutex */ + WARN_ON(stlc->fw_state != FW_STATE_RESET); + + spin_lock_bh(&stlc->tx_lock); + stlc45xx_flush_queues(stlc); + spin_unlock_bh(&stlc->tx_lock); + + stlc->fw_state = FW_STATE_RESETTING; + + stlc45xx_power_on(stlc); + stlc45xx_upload_firmware(stlc); + +out: + mutex_unlock(&stlc->mutex); +} + +/* caller must hold mutex */ +static void stlc45xx_reset(struct stlc45xx *stlc) +{ + stlc45xx_warning("resetting firmware"); + stlc->fw_state = FW_STATE_RESET; + ieee80211_stop_queues(stlc->hw); + queue_work(stlc->hw->workqueue, &stlc->work_reset); +} + +static void stlc45xx_work_tx_timeout(struct work_struct *work) +{ + struct stlc45xx *stlc = container_of(work, struct stlc45xx, + work_tx_timeout.work); + + stlc45xx_warning("tx timeout"); + + mutex_lock(&stlc->mutex); + + if (stlc->fw_state != FW_STATE_READY) + goto out; + + stlc45xx_reset(stlc); + +out: + mutex_unlock(&stlc->mutex); +} + +static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val) +{ + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val); +} + +static void stlc45xx_wakeup(struct stlc45xx *stlc) +{ + unsigned long timeout; + u32 ints; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + /* wake the chip */ + stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP); + + /* And wait for the READY interrupt */ + timeout = jiffies + HZ; + + ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS); + while (!(ints & SPI_HOST_INT_READY)) { + if (time_after(jiffies, timeout)) + goto out; + ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS); + } + + stlc45xx_int_ack(stlc, SPI_HOST_INT_READY); + +out: + return; +} + +static void stlc45xx_sleep(struct stlc45xx *stlc) +{ + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP); +} + +static void stlc45xx_int_ready(struct stlc45xx *stlc) +{ + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, + SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE); + + switch (stlc->fw_state) { + case FW_STATE_BOOTING: + stlc->fw_state = FW_STATE_READY; + complete(&stlc->fw_comp); + break; + case FW_STATE_RESETTING: + stlc->fw_state = FW_STATE_READY; + + stlc45xx_tx_scan(stlc); + stlc45xx_tx_setup(stlc); + stlc45xx_tx_edcf(stlc); + + ieee80211_wake_queues(stlc->hw); + break; + default: + break; + } +} + +static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info; + struct s_lm_control *control; + struct s_lmo_tx *tx; + struct txbuffer *entry; + int found = 0; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + control = (struct s_lm_control *) skb->data; + tx = (struct s_lmo_tx *) (control + 1); + + if (list_empty(&stlc->tx_sent)) { + if (net_ratelimit()) + stlc45xx_warning("no frames waiting for " + "acknowledgement"); + return -1; + } + + list_for_each_entry(entry, &stlc->tx_sent, tx_list) { + if (control->handle == entry->handle) { + found = 1; + break; + } + } + + if (!found) { + if (net_ratelimit()) + stlc45xx_warning("couldn't find frame for tx ack 0x%x", + control->handle); + return -1; + } + + stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle); + + if (entry->status_needed) { + info = IEEE80211_SKB_CB(entry->skb); + + if (!(tx->flags & LM_TX_FAILED)) { + /* frame was acked */ + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = tx->rcpi / 2 - 110; + } + + skb_pull(entry->skb, entry->header_len); + + ieee80211_tx_status(stlc->hw, entry->skb); + } + + list_del(&entry->tx_list); + + stlc45xx_check_txsent(stlc); + if (list_empty(&stlc->tx_sent)) + /* there are no pending frames, we can stop the tx timeout + * timer */ + cancel_delayed_work(&stlc->work_tx_timeout); + + spin_lock_bh(&stlc->tx_lock); + + stlc45xx_txbuffer_free(stlc, entry); + + if (stlc->tx_queue_stopped && + stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) { + stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues"); + ieee80211_wake_queues(stlc->hw); + stlc->tx_queue_stopped = 0; + } + + spin_unlock_bh(&stlc->tx_lock); + + return 0; +} + +static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb) +{ + struct s_lm_control *control; + int ret = 0; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + control = (struct s_lm_control *) skb->data; + + switch (control->oid) { + case LM_OID_TX: + ret = stlc45xx_rx_txack(stlc, skb); + break; + case LM_OID_SETUP: + case LM_OID_SCAN: + case LM_OID_TRAP: + case LM_OID_EDCF: + case LM_OID_KEYCACHE: + case LM_OID_PSM: + case LM_OID_STATS: + case LM_OID_LED: + default: + stlc45xx_warning("unhandled rx control oid %d\n", + control->oid); + break; + } + + dev_kfree_skb(skb); + + return ret; +} + +/* copied from mac80211 */ +static void stlc45xx_parse_elems(u8 *start, size_t len, + struct stlc45xx_ie_tim **tim, + size_t *tim_len) +{ + size_t left = len; + u8 *pos = start; + + while (left >= 2) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + left -= 2; + + if (elen > left) + return; + + switch (id) { + case WLAN_EID_TIM: + *tim = (struct stlc45xx_ie_tim *) pos; + *tim_len = elen; + break; + default: + break; + } + + left -= elen; + pos += elen; + } +} + +/* + * mac80211 doesn't have support for asking frames with PS-Poll, so let's + * implement in the driver for now. We have to add support to mac80211 + * later. + */ +static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb) +{ + struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data; + struct ieee80211_hdr *hdr; + size_t len; + u16 fc; + + hdr = (void *) skb->data + sizeof(*data); + len = skb->len - sizeof(*data); + + /* minimum frame length is the null frame length 24 bytes */ + if (len < 24) { + stlc45xx_warning("invalid frame length when checking for " + "more data"); + return -EINVAL; + } + + fc = le16_to_cpu(hdr->frame_control); + if (!(fc & IEEE80211_FCTL_FROMDS)) + /* this is not from DS */ + return 0; + + if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0) + /* the frame was not for us */ + return 0; + + if (!(fc & IEEE80211_FCTL_MOREDATA)) { + /* AP has no more frames buffered for us */ + stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved"); + stlc->pspolling = false; + return 0; + } + + /* MOREDATA bit is set, let's ask for a new frame from the AP */ + stlc45xx_tx_pspoll(stlc, stlc->psm); + + return 0; +} + +/* + * mac80211 cannot read TIM from beacons, so let's add a hack to the + * driver. We have to add support to mac80211 later. + */ +static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb) +{ + struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data; + size_t len = skb->len, tim_len = 0, baselen, pvbmap_len; + struct ieee80211_mgmt *mgmt; + struct stlc45xx_ie_tim *tim = NULL; + int bmap_offset, index, aid_bit; + + mgmt = (void *) skb->data + sizeof(*data); + + baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; + if (baselen > len) { + stlc45xx_warning("invalid baselen in beacon"); + return -EINVAL; + } + + stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim, + &tim_len); + + if (!tim) { + stlc45xx_warning("didn't find tim from a beacon"); + return -EINVAL; + } + + bmap_offset = tim->bmap_control & 0xfe; + index = stlc->aid / 8 - bmap_offset; + + pvbmap_len = tim_len - 3; + if (index > pvbmap_len) + return -EINVAL; + + aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8)); + + stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u " + "bmap_control 0x%x aid_bit %d", + mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4, + tim->dtim_count, tim->bmap_control, aid_bit); + + if (!aid_bit) + return 0; + + stlc->pspolling = true; + stlc45xx_tx_pspoll(stlc, stlc->psm); + + return 0; +} + +static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb) +{ + struct ieee80211_rx_status status; + struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data; + int align = 0; + u8 *p, align_len; + u16 len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + if (stlc->psm) { + if (data->flags & LM_IN_BEACON) + stlc45xx_rx_data_beacon(stlc, skb); + else if (stlc->pspolling && (data->flags & LM_IN_DATA)) + stlc45xx_check_more_data(stlc, skb); + } + + memset(&status, 0, sizeof(status)); + + status.freq = data->frequency; + status.signal = data->rcpi / 2 - 110; + + /* let's assume that maximum rcpi value is 140 (= 35 dBm) */ + status.qual = data->rcpi * 100 / 140; + + status.band = IEEE80211_BAND_2GHZ; + + /* + * FIXME: this gives warning from __ieee80211_rx() + * + * status.rate_idx = data->rate; + */ + + len = data->length; + + if (data->flags & LM_FLAG_ALIGN) + align = 1; + + skb_pull(skb, sizeof(*data)); + + if (align) { + p = skb->data; + align_len = *p; + skb_pull(skb, align_len); + } + + skb_trim(skb, len); + + stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len); + stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len); + + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx(stlc->hw, skb); + + return 0; +} + + + +static int stlc45xx_rx(struct stlc45xx *stlc) +{ + struct s_lm_control *control; + struct sk_buff *skb; + int ret; + u16 len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + stlc45xx_wakeup(stlc); + + /* dummy read to flush SPI DMA controller bug */ + stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1); + + len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA); + + if (len == 0) { + stlc45xx_warning("rx request of zero bytes"); + return 0; + } + + skb = dev_alloc_skb(len); + if (!skb) { + stlc45xx_warning("could not alloc skb"); + return 0; + } + + stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len); + + stlc45xx_sleep(stlc); + + stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len); + stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len); + + control = (struct s_lm_control *) skb->data; + + if (control->flags & LM_FLAG_CONTROL) + ret = stlc45xx_rx_control(stlc, skb); + else + ret = stlc45xx_rx_data(stlc, skb); + + return ret; +} + + +static irqreturn_t stlc45xx_interrupt(int irq, void *config) +{ + struct spi_device *spi = config; + struct stlc45xx *stlc = dev_get_drvdata(&spi->dev); + + stlc45xx_debug(DEBUG_IRQ, "IRQ"); + + queue_work(stlc->hw->workqueue, &stlc->work); + + return IRQ_HANDLED; +} + +static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address, + void *buf, size_t len) +{ + struct s_dma_regs dma_regs; + unsigned long timeout; + int ret = 0; + u32 ints; + + stlc->tx_frames++; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len); + stlc45xx_dump(DEBUG_TX_CONTENT, buf, len); + + stlc45xx_wakeup(stlc); + + dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE; + dma_regs.len = cpu_to_le16(len); + dma_regs.addr = cpu_to_le32(address); + + stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs, + sizeof(dma_regs)); + + stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len); + + timeout = jiffies + 2 * HZ; + ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS); + while (!(ints & SPI_HOST_INT_WR_READY)) { + if (time_after(jiffies, timeout)) { + stlc45xx_warning("WR_READY timeout"); + ret = -1; + goto out; + } + ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS); + } + + stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY); + + stlc45xx_sleep(stlc); + +out: + return ret; +} + +static int stlc45xx_wq_tx(struct stlc45xx *stlc) +{ + struct txbuffer *entry; + int ret = 0; + + spin_lock_bh(&stlc->tx_lock); + + while (!list_empty(&stlc->tx_pending)) { + entry = list_entry(stlc->tx_pending.next, + struct txbuffer, tx_list); + + list_del_init(&entry->tx_list); + + spin_unlock_bh(&stlc->tx_lock); + + ret = stlc45xx_tx_frame(stlc, entry->frame_start, + entry->skb->data, entry->skb->len); + + spin_lock_bh(&stlc->tx_lock); + + if (ret < 0) { + /* frame transfer to firmware buffer failed */ + /* FIXME: report this to mac80211 */ + dev_kfree_skb(entry->skb); + stlc45xx_txbuffer_free(stlc, entry); + goto out; + } + + list_add(&entry->tx_list, &stlc->tx_sent); + queue_delayed_work(stlc->hw->workqueue, + &stlc->work_tx_timeout, + msecs_to_jiffies(TX_TIMEOUT)); + } + +out: + spin_unlock_bh(&stlc->tx_lock); + return ret; +} + +static void stlc45xx_work(struct work_struct *work) +{ + struct stlc45xx *stlc = container_of(work, struct stlc45xx, work); + u32 ints; + int ret; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + mutex_lock(&stlc->mutex); + + if (stlc->fw_state == FW_STATE_OFF && + stlc->fw_state == FW_STATE_RESET) + goto out; + + ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS); + stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints); + + if (ints & SPI_HOST_INT_READY) { + stlc45xx_int_ready(stlc); + stlc45xx_int_ack(stlc, SPI_HOST_INT_READY); + } + + if (stlc->fw_state != FW_STATE_READY) + goto out; + + if (ints & SPI_HOST_INT_UPDATE) { + stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE); + ret = stlc45xx_rx(stlc); + if (ret < 0) { + stlc45xx_reset(stlc); + goto out; + } + } + if (ints & SPI_HOST_INT_SW_UPDATE) { + stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE); + ret = stlc45xx_rx(stlc); + if (ret < 0) { + stlc45xx_reset(stlc); + goto out; + } + } + + ret = stlc45xx_wq_tx(stlc); + if (ret < 0) { + stlc45xx_reset(stlc); + goto out; + } + + ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS); + stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints); + +out: + mutex_unlock(&stlc->mutex); +} + +static void stlc45xx_tx_edcf(struct stlc45xx *stlc) +{ + struct s_lm_control *control; + struct s_lmo_edcf *edcf; + size_t len, edcf_len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + edcf_len = sizeof(*edcf); + len = sizeof(*control) + edcf_len; + control = kzalloc(len, GFP_KERNEL); + edcf = (struct s_lmo_edcf *) (control + 1); + + control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET; + control->length = edcf_len; + control->oid = LM_OID_EDCF; + + edcf->slottime = 0x14; + edcf->sifs = 10; + edcf->eofpad = 6; + edcf->maxburst = 1500; + + edcf->queues[0].aifs = 2; + edcf->queues[0].pad0 = 1; + edcf->queues[0].cwmin = 3; + edcf->queues[0].cwmax = 7; + edcf->queues[0].txop = 47; + edcf->queues[1].aifs = 2; + edcf->queues[1].pad0 = 0; + edcf->queues[1].cwmin = 7; + edcf->queues[1].cwmax = 15; + edcf->queues[1].txop = 94; + edcf->queues[2].aifs = 3; + edcf->queues[2].pad0 = 0; + edcf->queues[2].cwmin = 15; + edcf->queues[2].cwmax = 1023; + edcf->queues[2].txop = 0; + edcf->queues[3].aifs = 7; + edcf->queues[3].pad0 = 0; + edcf->queues[3].cwmin = 15; + edcf->queues[3].cwmax = 1023; + edcf->queues[3].txop = 0; + edcf->queues[4].aifs = 13; + edcf->queues[4].pad0 = 99; + edcf->queues[4].cwmin = 3437; + edcf->queues[4].cwmax = 512; + edcf->queues[4].txop = 12; + edcf->queues[5].aifs = 142; + edcf->queues[5].pad0 = 109; + edcf->queues[5].cwmin = 8756; + edcf->queues[5].cwmax = 6; + edcf->queues[5].txop = 0; + edcf->queues[6].aifs = 4; + edcf->queues[6].pad0 = 0; + edcf->queues[6].cwmin = 0; + edcf->queues[6].cwmax = 58705; + edcf->queues[6].txop = 25716; + edcf->queues[7].aifs = 0; + edcf->queues[7].pad0 = 0; + edcf->queues[7].cwmin = 0; + edcf->queues[7].cwmax = 0; + edcf->queues[7].txop = 0; + + stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len); + + kfree(control); +} + +static void stlc45xx_tx_setup(struct stlc45xx *stlc) +{ + struct s_lm_control *control; + struct s_lmo_setup *setup; + size_t len, setup_len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + setup_len = sizeof(*setup); + len = sizeof(*control) + setup_len; + control = kzalloc(len, GFP_KERNEL); + setup = (struct s_lmo_setup *) (control + 1); + + control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET; + control->length = setup_len; + control->oid = LM_OID_SETUP; + + setup->flags = LM_SETUP_INFRA; + setup->antenna = 2; + setup->rx_align = 0; + setup->rx_buffer = FIRMWARE_RXBUFFER_START; + setup->rx_mtu = FIRMWARE_MTU; + setup->frontend = 5; + setup->timeout = 0; + setup->truncate = 48896; + setup->bratemask = 0xffffffff; + setup->ref_clock = 644245094; + setup->lpf_bandwidth = 65535; + setup->osc_start_delay = 65535; + + memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN); + memcpy(setup->bssid, stlc->bssid, ETH_ALEN); + + stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len); + + kfree(control); +} + +static void stlc45xx_tx_scan(struct stlc45xx *stlc) +{ + struct s_lm_control *control; + struct s_lmo_scan *scan; + size_t len, scan_len; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + scan_len = sizeof(*scan); + len = sizeof(*control) + scan_len; + control = kzalloc(len, GFP_KERNEL); + scan = (struct s_lmo_scan *) (control + 1); + + control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET; + control->length = scan_len; + control->oid = LM_OID_SCAN; + + scan->flags = LM_SCAN_EXIT; + scan->bratemask = 0x15f; + scan->aloft[0] = 3; + scan->aloft[1] = 3; + scan->aloft[2] = 1; + scan->aloft[3] = 0; + scan->aloft[4] = 0; + scan->aloft[5] = 0; + scan->aloft[6] = 0; + scan->aloft[7] = 0; + + memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) * + RSSI_CAL_LEN], + RSSI_CAL_LEN); + memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) * + CHANNEL_CAL_LEN], + CHANNEL_CAL_LEN); + + stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len); + + kfree(control); +} + +/* + * caller must hold mutex + */ +static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave) +{ + struct ieee80211_hdr *pspoll; + int payload_len, padding, i; + struct s_lm_data_out *data; + struct txbuffer *entry; + struct sk_buff *skb; + char *payload; + u16 fc; + + skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16); + if (!skb) { + stlc45xx_warning("failed to allocate pspoll frame"); + return -ENOMEM; + } + skb_reserve(skb, stlc->hw->extra_tx_headroom); + + pspoll = (struct ieee80211_hdr *) skb_put(skb, 16); + memset(pspoll, 0, 16); + fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL; + if (powersave) + fc |= IEEE80211_FCTL_PM; + pspoll->frame_control = cpu_to_le16(fc); + pspoll->duration_id = cpu_to_le16(stlc->aid); + + /* aid in PS-Poll has its two MSBs each set to 1 */ + pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14); + + memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN); + memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN); + + stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %pM (powersave %d, " + "fc 0x%x, aid %d)", pspoll->addr1, + powersave, fc, stlc->aid); + + spin_lock_bh(&stlc->tx_lock); + + entry = stlc45xx_txbuffer_alloc(stlc, skb->len); + + spin_unlock_bh(&stlc->tx_lock); + + if (!entry) { + /* + * The queue should be stopped before the firmware buffer + * is full, so firmware buffer should always have enough + * space. + * + * But I'm too lazy and omit it for now. + */ + if (net_ratelimit()) + stlc45xx_warning("firmware tx buffer full is full " + "for null frame"); + return -ENOSPC; + } + + payload = skb->data; + payload_len = skb->len; + padding = (int) (skb->data - sizeof(*data)) & 3; + entry->header_len = sizeof(*data) + padding; + + entry->skb = skb; + entry->status_needed = false; + entry->handle = (u32) skb; + entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME); + + stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B " + "padding %d header_len %d)", + entry->handle, payload, payload_len, padding, + entry->header_len); + stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len); + + data = (struct s_lm_data_out *) skb_push(skb, entry->header_len); + + memset(data, 0, entry->header_len); + + if (padding) + data->flags = LM_FLAG_ALIGN; + + data->flags = LM_OUT_BURST; + data->length = payload_len; + data->handle = entry->handle; + data->aid = 1; + data->rts_retries = 7; + data->retries = 7; + data->aloft_ctrl = 0; + data->crypt_offset = 58; + data->keytype = 0; + data->keylen = 0; + data->queue = LM_QUEUE_DATA3; + data->backlog = 32; + data->antenna = 2; + data->cts = 3; + data->power = 127; + + for (i = 0; i < 8; i++) + data->aloft[i] = 0; + + /* + * check if there's enough space in tx buffer + * + * FIXME: ignored for now + */ + + stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len); + + list_add(&entry->tx_list, &stlc->tx_sent); + + return 0; +} + +/* + * caller must hold mutex + * + * shamelessly stolen from mac80211/ieee80211_send_nullfunc + */ +static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave) +{ + struct ieee80211_hdr *nullfunc; + int payload_len, padding, i; + struct s_lm_data_out *data; + struct txbuffer *entry; + struct sk_buff *skb; + char *payload; + u16 fc; + + skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24); + if (!skb) { + stlc45xx_warning("failed to allocate buffer for null frame\n"); + return -ENOMEM; + } + skb_reserve(skb, stlc->hw->extra_tx_headroom); + + nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); + memset(nullfunc, 0, 24); + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | + IEEE80211_FCTL_TODS; + + if (powersave) + fc |= IEEE80211_FCTL_PM; + + nullfunc->frame_control = cpu_to_le16(fc); + memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN); + memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN); + memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN); + + stlc45xx_debug(DEBUG_PSM, "sending Null frame to %pM (powersave %d, " + "fc 0x%x)", nullfunc->addr1, powersave, fc); + + spin_lock_bh(&stlc->tx_lock); + + entry = stlc45xx_txbuffer_alloc(stlc, skb->len); + + spin_unlock_bh(&stlc->tx_lock); + + if (!entry) { + /* + * The queue should be stopped before the firmware buffer + * is full, so firmware buffer should always have enough + * space. + * + * But I'm too lazy and omit it for now. + */ + if (net_ratelimit()) + stlc45xx_warning("firmware tx buffer full is full " + "for null frame"); + return -ENOSPC; + } + + payload = skb->data; + payload_len = skb->len; + padding = (int) (skb->data - sizeof(*data)) & 3; + entry->header_len = sizeof(*data) + padding; + + entry->skb = skb; + entry->status_needed = false; + entry->handle = (u32) skb; + entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME); + + stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B " + "padding %d header_len %d)", + entry->handle, payload, payload_len, padding, + entry->header_len); + stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len); + + data = (struct s_lm_data_out *) skb_push(skb, entry->header_len); + + memset(data, 0, entry->header_len); + + if (padding) + data->flags = LM_FLAG_ALIGN; + + data->flags = LM_OUT_BURST; + data->length = payload_len; + data->handle = entry->handle; + data->aid = 1; + data->rts_retries = 7; + data->retries = 7; + data->aloft_ctrl = 0; + data->crypt_offset = 58; + data->keytype = 0; + data->keylen = 0; + data->queue = LM_QUEUE_DATA3; + data->backlog = 32; + data->antenna = 2; + data->cts = 3; + data->power = 127; + + for (i = 0; i < 8; i++) + data->aloft[i] = 0; + + /* + * check if there's enough space in tx buffer + * + * FIXME: ignored for now + */ + + stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len); + + list_add(&entry->tx_list, &stlc->tx_sent); + + return 0; +} + +/* caller must hold mutex */ +static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable) +{ + struct s_lm_control *control; + struct s_lmo_psm *psm; + size_t len, psm_len; + + WARN_ON(!stlc->associated); + WARN_ON(stlc->aid < 1); + WARN_ON(stlc->aid > 2007); + + psm_len = sizeof(*psm); + len = sizeof(*control) + psm_len; + control = kzalloc(len, GFP_KERNEL); + psm = (struct s_lmo_psm *) (control + 1); + + control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET; + control->length = psm_len; + control->oid = LM_OID_PSM; + + if (enable) + psm->flags |= LM_PSM; + + psm->aid = stlc->aid; + + psm->beacon_rcpi_skip_max = 60; + + psm->intervals[0].interval = 1; + psm->intervals[0].periods = 1; + psm->intervals[1].interval = 1; + psm->intervals[1].periods = 1; + psm->intervals[2].interval = 1; + psm->intervals[2].periods = 1; + psm->intervals[3].interval = 1; + psm->intervals[3].periods = 1; + + psm->nr = 0; + psm->exclude[0] = 0; + + stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)", + psm->aid, psm->intervals[0].interval); + + stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len); + + kfree(control); +} + +static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct stlc45xx *stlc = hw->priv; + struct ieee80211_tx_info *info; + struct ieee80211_rate *rate; + int payload_len, padding, i; + struct s_lm_data_out *data; + struct txbuffer *entry; + char *payload; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + spin_lock_bh(&stlc->tx_lock); + + entry = stlc45xx_txbuffer_alloc(stlc, skb->len); + if (!entry) { + /* the queue should be stopped before the firmware buffer + * is full, so firmware buffer should always have enough + * space */ + if (net_ratelimit()) + stlc45xx_warning("firmware buffer full"); + spin_unlock_bh(&stlc->tx_lock); + return NETDEV_TX_BUSY; + } + + info = IEEE80211_SKB_CB(skb); + + payload = skb->data; + payload_len = skb->len; + padding = (int) (skb->data - sizeof(*data)) & 3; + entry->header_len = sizeof(*data) + padding; + + entry->skb = skb; + entry->status_needed = true; + entry->handle = (u32) skb; + entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME); + + stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B " + "padding %d header_len %d)", + entry->handle, payload, payload_len, padding, + entry->header_len); + stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len); + + data = (struct s_lm_data_out *) skb_push(skb, entry->header_len); + + memset(data, 0, entry->header_len); + + if (padding) + data->flags = LM_FLAG_ALIGN; + + data->flags = LM_OUT_BURST; + data->length = payload_len; + data->handle = entry->handle; + data->aid = 1; + data->rts_retries = 7; + data->retries = 7; + data->aloft_ctrl = 0; + data->crypt_offset = 58; + data->keytype = 0; + data->keylen = 0; + data->queue = 2; + data->backlog = 32; + data->antenna = 2; + data->cts = 3; + data->power = 127; + + for (i = 0; i < 8; i++) { + rate = ieee80211_get_tx_rate(stlc->hw, info); + data->aloft[i] = rate->hw_value; + } + + list_add_tail(&entry->tx_list, &stlc->tx_pending); + + /* check if there's enough space in tx buffer */ + if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) { + stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues"); + stlc->tx_queue_stopped = 1; + ieee80211_stop_queues(stlc->hw); + } + + queue_work(stlc->hw->workqueue, &stlc->work); + + spin_unlock_bh(&stlc->tx_lock); + + return NETDEV_TX_OK; +} + +static int stlc45xx_op_start(struct ieee80211_hw *hw) +{ + struct stlc45xx *stlc = hw->priv; + unsigned long timeout; + int ret = 0; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + mutex_lock(&stlc->mutex); + + stlc->fw_state = FW_STATE_BOOTING; + stlc->channel = 1; + + stlc45xx_power_on(stlc); + + ret = stlc45xx_upload_firmware(stlc); + if (ret < 0) { + stlc45xx_power_off(stlc); + goto out_unlock; + } + + stlc->tx_queue_stopped = 0; + + mutex_unlock(&stlc->mutex); + + timeout = msecs_to_jiffies(2000); + timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp, + timeout); + if (!timeout) { + stlc45xx_error("firmware boot failed"); + stlc45xx_power_off(stlc); + ret = -1; + goto out; + } + + stlc45xx_debug(DEBUG_BOOT, "firmware booted"); + + /* FIXME: should we take mutex just after wait_for_completion()? */ + mutex_lock(&stlc->mutex); + + WARN_ON(stlc->fw_state != FW_STATE_READY); + +out_unlock: + mutex_unlock(&stlc->mutex); + +out: + return ret; +} + +static void stlc45xx_op_stop(struct ieee80211_hw *hw) +{ + struct stlc45xx *stlc = hw->priv; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + mutex_lock(&stlc->mutex); + + WARN_ON(stlc->fw_state != FW_STATE_READY); + + stlc45xx_power_off(stlc); + + /* FIXME: make sure that all work_structs have completed */ + + spin_lock_bh(&stlc->tx_lock); + stlc45xx_flush_queues(stlc); + spin_unlock_bh(&stlc->tx_lock); + + stlc->fw_state = FW_STATE_OFF; + + mutex_unlock(&stlc->mutex); +} + +static int stlc45xx_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + struct stlc45xx *stlc = hw->priv; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + switch (conf->type) { + case NL80211_IFTYPE_STATION: + break; + default: + return -EOPNOTSUPP; + } + + memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN); + + return 0; +} + +static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); +} + +static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct stlc45xx *stlc = hw->priv; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + mutex_lock(&stlc->mutex); + + stlc->channel = hw->conf.channel->hw_value; + stlc45xx_tx_scan(stlc); + stlc45xx_tx_setup(stlc); + stlc45xx_tx_edcf(stlc); + + if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) { + stlc->psm = hw->conf.flags & IEEE80211_CONF_PS; + if (stlc->associated) { + stlc45xx_tx_psm(stlc, stlc->psm); + stlc45xx_tx_nullfunc(stlc, stlc->psm); + } + } + + mutex_unlock(&stlc->mutex); + + return 0; +} + +static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + int mc_count, + struct dev_addr_list *mc_list) +{ + *total_flags = 0; +} + +static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed) +{ + struct stlc45xx *stlc = hw->priv; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + mutex_lock(&stlc->mutex); + + memcpy(stlc->bssid, info->bssid, ETH_ALEN); + stlc45xx_tx_setup(stlc); + + mutex_unlock(&stlc->mutex); + + if (changed & BSS_CHANGED_ASSOC) { + stlc->associated = info->assoc; + if (info->assoc) + stlc->aid = info->aid; + else + stlc->aid = -1; + + if (stlc->psm) { + stlc45xx_tx_psm(stlc, stlc->psm); + stlc45xx_tx_nullfunc(stlc, stlc->psm); + } + } +} + + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_rate stlc45xx_rates[] = { + { .bitrate = 10, .hw_value = 0, .hw_value_short = 0, }, + { .bitrate = 20, .hw_value = 1, .hw_value_short = 1, }, + { .bitrate = 55, .hw_value = 2, .hw_value_short = 2, }, + { .bitrate = 110, .hw_value = 3, .hw_value_short = 3, }, + { .bitrate = 60, .hw_value = 4, .hw_value_short = 4, }, + { .bitrate = 90, .hw_value = 5, .hw_value_short = 5, }, + { .bitrate = 120, .hw_value = 6, .hw_value_short = 6, }, + { .bitrate = 180, .hw_value = 7, .hw_value_short = 7, }, + { .bitrate = 240, .hw_value = 8, .hw_value_short = 8, }, + { .bitrate = 360, .hw_value = 9, .hw_value_short = 9, }, + { .bitrate = 480, .hw_value = 10, .hw_value_short = 10, }, + { .bitrate = 540, .hw_value = 11, .hw_value_short = 11, }, +}; + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_channel stlc45xx_channels[] = { + { .hw_value = 1, .center_freq = 2412}, + { .hw_value = 2, .center_freq = 2417}, + { .hw_value = 3, .center_freq = 2422}, + { .hw_value = 4, .center_freq = 2427}, + { .hw_value = 5, .center_freq = 2432}, + { .hw_value = 6, .center_freq = 2437}, + { .hw_value = 7, .center_freq = 2442}, + { .hw_value = 8, .center_freq = 2447}, + { .hw_value = 9, .center_freq = 2452}, + { .hw_value = 10, .center_freq = 2457}, + { .hw_value = 11, .center_freq = 2462}, + { .hw_value = 12, .center_freq = 2467}, + { .hw_value = 13, .center_freq = 2472}, +}; + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_supported_band stlc45xx_band_2ghz = { + .channels = stlc45xx_channels, + .n_channels = ARRAY_SIZE(stlc45xx_channels), + .bitrates = stlc45xx_rates, + .n_bitrates = ARRAY_SIZE(stlc45xx_rates), +}; + +static const struct ieee80211_ops stlc45xx_ops = { + .start = stlc45xx_op_start, + .stop = stlc45xx_op_stop, + .add_interface = stlc45xx_op_add_interface, + .remove_interface = stlc45xx_op_remove_interface, + .config = stlc45xx_op_config, + .configure_filter = stlc45xx_op_configure_filter, + .tx = stlc45xx_op_tx, + .bss_info_changed = stlc45xx_op_bss_info_changed, +}; + +static int stlc45xx_register_mac80211(struct stlc45xx *stlc) +{ + /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr + to be non-const for some strange reason */ + static u8 default_mac_addr[ETH_ALEN] = { + 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee + }; + int ret; + + SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr); + + ret = ieee80211_register_hw(stlc->hw); + if (ret) { + stlc45xx_error("unable to register mac80211 hw: %d", ret); + return ret; + } + + return 0; +} + +static void stlc45xx_device_release(struct device *dev) +{ + +} + +static struct platform_device stlc45xx_device = { + .name = "stlc45xx", + .id = -1, + + /* device model insists to have a release function */ + .dev = { + .release = stlc45xx_device_release, + }, +}; + +static int __devinit stlc45xx_probe(struct spi_device *spi) +{ + struct stlc45xx *stlc; + struct ieee80211_hw *hw; + int ret; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + /* mac80211 alloc */ + hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops); + if (!hw) { + stlc45xx_error("could not alloc ieee80211_hw"); + ret = -ENOMEM; + goto out; + } + + /* mac80211 clears hw->priv */ + stlc = hw->priv; + + stlc->hw = hw; + dev_set_drvdata(&spi->dev, stlc); + stlc->spi = spi; + + spi->bits_per_word = 16; + spi->max_speed_hz = 24000000; + + ret = spi_setup(spi); + if (ret < 0) + stlc45xx_error("spi_setup failed"); + + ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power"); + if (ret < 0) { + stlc45xx_error("power GPIO request failed: %d", ret); + return ret; + } + + ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq"); + if (ret < 0) { + stlc45xx_error("irq GPIO request failed: %d", ret); + goto out; + } + + gpio_direction_output(stlc45xx_gpio_power, 0); + gpio_direction_input(stlc45xx_gpio_irq); + + ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq), + stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx", + stlc->spi); + if (ret < 0) + /* FIXME: handle the error */ + stlc45xx_error("request_irq() failed"); + + set_irq_type(gpio_to_irq(stlc45xx_gpio_irq), + IRQ_TYPE_EDGE_RISING); + + disable_irq(gpio_to_irq(stlc45xx_gpio_irq)); + + ret = platform_device_register(&stlc45xx_device); + if (ret) { + stlc45xx_error("Couldn't register wlan_omap device."); + return ret; + } + dev_set_drvdata(&stlc45xx_device.dev, stlc); + + INIT_WORK(&stlc->work, stlc45xx_work); + INIT_WORK(&stlc->work_reset, stlc45xx_work_reset); + INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout); + mutex_init(&stlc->mutex); + init_completion(&stlc->fw_comp); + spin_lock_init(&stlc->tx_lock); + INIT_LIST_HEAD(&stlc->txbuffer); + INIT_LIST_HEAD(&stlc->tx_pending); + INIT_LIST_HEAD(&stlc->tx_sent); + + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; + /* four bytes for padding */ + hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4; + + /* unit us */ + hw->channel_change_time = 1000; + + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz; + + SET_IEEE80211_DEV(hw, &spi->dev); + + BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN); + BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN); + + stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN, + GFP_KERNEL); + stlc->cal_channels = kmemdup(default_cal_channels, + CHANNEL_CAL_ARRAY_LEN, + GFP_KERNEL); + + ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi); + if (ret < 0) { + stlc45xx_error("failed to create sysfs file cal_rssi"); + goto out; + } + + ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels); + if (ret < 0) { + stlc45xx_error("failed to create sysfs file cal_channels"); + goto out; + } + + ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf); + if (ret < 0) { + stlc45xx_error("failed to create sysfs file tx_buf"); + goto out; + } + + ret = stlc45xx_register_mac80211(stlc); + if (ret < 0) + goto out; + + stlc45xx_info("v" DRIVER_VERSION " loaded"); + + stlc45xx_info("config buffer 0x%x-0x%x", + FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END); + stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x", + FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END, + FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END); + +out: + return ret; +} + +static int __devexit stlc45xx_remove(struct spi_device *spi) +{ + struct stlc45xx *stlc = dev_get_drvdata(&spi->dev); + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + platform_device_unregister(&stlc45xx_device); + + ieee80211_unregister_hw(stlc->hw); + + free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi); + + gpio_free(stlc45xx_gpio_power); + gpio_free(stlc45xx_gpio_irq); + + /* FIXME: free cal_channels and cal_rssi? */ + + kfree(stlc->fw); + + mutex_destroy(&stlc->mutex); + + /* frees also stlc */ + ieee80211_free_hw(stlc->hw); + stlc = NULL; + + return 0; +} + + +static struct spi_driver stlc45xx_spi_driver = { + .driver = { + /* use cx3110x name because board-n800.c uses that for the + * SPI port */ + .name = "cx3110x", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = stlc45xx_probe, + .remove = __devexit_p(stlc45xx_remove), +}; + +static int __init stlc45xx_init(void) +{ + int ret; + + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + ret = spi_register_driver(&stlc45xx_spi_driver); + if (ret < 0) { + stlc45xx_error("failed to register SPI driver: %d", ret); + goto out; + } + +out: + return ret; +} + +static void __exit stlc45xx_exit(void) +{ + stlc45xx_debug(DEBUG_FUNC, "%s", __func__); + + spi_unregister_driver(&stlc45xx_spi_driver); + + stlc45xx_info("unloaded"); +} + +module_init(stlc45xx_init); +module_exit(stlc45xx_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kalle Valo "); +MODULE_ALIAS("spi:cx3110x"); diff --git a/trunk/drivers/staging/stlc45xx/stlc45xx.h b/trunk/drivers/staging/stlc45xx/stlc45xx.h new file mode 100644 index 000000000000..ac96bbbde79f --- /dev/null +++ b/trunk/drivers/staging/stlc45xx/stlc45xx.h @@ -0,0 +1,283 @@ +/* + * This file is part of stlc45xx + * + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Kalle Valo + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include + +#include "stlc45xx_lmac.h" + +#define DRIVER_NAME "stlc45xx" +#define DRIVER_VERSION "0.1.3" + +#define DRIVER_PREFIX DRIVER_NAME ": " + +enum { + DEBUG_NONE = 0, + DEBUG_FUNC = 1 << 0, + DEBUG_IRQ = 1 << 1, + DEBUG_BH = 1 << 2, + DEBUG_RX = 1 << 3, + DEBUG_RX_CONTENT = 1 << 5, + DEBUG_TX = 1 << 6, + DEBUG_TX_CONTENT = 1 << 8, + DEBUG_TXBUFFER = 1 << 9, + DEBUG_QUEUE = 1 << 10, + DEBUG_BOOT = 1 << 11, + DEBUG_PSM = 1 << 12, + DEBUG_ALL = ~0, +}; + +#define DEBUG_LEVEL DEBUG_NONE +/* #define DEBUG_LEVEL DEBUG_ALL */ +/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_RX | DEBUG_IRQ) */ +/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_MEMREGION | DEBUG_QUEUE) */ +/* #define DEBUG_LEVEL (DEBUG_MEMREGION | DEBUG_QUEUE) */ + +#define stlc45xx_error(fmt, arg...) \ + printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) + +#define stlc45xx_warning(fmt, arg...) \ + printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) + +#define stlc45xx_info(fmt, arg...) \ + printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) + +#define stlc45xx_debug(level, fmt, arg...) \ + do { \ + if (level & DEBUG_LEVEL) \ + printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ + } while (0) + +#define stlc45xx_dump(level, buf, len) \ + do { \ + if (level & DEBUG_LEVEL) \ + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \ + 16, 1, buf, len, 1); \ + } while (0) + +#define MAC2STR(a) ((a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]) +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" + +/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */ +#define ADDR_READ_BIT_15 0x8000 + +#define SPI_ADRS_ARM_INTERRUPTS 0x00 +#define SPI_ADRS_ARM_INT_EN 0x04 + +#define SPI_ADRS_HOST_INTERRUPTS 0x08 +#define SPI_ADRS_HOST_INT_EN 0x0c +#define SPI_ADRS_HOST_INT_ACK 0x10 + +#define SPI_ADRS_GEN_PURP_1 0x14 +#define SPI_ADRS_GEN_PURP_2 0x18 + +/* high word */ +#define SPI_ADRS_DEV_CTRL_STAT 0x26 + +#define SPI_ADRS_DMA_DATA 0x28 + +#define SPI_ADRS_DMA_WRITE_CTRL 0x2c +#define SPI_ADRS_DMA_WRITE_LEN 0x2e +#define SPI_ADRS_DMA_WRITE_BASE 0x30 + +#define SPI_ADRS_DMA_READ_CTRL 0x34 +#define SPI_ADRS_DMA_READ_LEN 0x36 +#define SPI_ADRS_DMA_READ_BASE 0x38 + +#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000 +#define SPI_CTRL_STAT_START_HALTED 0x4000 +#define SPI_CTRL_STAT_RAM_BOOT 0x2000 +#define SPI_CTRL_STAT_HOST_RESET 0x1000 +#define SPI_CTRL_STAT_HOST_CPU_EN 0x0800 + +#define SPI_DMA_WRITE_CTRL_ENABLE 0x0001 +#define SPI_DMA_READ_CTRL_ENABLE 0x0001 +#define HOST_ALLOWED (1 << 7) + +#define FIRMWARE_ADDRESS 0x20000 + +#define SPI_TIMEOUT 100 /* msec */ + +#define SPI_MAX_TX_PACKETS 32 + +#define SPI_MAX_PACKET_SIZE 32767 + +#define SPI_TARGET_INT_WAKEUP 0x00000001 +#define SPI_TARGET_INT_SLEEP 0x00000002 +#define SPI_TARGET_INT_RDDONE 0x00000004 + +#define SPI_TARGET_INT_CTS 0x00004000 +#define SPI_TARGET_INT_DR 0x00008000 + +#define SPI_HOST_INT_READY 0x00000001 +#define SPI_HOST_INT_WR_READY 0x00000002 +#define SPI_HOST_INT_SW_UPDATE 0x00000004 +#define SPI_HOST_INT_UPDATE 0x10000000 + +/* clear to send */ +#define SPI_HOST_INT_CTS 0x00004000 + +/* data ready */ +#define SPI_HOST_INT_DR 0x00008000 + +#define SPI_HOST_INTS_DEFAULT \ + (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE) + +#define TARGET_BOOT_SLEEP 50 + +/* The firmware buffer is divided into three areas: + * + * o config area (for control commands) + * o tx buffer + * o rx buffer + */ +#define FIRMWARE_BUFFER_START 0x20200 +#define FIRMWARE_BUFFER_END 0x27c60 +#define FIRMWARE_BUFFER_LEN (FIRMWARE_BUFFER_END - FIRMWARE_BUFFER_START) +#define FIRMWARE_MTU 3240 +#define FIRMWARE_CONFIG_PAYLOAD_LEN 1024 +#define FIRMWARE_CONFIG_START FIRMWARE_BUFFER_START +#define FIRMWARE_CONFIG_LEN (sizeof(struct s_lm_control) + \ + FIRMWARE_CONFIG_PAYLOAD_LEN) +#define FIRMWARE_CONFIG_END (FIRMWARE_CONFIG_START + FIRMWARE_CONFIG_LEN - 1) +#define FIRMWARE_RXBUFFER_LEN (5 * FIRMWARE_MTU + 1024) +#define FIRMWARE_RXBUFFER_START (FIRMWARE_BUFFER_END - FIRMWARE_RXBUFFER_LEN) +#define FIRMWARE_RXBUFFER_END (FIRMWARE_RXBUFFER_START + \ + FIRMWARE_RXBUFFER_LEN - 1) +#define FIRMWARE_TXBUFFER_START (FIRMWARE_BUFFER_START + FIRMWARE_CONFIG_LEN) +#define FIRMWARE_TXBUFFER_LEN (FIRMWARE_BUFFER_LEN - FIRMWARE_CONFIG_LEN - \ + FIRMWARE_RXBUFFER_LEN) +#define FIRMWARE_TXBUFFER_END (FIRMWARE_TXBUFFER_START + \ + FIRMWARE_TXBUFFER_LEN - 1) + +#define FIRMWARE_TXBUFFER_HEADER 100 +#define FIRMWARE_TXBUFFER_TRAILER 4 + +/* FIXME: come up with a proper value */ +#define MAX_FRAME_LEN 2500 + +/* unit is ms */ +#define TX_FRAME_LIFETIME 2000 +#define TX_TIMEOUT 4000 + +#define SUPPORTED_CHANNELS 13 + +/* FIXME */ +/* #define CHANNEL_CAL_LEN offsetof(struct s_lmo_scan, bratemask) - \ */ +/* offsetof(struct s_lmo_scan, channel) */ +#define CHANNEL_CAL_LEN 292 +#define CHANNEL_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * CHANNEL_CAL_LEN) +/* FIXME */ +/* #define RSSI_CAL_LEN sizeof(struct s_lmo_scan) - \ */ +/* offsetof(struct s_lmo_scan, rssical) */ +#define RSSI_CAL_LEN 8 +#define RSSI_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * RSSI_CAL_LEN) + +struct s_dma_regs { + unsigned short cmd; + unsigned short len; + unsigned long addr; +}; + +struct stlc45xx_ie_tim { + u8 dtim_count; + u8 dtim_period; + u8 bmap_control; + u8 pvbmap[251]; +}; + +struct txbuffer { + /* can be removed when switched to skb queue */ + struct list_head tx_list; + + struct list_head buffer_list; + + int start; + int frame_start; + int end; + + struct sk_buff *skb; + u32 handle; + + bool status_needed; + + int header_len; + + /* unit jiffies */ + unsigned long lifetime; +}; + +enum fw_state { + FW_STATE_OFF, + FW_STATE_BOOTING, + FW_STATE_READY, + FW_STATE_RESET, + FW_STATE_RESETTING, +}; + +struct stlc45xx { + struct ieee80211_hw *hw; + struct spi_device *spi; + struct work_struct work; + struct work_struct work_reset; + struct delayed_work work_tx_timeout; + struct mutex mutex; + struct completion fw_comp; + + + u8 bssid[ETH_ALEN]; + u8 mac_addr[ETH_ALEN]; + int channel; + + u8 *cal_rssi; + u8 *cal_channels; + + enum fw_state fw_state; + + spinlock_t tx_lock; + + /* protected by tx_lock */ + struct list_head txbuffer; + + /* protected by tx_lock */ + struct list_head tx_pending; + + /* protected by tx_lock */ + int tx_queue_stopped; + + /* protected by mutex */ + struct list_head tx_sent; + + int tx_frames; + + u8 *fw; + int fw_len; + + bool psm; + bool associated; + int aid; + bool pspolling; +}; + + diff --git a/trunk/drivers/staging/stlc45xx/stlc45xx_lmac.h b/trunk/drivers/staging/stlc45xx/stlc45xx_lmac.h new file mode 100644 index 000000000000..af5db801347f --- /dev/null +++ b/trunk/drivers/staging/stlc45xx/stlc45xx_lmac.h @@ -0,0 +1,434 @@ +/************************************************************************ +* This is the LMAC API interface header file for STLC4560. * +* Copyright (C) 2007 Conexant Systems, Inc. * +* This program is free software; you can redistribute it and/or * +* modify it under the terms of the GNU General Public License * +* as published by the Free Software Foundation; either version 2 * +* of the License, or (at your option) any later version. * +* * +* 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. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program. If not, see .* +*************************************************************************/ + +#ifndef __lmac_h__ +#define __lmac_h__ + +#define LM_TOP_VARIANT 0x0506 +#define LM_BOTTOM_VARIANT 0x0506 + +/* + * LMAC - UMAC interface definition: + */ + +#define LM_FLAG_CONTROL 0x8000 +#define LM_FLAG_ALIGN 0x4000 + +#define LM_CTRL_OPSET 0x0001 + +#define LM_OUT_PROMISC 0x0001 +#define LM_OUT_TIMESTAMP 0x0002 +#define LM_OUT_SEQNR 0x0004 +#define LM_OUT_BURST 0x0010 +#define LM_OUT_NOCANCEL 0x0020 +#define LM_OUT_CLEARTIM 0x0040 +#define LM_OUT_HITCHHIKE 0x0080 +#define LM_OUT_COMPRESS 0x0100 +#define LM_OUT_CONCAT 0x0200 +#define LM_OUT_PCS_ACCEPT 0x0400 +#define LM_OUT_WAITEOSP 0x0800 + + +#define LM_ALOFT_SP 0x10 +#define LM_ALOFT_CTS 0x20 +#define LM_ALOFT_RTS 0x40 +#define LM_ALOFT_MASK 0x1f +#define LM_ALOFT_RATE 0x0f + +#define LM_IN_FCS_GOOD 0x0001 +#define LM_IN_MATCH_MAC 0x0002 +#define LM_IN_MCBC 0x0004 +#define LM_IN_BEACON 0x0008 +#define LM_IN_MATCH_BSS 0x0010 +#define LM_IN_BCAST_BSS 0x0020 +#define LM_IN_DATA 0x0040 +#define LM_IN_TRUNCATED 0x0080 + +#define LM_IN_TRANSPARENT 0x0200 + +#define LM_QUEUE_BEACON 0 +#define LM_QUEUE_SCAN 1 +#define LM_QUEUE_MGT 2 +#define LM_QUEUE_MCBC 3 +#define LM_QUEUE_DATA 4 +#define LM_QUEUE_DATA0 4 +#define LM_QUEUE_DATA1 5 +#define LM_QUEUE_DATA2 6 +#define LM_QUEUE_DATA3 7 + +#define LM_SETUP_INFRA 0x0001 +#define LM_SETUP_IBSS 0x0002 +#define LM_SETUP_TRANSPARENT 0x0008 +#define LM_SETUP_PROMISCUOUS 0x0010 +#define LM_SETUP_HIBERNATE 0x0020 +#define LM_SETUP_NOACK 0x0040 +#define LM_SETUP_RX_DISABLED 0x0080 + +#define LM_ANTENNA_0 0 +#define LM_ANTENNA_1 1 +#define LM_ANTENNA_DIVERSITY 2 + +#define LM_TX_FAILED 0x0001 +#define LM_TX_PSM 0x0002 +#define LM_TX_PSM_CANCELLED 0x0004 + +#define LM_SCAN_EXIT 0x0001 +#define LM_SCAN_TRAP 0x0002 +#define LM_SCAN_ACTIVE 0x0004 +#define LM_SCAN_FILTER 0x0008 + +#define LM_PSM 0x0001 +#define LM_PSM_DTIM 0x0002 +#define LM_PSM_MCBC 0x0004 +#define LM_PSM_CHECKSUM 0x0008 +#define LM_PSM_SKIP_MORE_DATA 0x0010 +#define LM_PSM_BEACON_TIMEOUT 0x0020 +#define LM_PSM_HFOSLEEP 0x0040 +#define LM_PSM_AUTOSWITCH_SLEEP 0x0080 +#define LM_PSM_LPIT 0x0100 +#define LM_PSM_BF_UCAST_SKIP 0x0200 +#define LM_PSM_BF_MCAST_SKIP 0x0400 + +/* hfosleep */ +#define LM_PSM_SLEEP_OPTION_MASK (LM_PSM_AUTOSWITCH_SLEEP | LM_PSM_HFOSLEEP) +#define LM_PSM_SLEEP_OPTION_SHIFT 6 +/* hfosleepend */ +#define LM_PSM_BF_OPTION_MASK (LM_PSM_BF_MCAST_SKIP | LM_PSM_BF_UCAST_SKIP) +#define LM_PSM_BF_OPTION_SHIFT 9 + + +#define LM_PRIVACC_WEP 0x01 +#define LM_PRIVACC_TKIP 0x02 +#define LM_PRIVACC_MICHAEL 0x04 +#define LM_PRIVACC_CCX_KP 0x08 +#define LM_PRIVACC_CCX_MIC 0x10 +#define LM_PRIVACC_AES_CCMP 0x20 + +/* size of s_lm_descr in words */ +#define LM_DESCR_SIZE_WORDS 11 + +#ifndef __ASSEMBLER__ + +enum { + LM_MODE_CLIENT = 0, + LM_MODE_AP +}; + +struct s_lm_descr { + uint16_t modes; + uint16_t flags; + uint32_t buffer_start; + uint32_t buffer_end; + uint8_t header; + uint8_t trailer; + uint8_t tx_queues; + uint8_t tx_depth; + uint8_t privacy; + uint8_t rx_keycache; + uint8_t tim_size; + uint8_t pad1; + uint8_t rates[16]; + uint32_t link; + uint16_t mtu; +}; + + +struct s_lm_control { + uint16_t flags; + uint16_t length; + uint32_t handle; + uint16_t oid; + uint16_t pad; + /* uint8_t data[]; */ +}; + +enum { + LM_PRIV_NONE = 0, + LM_PRIV_WEP, + LM_PRIV_TKIP, + LM_PRIV_TKIPMICHAEL, + LM_PRIV_CCX_WEPMIC, + LM_PRIV_CCX_KPMIC, + LM_PRIV_CCX_KP, + LM_PRIV_AES_CCMP +}; + +enum { + LM_DECRYPT_NONE, + LM_DECRYPT_OK, + LM_DECRYPT_NOKEY, + LM_DECRYPT_NOMICHAEL, + LM_DECRYPT_NOCKIPMIC, + LM_DECRYPT_FAIL_WEP, + LM_DECRYPT_FAIL_TKIP, + LM_DECRYPT_FAIL_MICHAEL, + LM_DECRYPT_FAIL_CKIPKP, + LM_DECRYPT_FAIL_CKIPMIC, + LM_DECRYPT_FAIL_AESCCMP +}; + +struct s_lm_data_out { + uint16_t flags; + uint16_t length; + uint32_t handle; + uint16_t aid; + uint8_t rts_retries; + uint8_t retries; + uint8_t aloft[8]; + uint8_t aloft_ctrl; + uint8_t crypt_offset; + uint8_t keytype; + uint8_t keylen; + uint8_t key[16]; + uint8_t queue; + uint8_t backlog; + uint16_t durations[4]; + uint8_t antenna; + uint8_t cts; + int16_t power; + uint8_t pad[2]; + /*uint8_t data[];*/ +}; + +#define LM_RCPI_INVALID (0xff) + +struct s_lm_data_in { + uint16_t flags; + uint16_t length; + uint16_t frequency; + uint8_t antenna; + uint8_t rate; + uint8_t rcpi; + uint8_t sq; + uint8_t decrypt; + uint8_t rssi_raw; + uint32_t clock[2]; + /*uint8_t data[];*/ +}; + +union u_lm_data { + struct s_lm_data_out out; + struct s_lm_data_in in; +}; + +enum { + LM_OID_SETUP = 0, + LM_OID_SCAN = 1, + LM_OID_TRAP = 2, + LM_OID_EDCF = 3, + LM_OID_KEYCACHE = 4, + LM_OID_PSM = 6, + LM_OID_TXCANCEL = 7, + LM_OID_TX = 8, + LM_OID_BURST = 9, + LM_OID_STATS = 10, + LM_OID_LED = 13, + LM_OID_TIMER = 15, + LM_OID_NAV = 20, + LM_OID_PCS = 22, + LM_OID_BT_BALANCER = 28, + LM_OID_GROUP_ADDRESS_TABLE = 30, + LM_OID_ARPTABLE = 31, + LM_OID_BT_OPTIONS = 35 +}; + +enum { + LM_FRONTEND_UNKNOWN = 0, + LM_FRONTEND_DUETTE3, + LM_FRONTEND_DUETTE2, + LM_FRONTEND_FRISBEE, + LM_FRONTEND_CROSSBOW, + LM_FRONTEND_LONGBOW +}; + + +#define INVALID_LPF_BANDWIDTH 0xffff +#define INVALID_OSC_START_DELAY 0xffff + +struct s_lmo_setup { + uint16_t flags; + uint8_t macaddr[6]; + uint8_t bssid[6]; + uint8_t antenna; + uint8_t rx_align; + uint32_t rx_buffer; + uint16_t rx_mtu; + uint16_t frontend; + uint16_t timeout; + uint16_t truncate; + uint32_t bratemask; + uint8_t sbss_offset; + uint8_t mcast_window; + uint8_t rx_rssi_threshold; + uint8_t rx_ed_threshold; + uint32_t ref_clock; + uint16_t lpf_bandwidth; + uint16_t osc_start_delay; +}; + + +struct s_lmo_scan { + uint16_t flags; + uint16_t dwell; + uint8_t channel[292]; + uint32_t bratemask; + uint8_t aloft[8]; + uint8_t rssical[8]; +}; + + +enum { + LM_TRAP_SCAN = 0, + LM_TRAP_TIMER, + LM_TRAP_BEACON_TX, + LM_TRAP_FAA_RADIO_ON, + LM_TRAP_FAA_RADIO_OFF, + LM_TRAP_RADAR, + LM_TRAP_NO_BEACON, + LM_TRAP_TBTT, + LM_TRAP_SCO_ENTER, + LM_TRAP_SCO_EXIT +}; + +struct s_lmo_trap { + uint16_t event; + uint16_t frequency; +}; + +struct s_lmo_timer { + uint32_t interval; +}; + +struct s_lmo_nav { + uint32_t period; +}; + + +struct s_lmo_edcf_queue; + +struct s_lmo_edcf { + uint8_t flags; + uint8_t slottime; + uint8_t sifs; + uint8_t eofpad; + struct s_lmo_edcf_queue { + uint8_t aifs; + uint8_t pad0; + uint16_t cwmin; + uint16_t cwmax; + uint16_t txop; + } queues[8]; + uint8_t mapping[4]; + uint16_t maxburst; + uint16_t round_trip_delay; +}; + +struct s_lmo_keycache { + uint8_t entry; + uint8_t keyid; + uint8_t address[6]; + uint8_t pad[2]; + uint8_t keytype; + uint8_t keylen; + uint8_t key[24]; +}; + + +struct s_lm_interval; + +struct s_lmo_psm { + uint16_t flags; + uint16_t aid; + struct s_lm_interval { + uint16_t interval; + uint16_t periods; + } intervals[4]; + /* uint16_t pad; */ + uint8_t beacon_rcpi_skip_max; + uint8_t rcpi_delta_threshold; + uint8_t nr; + uint8_t exclude[1]; +}; + +#define MC_FILTER_ADDRESS_NUM 4 + +struct s_lmo_group_address_table { + uint16_t filter_enable; + uint16_t num_address; + uint8_t macaddr_list[MC_FILTER_ADDRESS_NUM][6]; +}; + +struct s_lmo_txcancel { + uint32_t address[1]; +}; + + +struct s_lmo_tx { + uint8_t flags; + uint8_t retries; + uint8_t rcpi; + uint8_t sq; + uint16_t seqctrl; + uint8_t antenna; + uint8_t pad; +}; + +struct s_lmo_burst { + uint8_t flags; + uint8_t queue; + uint8_t backlog; + uint8_t pad; + uint16_t durations[32]; +}; + +struct s_lmo_stats { + uint32_t valid; + uint32_t fcs; + uint32_t abort; + uint32_t phyabort; + uint32_t rts_success; + uint32_t rts_fail; + uint32_t timestamp; + uint32_t time_tx; + uint32_t noisefloor; + uint32_t sample_noise[8]; + uint32_t sample_cca; + uint32_t sample_tx; +}; + + +struct s_lmo_led { + uint16_t flags; + uint16_t mask[2]; + uint16_t delay/*[2]*/; +}; + + +struct s_lmo_bt_balancer { + uint16_t prio_thresh; + uint16_t acl_thresh; +}; + + +struct s_lmo_arp_table { + uint16_t filter_enable; + uint32_t ipaddr; +}; + +#endif /* __ASSEMBLER__ */ + +#endif /* __lmac_h__ */ diff --git a/trunk/drivers/staging/vt6656/main_usb.c b/trunk/drivers/staging/vt6656/main_usb.c index 05186110c029..7f96bcaf1c60 100644 --- a/trunk/drivers/staging/vt6656/main_usb.c +++ b/trunk/drivers/staging/vt6656/main_usb.c @@ -1332,6 +1332,7 @@ device_release_WPADEV(pDevice); free_netdev(pDevice->dev); } + kfree(pDevice); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n"); } diff --git a/trunk/drivers/staging/winbond/Kconfig b/trunk/drivers/staging/winbond/Kconfig index 132671d96d0d..940460c39f36 100644 --- a/trunk/drivers/staging/winbond/Kconfig +++ b/trunk/drivers/staging/winbond/Kconfig @@ -1,6 +1,6 @@ config W35UND tristate "IS89C35 WLAN USB driver" - depends on MAC80211 && WLAN && USB && EXPERIMENTAL + depends on MAC80211 && WLAN_80211 && USB && EXPERIMENTAL default n ---help--- This is highly experimental driver for Winbond WIFI card. diff --git a/trunk/drivers/staging/wlan-ng/Kconfig b/trunk/drivers/staging/wlan-ng/Kconfig index f44294b0d8dc..9959b658c8cf 100644 --- a/trunk/drivers/staging/wlan-ng/Kconfig +++ b/trunk/drivers/staging/wlan-ng/Kconfig @@ -1,6 +1,6 @@ config PRISM2_USB tristate "Prism2.5/3 USB driver" - depends on WLAN && USB && WIRELESS_EXT + depends on WLAN_80211 && USB && WIRELESS_EXT default n ---help--- This is the wlan-ng prism 2.5/3 USB driver for a wide range of diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index fa3d142ba64d..42a74b8a0bb8 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -2139,7 +2139,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, static void fsl_udc_release(struct device *dev) { complete(udc_controller->done); - dma_free_coherent(dev->parent, udc_controller->ep_qh_size, + dma_free_coherent(dev, udc_controller->ep_qh_size, udc_controller->ep_qh, udc_controller->ep_qh_dma); kfree(udc_controller); } diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index e33d36256350..749b53742828 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -1003,20 +1003,19 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, if (syssts == SE0) { r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); - } else { - if (syssts == FS_JSTS) - r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); - else if (syssts == LS_JSTS) - r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); + return; + } - r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); - r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); + if (syssts == FS_JSTS) + r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); + else if (syssts == LS_JSTS) + r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); - if (r8a66597->bus_suspended) - usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); - } + r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); + r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); - usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597)); + if (r8a66597->bus_suspended) + usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); } /* this function must be called with interrupt disabled */ @@ -1025,8 +1024,6 @@ static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port) u16 speed = get_rh_usb_speed(r8a66597, port); struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; - rh->port &= ~((1 << USB_PORT_FEAT_HIGHSPEED) | - (1 << USB_PORT_FEAT_LOWSPEED)); if (speed == HSMODE) rh->port |= (1 << USB_PORT_FEAT_HIGHSPEED); else if (speed == LSMODE) diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index cd44c68954df..65d96b214f95 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -315,9 +315,6 @@ static int option_resume(struct usb_serial *serial); #define QISDA_PRODUCT_H20_4515 0x4515 #define QISDA_PRODUCT_H20_4519 0x4519 -/* TLAYTECH PRODUCTS */ -#define TLAYTECH_VENDOR_ID 0x20B9 -#define TLAYTECH_PRODUCT_TEU800 0x1682 /* TOSHIBA PRODUCTS */ #define TOSHIBA_VENDOR_ID 0x0930 @@ -596,7 +593,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, - { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 5019325ba25d..45883988a005 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -296,6 +296,7 @@ struct sierra_port_private { int dsr_state; int dcd_state; int ri_state; + unsigned int opened:1; }; @@ -305,8 +306,6 @@ static int sierra_send_setup(struct usb_serial_port *port) struct sierra_port_private *portdata; __u16 interface = 0; int val = 0; - int do_send = 0; - int retval; dev_dbg(&port->dev, "%s\n", __func__); @@ -325,7 +324,10 @@ static int sierra_send_setup(struct usb_serial_port *port) */ if (port->interrupt_in_urb) { /* send control message */ - do_send = 1; + return usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), + 0x22, 0x21, val, interface, + NULL, 0, USB_CTRL_SET_TIMEOUT); } } @@ -337,18 +339,12 @@ static int sierra_send_setup(struct usb_serial_port *port) interface = 1; else if (port->bulk_out_endpointAddress == 5) interface = 2; - - do_send = 1; + return usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), + 0x22, 0x21, val, interface, + NULL, 0, USB_CTRL_SET_TIMEOUT); } - if (!do_send) - return 0; - - usb_autopm_get_interface(serial->interface); - retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT); - usb_autopm_put_interface(serial->interface); - - return retval; + return 0; } static void sierra_set_termios(struct tty_struct *tty, @@ -777,11 +773,8 @@ static void sierra_close(struct usb_serial_port *port) if (serial->dev) { mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) { - serial->interface->needs_remote_wakeup = 0; - usb_autopm_get_interface(serial->interface); + if (!serial->disconnected) sierra_send_setup(port); - } mutex_unlock(&serial->disc_mutex); spin_lock_irq(&intfdata->susp_lock); portdata->opened = 0; @@ -795,6 +788,8 @@ static void sierra_close(struct usb_serial_port *port) sierra_release_urb(portdata->in_urbs[i]); portdata->in_urbs[i] = NULL; } + usb_autopm_get_interface(serial->interface); + serial->interface->needs_remote_wakeup = 0; } } @@ -832,8 +827,6 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) if (err) { /* get rid of everything as in close */ sierra_close(port); - /* restore balance for autopm */ - usb_autopm_put_interface(serial->interface); return err; } sierra_send_setup(port); @@ -922,7 +915,7 @@ static void sierra_release(struct usb_serial *serial) #ifdef CONFIG_PM static void stop_read_write_urbs(struct usb_serial *serial) { - int i; + int i, j; struct usb_serial_port *port; struct sierra_port_private *portdata; @@ -930,7 +923,8 @@ static void stop_read_write_urbs(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; portdata = usb_get_serial_port_data(port); - sierra_stop_rx_urbs(port); + for (j = 0; j < N_IN_URB; j++) + usb_kill_urb(portdata->in_urbs[j]); usb_kill_anchored_urbs(&portdata->active); } } diff --git a/trunk/firmware/Makefile b/trunk/firmware/Makefile index f4ca0c7eb51c..a6c7c3e47e42 100644 --- a/trunk/firmware/Makefile +++ b/trunk/firmware/Makefile @@ -69,13 +69,11 @@ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \ cis/DP83903.cis cis/NE2K.cis \ - cis/tamarack.cis cis/PE-200.cis + cis/tamarack.cis fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \ - cis/COMpad2.cis cis/COMpad4.cis \ - cis/SW_555_SER.cis cis/SW_7xx_SER.cis \ - cis/SW_8xx_SER.cis + cis/COMpad2.cis cis/COMpad4.cis fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ advansys/3550.bin advansys/38C0800.bin diff --git a/trunk/firmware/WHENCE b/trunk/firmware/WHENCE index 7a8adc06eb34..c437e14f0b11 100644 --- a/trunk/firmware/WHENCE +++ b/trunk/firmware/WHENCE @@ -600,7 +600,6 @@ File: cis/LA-PCM.cis cis/DP83903.cis cis/NE2K.cis cis/tamarack.cis - cis/PE-200.cis Licence: GPL @@ -634,9 +633,6 @@ File: cis/MT5634ZLX.cis cis/RS-COM-2P.cis cis/COMpad2.cis cis/COMpad4.cis - cis/SW_555_SER.cis - cis/SW_7xx_SER.cis - cis/SW_8xx_SER.cis Licence: GPL diff --git a/trunk/firmware/cis/PE-200.cis.ihex b/trunk/firmware/cis/PE-200.cis.ihex deleted file mode 100644 index e6dbdab6eb79..000000000000 --- a/trunk/firmware/cis/PE-200.cis.ihex +++ /dev/null @@ -1,9 +0,0 @@ -:1000000001030000FF151E0401504D582020200060 -:1000100050452D3230300045544845524E4554002D -:1000200052303100FF210206031A050101000101CF -:100030001B0EC181190155E051000F100F30FFFF59 -:040040001400FF00A9 -:00000001FF -# -# Replacement CIS for PE-200 ethernet card -# diff --git a/trunk/firmware/cis/SW_555_SER.cis.ihex b/trunk/firmware/cis/SW_555_SER.cis.ihex deleted file mode 100644 index 9b9348acee7b..000000000000 --- a/trunk/firmware/cis/SW_555_SER.cis.ihex +++ /dev/null @@ -1,12 +0,0 @@ -:100000000101FF17034100FF20043F0110072102F7 -:100010000200152A070053696572726120576972E0 -:10002000656C657373004169724361726420353594 -:1000300035004135353500526576203100FF1A050F -:1000400001030007731B0BE00118A360F8030730DE -:10005000BC3F1B08A10108A360F802071B08A2010E -:1000600008A360E803071B08A30108A360E80207D0 -:0A0070001B04A40108231400FF0084 -:00000001FF -# -# Replacement CIS for AC555 provided by Sierra Wireless -# diff --git a/trunk/firmware/cis/SW_7xx_SER.cis.ihex b/trunk/firmware/cis/SW_7xx_SER.cis.ihex deleted file mode 100644 index 11e44ad86437..000000000000 --- a/trunk/firmware/cis/SW_7xx_SER.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:100000000101FF17034100FF2004920110072102A4 -:1000100002001537070053696572726120576972D3 -:10002000656C6573730041433731302F4143373579 -:10003000300047505253204E6574776F726B2041E9 -:1000400064617074657200523100FF1A050103008B -:1000500007731B10E00119784D555D25A360F80367 -:100060000730BC861B08A10108A360F802071B0823 -:10007000A20108A360E803071B08A30108A360E826 -:0C00800002071B04A40108231400FF0069 -:00000001FF -# -# Replacement CIS for AC7xx provided by Sierra Wireless -# diff --git a/trunk/firmware/cis/SW_8xx_SER.cis.ihex b/trunk/firmware/cis/SW_8xx_SER.cis.ihex deleted file mode 100644 index bbcfe6348328..000000000000 --- a/trunk/firmware/cis/SW_8xx_SER.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:100000000101FF17034100FF2004920110072102A4 -:100010000200152F070053696572726120576972DB -:10002000656C657373004143383530003347204EAB -:100030006574776F726B20416461707465720052F1 -:100040003100FF1A0501030007731B10E001197846 -:100050004D555D25A360F8480730BC861B08A101FB -:1000600008A360F847071B08A20108A360E8480737 -:100070001B08A30108A360E847071B04A401082389 -:040080001400FF0069 -:00000001FF -# -# Replacement CIS for AC8xx provided by Sierra Wireless -# diff --git a/trunk/fs/9p/vfs_dir.c b/trunk/fs/9p/vfs_dir.c index 15cce53bf61e..873cd31baa47 100644 --- a/trunk/fs/9p/vfs_dir.c +++ b/trunk/fs/9p/vfs_dir.c @@ -39,24 +39,6 @@ #include "v9fs_vfs.h" #include "fid.h" -/** - * struct p9_rdir - readdir accounting - * @mutex: mutex protecting readdir - * @head: start offset of current dirread buffer - * @tail: end offset of current dirread buffer - * @buf: dirread buffer - * - * private structure for keeping track of readdir - * allocated on demand - */ - -struct p9_rdir { - struct mutex mutex; - int head; - int tail; - uint8_t *buf; -}; - /** * dt_type - return file type * @mistat: mistat structure @@ -88,79 +70,56 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) { int over; struct p9_wstat st; - int err = 0; + int err; struct p9_fid *fid; int buflen; - int reclen = 0; - struct p9_rdir *rdir; + char *statbuf; + int n, i = 0; P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); fid = filp->private_data; buflen = fid->clnt->msize - P9_IOHDRSZ; - - /* allocate rdir on demand */ - if (!fid->rdir) { - rdir = kmalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL); - - if (rdir == NULL) { - err = -ENOMEM; - goto exit; - } - spin_lock(&filp->f_dentry->d_lock); - if (!fid->rdir) { - rdir->buf = (uint8_t *)rdir + sizeof(struct p9_rdir); - mutex_init(&rdir->mutex); - rdir->head = rdir->tail = 0; - fid->rdir = (void *) rdir; - rdir = NULL; - } - spin_unlock(&filp->f_dentry->d_lock); - kfree(rdir); - } - rdir = (struct p9_rdir *) fid->rdir; - - err = mutex_lock_interruptible(&rdir->mutex); - while (err == 0) { - if (rdir->tail == rdir->head) { - err = v9fs_file_readn(filp, rdir->buf, NULL, - buflen, filp->f_pos); - if (err <= 0) - goto unlock_and_exit; - - rdir->head = 0; - rdir->tail = err; - } - - while (rdir->head < rdir->tail) { - err = p9stat_read(rdir->buf + rdir->head, - buflen - rdir->head, &st, - fid->clnt->dotu); + statbuf = kmalloc(buflen, GFP_KERNEL); + if (!statbuf) + return -ENOMEM; + + while (1) { + err = v9fs_file_readn(filp, statbuf, NULL, buflen, + fid->rdir_fpos); + if (err <= 0) + break; + + n = err; + while (i < n) { + err = p9stat_read(statbuf + i, buflen-i, &st, + fid->clnt->dotu); if (err) { P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err); err = -EIO; p9stat_free(&st); - goto unlock_and_exit; + goto free_and_exit; } - reclen = st.size+2; + + i += st.size+2; + fid->rdir_fpos += st.size+2; over = filldir(dirent, st.name, strlen(st.name), filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st)); + filp->f_pos += st.size+2; + p9stat_free(&st); if (over) { err = 0; - goto unlock_and_exit; + goto free_and_exit; } - rdir->head += reclen; - filp->f_pos += reclen; } } -unlock_and_exit: - mutex_unlock(&rdir->mutex); -exit: +free_and_exit: + kfree(statbuf); return err; } diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index 18f74ec4dce9..5947628aefef 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -994,7 +994,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) P9_DPRINTK(P9_DEBUG_VFS, "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer); - retval = strnlen(buffer, buflen); + retval = buflen; + done: kfree(st); return retval; @@ -1061,7 +1062,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) __putname(link); link = ERR_PTR(len); } else - link[min(len, PATH_MAX-1)] = 0; + link[len] = 0; } nd_set_link(nd, link); diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index 2126078a38ed..64d44efad7a5 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -135,7 +135,7 @@ config TMPFS_POSIX_ACL config HUGETLBFS bool "HugeTLB file system support" - depends on X86 || IA64 || PPC_BOOK3S_64 || SPARC64 || (S390 && 64BIT) || \ + depends on X86 || IA64 || SPARC64 || (S390 && 64BIT) || \ SYS_SUPPORTS_HUGETLBFS || BROKEN help hugetlbfs is a filesystem backing for HugeTLB pages, based on diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 12da5db8682c..402cb84a92a1 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -325,16 +325,8 @@ static void bio_fs_destructor(struct bio *bio) * @gfp_mask: allocation mask to use * @nr_iovecs: number of iovecs * - * bio_alloc will allocate a bio and associated bio_vec array that can hold - * at least @nr_iovecs entries. Allocations will be done from the - * fs_bio_set. Also see @bio_alloc_bioset and @bio_kmalloc. - * - * If %__GFP_WAIT is set, then bio_alloc will always be able to allocate - * a bio. This is due to the mempool guarantees. To make this work, callers - * must never allocate more than 1 bio at a time from this pool. Callers - * that need to allocate more than 1 bio must always submit the previously - * allocated bio for IO before attempting to allocate a new one. Failure to - * do so can cause livelocks under memory pressure. + * Allocate a new bio with @nr_iovecs bvecs. If @gfp_mask + * contains __GFP_WAIT, the allocation is guaranteed to succeed. * * RETURNS: * Pointer to new bio on success, NULL on failure. @@ -358,13 +350,21 @@ static void bio_kmalloc_destructor(struct bio *bio) } /** - * bio_kmalloc - allocate a bio for I/O using kmalloc() + * bio_alloc - allocate a bio for I/O * @gfp_mask: the GFP_ mask given to the slab allocator * @nr_iovecs: number of iovecs to pre-allocate * * Description: - * Allocate a new bio with @nr_iovecs bvecs. If @gfp_mask contains - * %__GFP_WAIT, the allocation is guaranteed to succeed. + * bio_alloc will allocate a bio and associated bio_vec array that can hold + * at least @nr_iovecs entries. Allocations will be done from the + * fs_bio_set. Also see @bio_alloc_bioset. + * + * If %__GFP_WAIT is set, then bio_alloc will always be able to allocate + * a bio. This is due to the mempool guarantees. To make this work, callers + * must never allocate more than 1 bio at a time from this pool. Callers + * that need to allocate more than 1 bio must always submit the previously + * allocated bio for IO before attempting to allocate a new one. Failure to + * do so can cause livelocks under memory pressure. * **/ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) @@ -407,7 +407,7 @@ EXPORT_SYMBOL(zero_fill_bio); * * Description: * Put a reference to a &struct bio, either one you have gotten with - * bio_alloc, bio_get or bio_clone. The last put of a bio will free it. + * bio_alloc or bio_get. The last put of a bio will free it. **/ void bio_put(struct bio *bio) { diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 6c19040ffeef..d576b552e8e2 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -1532,8 +1532,6 @@ int compat_do_execve(char * filename, if (retval < 0) goto out; - current->stack_start = current->mm->start_stack; - /* execve succeeded */ current->fs->in_exec = 0; current->in_execve = 0; diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 00d153f2f261..984ca0cb38c3 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -743,7 +743,6 @@ struct ext4_inode_info { #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ -#define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index d4ca92aab514..312211ee05af 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -1300,11 +1300,9 @@ static int parse_options(char *options, struct super_block *sb, *journal_devnum = option; break; case Opt_journal_checksum: - set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); - break; + break; /* Kept for backwards compatibility */ case Opt_journal_async_commit: set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT); - set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); break; case Opt_noload: set_opt(sbi->s_mount_opt, NOLOAD); @@ -2761,20 +2759,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount4; } - if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { - jbd2_journal_set_features(sbi->s_journal, - JBD2_FEATURE_COMPAT_CHECKSUM, 0, + jbd2_journal_set_features(sbi->s_journal, + JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0); + if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) + jbd2_journal_set_features(sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); - } else if (test_opt(sb, JOURNAL_CHECKSUM)) { - jbd2_journal_set_features(sbi->s_journal, - JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0); + else jbd2_journal_clear_features(sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); - } else { - jbd2_journal_clear_features(sbi->s_journal, - JBD2_FEATURE_COMPAT_CHECKSUM, 0, - JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); - } /* We have now updated the journal if required, so we can * validate the data journaling mode. */ diff --git a/trunk/fs/nilfs2/btnode.c b/trunk/fs/nilfs2/btnode.c index 84c25382f8e3..5941958f1e47 100644 --- a/trunk/fs/nilfs2/btnode.c +++ b/trunk/fs/nilfs2/btnode.c @@ -87,7 +87,6 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, brelse(bh); BUG(); } - memset(bh->b_data, 0, 1 << inode->i_blkbits); bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev; bh->b_blocknr = blocknr; set_buffer_mapped(bh); @@ -277,7 +276,8 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc, "invalid oldkey %lld (newkey=%lld)", (unsigned long long)oldkey, (unsigned long long)newkey); - nilfs_btnode_mark_dirty(obh); + if (!test_set_buffer_dirty(obh) && TestSetPageDirty(opage)) + BUG(); spin_lock_irq(&btnc->tree_lock); radix_tree_delete(&btnc->page_tree, oldkey); diff --git a/trunk/fs/nilfs2/segment.c b/trunk/fs/nilfs2/segment.c index 6eff66a070d5..683df89dbae5 100644 --- a/trunk/fs/nilfs2/segment.c +++ b/trunk/fs/nilfs2/segment.c @@ -2468,22 +2468,17 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, /* Clear requests (even when the construction failed) */ spin_lock(&sci->sc_state_lock); + sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; + if (req->mode == SC_LSEG_SR) { - sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; sci->sc_seq_done = req->seq_accepted; nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err); sci->sc_flush_request = 0; - } else { - if (req->mode == SC_FLUSH_FILE) - sci->sc_flush_request &= ~FLUSH_FILE_BIT; - else if (req->mode == SC_FLUSH_DAT) - sci->sc_flush_request &= ~FLUSH_DAT_BIT; + } else if (req->mode == SC_FLUSH_FILE) + sci->sc_flush_request &= ~FLUSH_FILE_BIT; + else if (req->mode == SC_FLUSH_DAT) + sci->sc_flush_request &= ~FLUSH_DAT_BIT; - /* re-enable timer if checkpoint creation was not done */ - if (sci->sc_timer && (sci->sc_state & NILFS_SEGCTOR_COMMIT) && - time_before(jiffies, sci->sc_timer->expires)) - add_timer(sci->sc_timer); - } spin_unlock(&sci->sc_state_lock); } diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index e0201837d244..5fad489ce5bc 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "sysfs.h" DEFINE_MUTEX(sysfs_mutex); @@ -286,9 +285,6 @@ void release_sysfs_dirent(struct sysfs_dirent * sd) sysfs_put(sd->s_symlink.target_sd); if (sysfs_type(sd) & SYSFS_COPY_NAME) kfree(sd->s_name); - if (sd->s_iattr && sd->s_iattr->ia_secdata) - security_release_secctx(sd->s_iattr->ia_secdata, - sd->s_iattr->ia_secdata_len); kfree(sd->s_iattr); sysfs_free_ino(sd->s_ino); kmem_cache_free(sysfs_dir_cachep, sd); diff --git a/trunk/fs/xfs/linux-2.6/xfs_quotaops.c b/trunk/fs/xfs/linux-2.6/xfs_quotaops.c index 3d4a0c84d634..9e41f91aa269 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_quotaops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_quotaops.c @@ -80,7 +80,7 @@ xfs_fs_set_xstate( if (sb->s_flags & MS_RDONLY) return -EROFS; - if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp)) + if (!XFS_IS_QUOTA_RUNNING(mp)) return -ENOSYS; if (!capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index 0785797db828..ab64f3efb43b 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -880,7 +880,6 @@ xfs_dialloc( * Not in range - save last search * location and allocate a new inode */ - xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); pag->pagl_leftrec = trec.ir_startino; pag->pagl_rightrec = rec.ir_startino; pag->pagl_pagino = pagino; diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 2ea3e4921812..aca31bf7d8ed 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -124,9 +124,7 @@ struct device_driver { struct bus_type *bus; struct module *owner; - const char *mod_name; /* used for built-in modules */ - - bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ + const char *mod_name; /* used for built-in modules */ int (*probe) (struct device *dev); int (*remove) (struct device *dev); diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index 9e7012689a84..2e6d95f97419 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -471,8 +471,8 @@ struct hw_perf_event { unsigned long event_base; int idx; }; - struct { /* software */ - s64 remaining; + union { /* software */ + atomic64_t count; struct hrtimer hrtimer; }; }; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index bcdd6606f468..df7b23ac66e6 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -354,8 +354,8 @@ struct sk_buff { ipvs_property:1, peeked:1, nf_trace:1; - __be16 protocol:16; kmemcheck_bitfield_end(flags1); + __be16 protocol; void (*destructor)(struct sk_buff *skb); #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) @@ -367,6 +367,7 @@ struct sk_buff { #endif int iif; + __u16 queue_mapping; #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ #ifdef CONFIG_NET_CLS_ACT @@ -375,7 +376,6 @@ struct sk_buff { #endif kmemcheck_bitfield_begin(flags2); - __u16 queue_mapping:16; #ifdef CONFIG_IPV6_NDISC_NODETYPE __u8 ndisc_nodetype:2; #endif @@ -1757,8 +1757,6 @@ extern int skb_copy_datagram_const_iovec(const struct sk_buff *from, int to_offset, int size); extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); -extern void skb_free_datagram_locked(struct sock *sk, - struct sk_buff *skb); extern int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); extern __wsum skb_checksum(const struct sk_buff *skb, int offset, diff --git a/trunk/include/linux/trace_seq.h b/trunk/include/linux/trace_seq.h index 09077f6ed128..c134dd1fe6b6 100644 --- a/trunk/include/linux/trace_seq.h +++ b/trunk/include/linux/trace_seq.h @@ -7,7 +7,7 @@ /* * Trace sequences are used to allow a function to call several other functions - * to create a string of data to use (up to a max of PAGE_SIZE). + * to create a string of data to use (up to a max of PAGE_SIZE. */ struct trace_seq { diff --git a/trunk/include/net/9p/client.h b/trunk/include/net/9p/client.h index fb00b329f0d3..e26812274b75 100644 --- a/trunk/include/net/9p/client.h +++ b/trunk/include/net/9p/client.h @@ -159,7 +159,8 @@ struct p9_client { * @qid: the &p9_qid server identifier this handle points to * @iounit: the server reported maximum transaction size for this file * @uid: the numeric uid of the local user who owns this handle - * @rdir: readdir accounting structure (allocated on demand) + * @aux: transport specific information (unused?) + * @rdir_fpos: tracks offset of file position when reading directory contents * @flist: per-client-instance fid tracking * @dlist: per-dentry fid tracking * @@ -173,9 +174,9 @@ struct p9_fid { struct p9_qid qid; u32 iounit; uid_t uid; + void *aux; - void *rdir; - + int rdir_fpos; struct list_head flist; struct list_head dlist; /* list of all fids attached to a dentry */ }; diff --git a/trunk/include/net/ip_fib.h b/trunk/include/net/ip_fib.h index 4d22fabc7719..ef91fe924ba4 100644 --- a/trunk/include/net/ip_fib.h +++ b/trunk/include/net/ip_fib.h @@ -210,8 +210,7 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id); extern const struct nla_policy rtm_ipv4_policy[]; extern void ip_fib_init(void); extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, - u32 *itag, u32 mark); + struct net_device *dev, __be32 *spec_dst, u32 *itag); extern void fib_select_default(struct net *net, const struct flowi *flp, struct fib_result *res); diff --git a/trunk/include/pcmcia/ss.h b/trunk/include/pcmcia/ss.h index e0f6feb8588c..d696a692d94a 100644 --- a/trunk/include/pcmcia/ss.h +++ b/trunk/include/pcmcia/ss.h @@ -262,8 +262,6 @@ struct pcmcia_socket { struct device dev; /* data internal to the socket driver */ void *driver_data; - /* status of the card during resume from a system sleep state */ - int resume_status; }; @@ -282,8 +280,6 @@ extern struct pccard_resource_ops pccard_nonstatic_ops; /* socket drivers are expected to use these callbacks in their .drv struct */ extern int pcmcia_socket_dev_suspend(struct device *dev); -extern void pcmcia_socket_dev_early_resume(struct device *dev); -extern void pcmcia_socket_dev_late_resume(struct device *dev); extern int pcmcia_socket_dev_resume(struct device *dev); /* socket drivers use this callback in their IRQ handler */ diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 166b8c49257c..4c20fff8c13a 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -91,7 +91,7 @@ int nr_processes(void) int cpu; int total = 0; - for_each_possible_cpu(cpu) + for_each_online_cpu(cpu) total += per_cpu(process_counts, cpu); return total; diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index fb65e822fc41..642f3bbaacc7 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -2127,7 +2127,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, plist_del(&q->list, &q->list.plist); /* Handle spurious wakeups gracefully */ - ret = -EWOULDBLOCK; + ret = -EAGAIN; if (timeout && !timeout->task) ret = -ETIMEDOUT; else if (signal_pending(current)) @@ -2208,6 +2208,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, debug_rt_mutex_init_waiter(&rt_waiter); rt_waiter.task = NULL; +retry: key2 = FUTEX_KEY_INIT; ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE); if (unlikely(ret != 0)) @@ -2302,6 +2303,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, out_key2: put_futex_key(fshared, &key2); + /* Spurious wakeup ? */ + if (ret == -EAGAIN) + goto retry; out: if (to) { hrtimer_cancel(&to->timer); diff --git a/trunk/kernel/kthread.c b/trunk/kernel/kthread.c index ab7ae57773e1..5fe709982caa 100644 --- a/trunk/kernel/kthread.c +++ b/trunk/kernel/kthread.c @@ -149,6 +149,29 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), } EXPORT_SYMBOL(kthread_create); +/** + * kthread_bind - bind a just-created kthread to a cpu. + * @k: thread created by kthread_create(). + * @cpu: cpu (might not be online, must be possible) for @k to run on. + * + * Description: This function is equivalent to set_cpus_allowed(), + * except that @cpu doesn't need to be online, and the thread must be + * stopped (i.e., just returned from kthread_create()). + */ +void kthread_bind(struct task_struct *k, unsigned int cpu) +{ + /* Must have done schedule() in kthread() before we set_task_cpu */ + if (!wait_task_inactive(k, TASK_UNINTERRUPTIBLE)) { + WARN_ON(1); + return; + } + set_task_cpu(k, cpu); + k->cpus_allowed = cpumask_of_cpu(cpu); + k->rt.nr_cpus_allowed = 1; + k->flags |= PF_THREAD_BOUND; +} +EXPORT_SYMBOL(kthread_bind); + /** * kthread_stop - stop a thread created by kthread_create(). * @k: thread created by kthread_create(). diff --git a/trunk/kernel/perf_event.c b/trunk/kernel/perf_event.c index 7f29643c8985..afb7ef3dbc44 100644 --- a/trunk/kernel/perf_event.c +++ b/trunk/kernel/perf_event.c @@ -3959,9 +3959,8 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) regs = task_pt_regs(current); if (regs) { - if (!(event->attr.exclude_idle && current->pid == 0)) - if (perf_event_overflow(event, 0, &data, regs)) - ret = HRTIMER_NORESTART; + if (perf_event_overflow(event, 0, &data, regs)) + ret = HRTIMER_NORESTART; } period = max_t(u64, 10000, event->hw.sample_period); @@ -3970,42 +3969,6 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) return ret; } -static void perf_swevent_start_hrtimer(struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hwc->hrtimer.function = perf_swevent_hrtimer; - if (hwc->sample_period) { - u64 period; - - if (hwc->remaining) { - if (hwc->remaining < 0) - period = 10000; - else - period = hwc->remaining; - hwc->remaining = 0; - } else { - period = max_t(u64, 10000, hwc->sample_period); - } - __hrtimer_start_range_ns(&hwc->hrtimer, - ns_to_ktime(period), 0, - HRTIMER_MODE_REL, 0); - } -} - -static void perf_swevent_cancel_hrtimer(struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->sample_period) { - ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer); - hwc->remaining = ktime_to_ns(remaining); - - hrtimer_cancel(&hwc->hrtimer); - } -} - /* * Software event: cpu wall time clock */ @@ -4028,14 +3991,22 @@ static int cpu_clock_perf_event_enable(struct perf_event *event) int cpu = raw_smp_processor_id(); atomic64_set(&hwc->prev_count, cpu_clock(cpu)); - perf_swevent_start_hrtimer(event); + hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hwc->hrtimer.function = perf_swevent_hrtimer; + if (hwc->sample_period) { + u64 period = max_t(u64, 10000, hwc->sample_period); + __hrtimer_start_range_ns(&hwc->hrtimer, + ns_to_ktime(period), 0, + HRTIMER_MODE_REL, 0); + } return 0; } static void cpu_clock_perf_event_disable(struct perf_event *event) { - perf_swevent_cancel_hrtimer(event); + if (event->hw.sample_period) + hrtimer_cancel(&event->hw.hrtimer); cpu_clock_perf_event_update(event); } @@ -4072,15 +4043,22 @@ static int task_clock_perf_event_enable(struct perf_event *event) now = event->ctx->time; atomic64_set(&hwc->prev_count, now); - - perf_swevent_start_hrtimer(event); + hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hwc->hrtimer.function = perf_swevent_hrtimer; + if (hwc->sample_period) { + u64 period = max_t(u64, 10000, hwc->sample_period); + __hrtimer_start_range_ns(&hwc->hrtimer, + ns_to_ktime(period), 0, + HRTIMER_MODE_REL, 0); + } return 0; } static void task_clock_perf_event_disable(struct perf_event *event) { - perf_swevent_cancel_hrtimer(event); + if (event->hw.sample_period) + hrtimer_cancel(&event->hw.hrtimer); task_clock_perf_event_update(event, event->ctx->time); } diff --git a/trunk/kernel/power/hibernate.c b/trunk/kernel/power/hibernate.c index 04a9e90d248f..04b3a83d686f 100644 --- a/trunk/kernel/power/hibernate.c +++ b/trunk/kernel/power/hibernate.c @@ -693,22 +693,21 @@ static int software_resume(void) /* The snapshot device should not be opened while we're running */ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { error = -EBUSY; - swsusp_close(FMODE_READ); goto Unlock; } pm_prepare_console(); error = pm_notifier_call_chain(PM_RESTORE_PREPARE); if (error) - goto close_finish; + goto Finish; error = usermodehelper_disable(); if (error) - goto close_finish; + goto Finish; error = create_basic_memory_bitmaps(); if (error) - goto close_finish; + goto Finish; pr_debug("PM: Preparing processes for restore.\n"); error = prepare_processes(); @@ -720,7 +719,6 @@ static int software_resume(void) pr_debug("PM: Reading hibernation image.\n"); error = swsusp_read(&flags); - swsusp_close(FMODE_READ); if (!error) hibernation_restore(flags & SF_PLATFORM_MODE); @@ -739,9 +737,6 @@ static int software_resume(void) mutex_unlock(&pm_mutex); pr_debug("PM: Resume from disk failed.\n"); return error; -close_finish: - swsusp_close(FMODE_READ); - goto Finish; } late_initcall(software_resume); diff --git a/trunk/kernel/power/swap.c b/trunk/kernel/power/swap.c index 890f6b11b1d3..b101cdc4df3f 100644 --- a/trunk/kernel/power/swap.c +++ b/trunk/kernel/power/swap.c @@ -314,6 +314,7 @@ static int save_image(struct swap_map_handle *handle, { unsigned int m; int ret; + int error = 0; int nr_pages; int err2; struct bio *bio; @@ -328,27 +329,26 @@ static int save_image(struct swap_map_handle *handle, nr_pages = 0; bio = NULL; do_gettimeofday(&start); - while (1) { + do { ret = snapshot_read_next(snapshot, PAGE_SIZE); - if (ret <= 0) - break; - ret = swap_write_page(handle, data_of(*snapshot), &bio); - if (ret) - break; - if (!(nr_pages % m)) - printk("\b\b\b\b%3d%%", nr_pages / m); - nr_pages++; - } + if (ret > 0) { + error = swap_write_page(handle, data_of(*snapshot), + &bio); + if (error) + break; + if (!(nr_pages % m)) + printk("\b\b\b\b%3d%%", nr_pages / m); + nr_pages++; + } + } while (ret > 0); err2 = wait_on_bio_chain(&bio); do_gettimeofday(&stop); - if (!ret) - ret = err2; - if (!ret) + if (!error) + error = err2; + if (!error) printk("\b\b\b\bdone\n"); - else - printk("\n"); swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); - return ret; + return error; } /** @@ -536,8 +536,7 @@ static int load_image(struct swap_map_handle *handle, snapshot_write_finalize(snapshot); if (!snapshot_image_loaded(snapshot)) error = -ENODATA; - } else - printk("\n"); + } swsusp_show_speed(&start, &stop, nr_to_read, "Read"); return error; } @@ -573,6 +572,8 @@ int swsusp_read(unsigned int *flags_p) error = load_image(&handle, &snapshot, header->pages - 1); release_swap_reader(&handle); + blkdev_put(resume_bdev, FMODE_READ); + if (!error) pr_debug("PM: Image successfully loaded\n"); else @@ -595,7 +596,7 @@ int swsusp_check(void) error = bio_read_page(swsusp_resume_block, swsusp_header, NULL); if (error) - goto put; + return error; if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) { memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); @@ -603,10 +604,8 @@ int swsusp_check(void) error = bio_write_page(swsusp_resume_block, swsusp_header, NULL); } else { - error = -EINVAL; + return -EINVAL; } - -put: if (error) blkdev_put(resume_bdev, FMODE_READ); else diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 28dd4f490bfc..a455dca884a6 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -1992,38 +1992,6 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p, p->sched_class->prio_changed(rq, p, oldprio, running); } -/** - * kthread_bind - bind a just-created kthread to a cpu. - * @k: thread created by kthread_create(). - * @cpu: cpu (might not be online, must be possible) for @k to run on. - * - * Description: This function is equivalent to set_cpus_allowed(), - * except that @cpu doesn't need to be online, and the thread must be - * stopped (i.e., just returned from kthread_create()). - * - * Function lives here instead of kthread.c because it messes with - * scheduler internals which require locking. - */ -void kthread_bind(struct task_struct *p, unsigned int cpu) -{ - struct rq *rq = cpu_rq(cpu); - unsigned long flags; - - /* Must have done schedule() in kthread() before we set_task_cpu */ - if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) { - WARN_ON(1); - return; - } - - spin_lock_irqsave(&rq->lock, flags); - set_task_cpu(p, cpu); - p->cpus_allowed = cpumask_of_cpu(cpu); - p->rt.nr_cpus_allowed = 1; - p->flags |= PF_THREAD_BOUND; - spin_unlock_irqrestore(&rq->lock, flags); -} -EXPORT_SYMBOL(kthread_bind); - #ifdef CONFIG_SMP /* * Is this task likely cache-hot: @@ -2036,7 +2004,7 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) /* * Buddy candidates are cache hot: */ - if (sched_feat(CACHE_HOT_BUDDY) && this_rq()->nr_running && + if (sched_feat(CACHE_HOT_BUDDY) && (&p->se == cfs_rq_of(&p->se)->next || &p->se == cfs_rq_of(&p->se)->last)) return 1; @@ -9564,13 +9532,13 @@ void __init sched_init(void) current->sched_class = &fair_sched_class; /* Allocate the nohz_cpu_mask if CONFIG_CPUMASK_OFFSTACK */ - zalloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT); + alloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT); #ifdef CONFIG_SMP #ifdef CONFIG_NO_HZ - zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT); + alloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT); alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT); #endif - zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); + alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); #endif /* SMP */ perf_event_init(); diff --git a/trunk/kernel/sched_fair.c b/trunk/kernel/sched_fair.c index 37087a7fac22..c32c3e643daa 100644 --- a/trunk/kernel/sched_fair.c +++ b/trunk/kernel/sched_fair.c @@ -822,26 +822,6 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) * re-elected due to buddy favours. */ clear_buddies(cfs_rq, curr); - return; - } - - /* - * Ensure that a task that missed wakeup preemption by a - * narrow margin doesn't have to wait for a full slice. - * This also mitigates buddy induced latencies under load. - */ - if (!sched_feat(WAKEUP_PREEMPT)) - return; - - if (delta_exec < sysctl_sched_min_granularity) - return; - - if (cfs_rq->nr_running > 1) { - struct sched_entity *se = __pick_next_entity(cfs_rq); - s64 delta = curr->vruntime - se->vruntime; - - if (delta > ideal_runtime) - resched_task(rq_of(cfs_rq)->curr); } } @@ -881,18 +861,21 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se); static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) { struct sched_entity *se = __pick_next_entity(cfs_rq); - struct sched_entity *left = se; + struct sched_entity *buddy; - if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, left) < 1) - se = cfs_rq->next; - - /* - * Prefer last buddy, try to return the CPU to a preempted task. - */ - if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, left) < 1) - se = cfs_rq->last; + if (cfs_rq->next) { + buddy = cfs_rq->next; + cfs_rq->next = NULL; + if (wakeup_preempt_entity(buddy, se) < 1) + return buddy; + } - clear_buddies(cfs_rq, se); + if (cfs_rq->last) { + buddy = cfs_rq->last; + cfs_rq->last = NULL; + if (wakeup_preempt_entity(buddy, se) < 1) + return buddy; + } return se; } @@ -1594,7 +1577,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ struct sched_entity *se = &curr->se, *pse = &p->se; struct cfs_rq *cfs_rq = task_cfs_rq(curr); int sync = wake_flags & WF_SYNC; - int scale = cfs_rq->nr_running >= sched_nr_latency; update_curr(cfs_rq); @@ -1609,7 +1591,18 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ if (unlikely(se == pse)) return; - if (sched_feat(NEXT_BUDDY) && scale && !(wake_flags & WF_FORK)) + /* + * Only set the backward buddy when the current task is still on the + * rq. This can happen when a wakeup gets interleaved with schedule on + * the ->pre_schedule() or idle_balance() point, either of which can + * drop the rq lock. + * + * Also, during early boot the idle thread is in the fair class, for + * obvious reasons its a bad idea to schedule back to the idle thread. + */ + if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle)) + set_last_buddy(se); + if (sched_feat(NEXT_BUDDY) && !(wake_flags & WF_FORK)) set_next_buddy(pse); /* @@ -1655,22 +1648,8 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ BUG_ON(!pse); - if (wakeup_preempt_entity(se, pse) == 1) { + if (wakeup_preempt_entity(se, pse) == 1) resched_task(curr); - /* - * Only set the backward buddy when the current task is still - * on the rq. This can happen when a wakeup gets interleaved - * with schedule on the ->pre_schedule() or idle_balance() - * point, either of which can * drop the rq lock. - * - * Also, during early boot the idle thread is in the fair class, - * for obvious reasons its a bad idea to schedule back to it. - */ - if (unlikely(!se->on_rq || curr == rq->idle)) - return; - if (sched_feat(LAST_BUDDY) && scale && entity_is_task(se)) - set_last_buddy(se); - } } static struct task_struct *pick_next_task_fair(struct rq *rq) diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index 6dc4e5ef7a01..37ba67e33265 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -740,7 +740,7 @@ ftrace_profile_write(struct file *filp, const char __user *ubuf, out: mutex_unlock(&ftrace_profile_lock); - *ppos += cnt; + filp->f_pos += cnt; return cnt; } @@ -2222,15 +2222,15 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, ret = ftrace_process_regex(parser->buffer, parser->idx, enable); if (ret) - goto out_unlock; + goto out; trace_parser_clear(parser); } ret = read; -out_unlock: - mutex_unlock(&ftrace_regex_lock); + mutex_unlock(&ftrace_regex_lock); +out: return ret; } diff --git a/trunk/kernel/trace/ring_buffer.c b/trunk/kernel/trace/ring_buffer.c index 5dd017fea6f5..d4ff01970547 100644 --- a/trunk/kernel/trace/ring_buffer.c +++ b/trunk/kernel/trace/ring_buffer.c @@ -483,7 +483,7 @@ struct ring_buffer_iter { /* Up this if you want to test the TIME_EXTENTS and normalization */ #define DEBUG_SHIFT 0 -static inline u64 rb_time_stamp(struct ring_buffer *buffer) +static inline u64 rb_time_stamp(struct ring_buffer *buffer, int cpu) { /* shift to debug/test normalization and TIME_EXTENTS */ return buffer->clock() << DEBUG_SHIFT; @@ -494,7 +494,7 @@ u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu) u64 time; preempt_disable_notrace(); - time = rb_time_stamp(buffer); + time = rb_time_stamp(buffer, cpu); preempt_enable_no_resched_notrace(); return time; @@ -599,7 +599,7 @@ static struct list_head *rb_list_head(struct list_head *list) } /* - * rb_is_head_page - test if the given page is the head page + * rb_is_head_page - test if the give page is the head page * * Because the reader may move the head_page pointer, we can * not trust what the head page is (it may be pointing to @@ -1193,7 +1193,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) atomic_inc(&cpu_buffer->record_disabled); synchronize_sched(); - spin_lock_irq(&cpu_buffer->reader_lock); rb_head_page_deactivate(cpu_buffer); for (i = 0; i < nr_pages; i++) { @@ -1208,7 +1207,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) return; rb_reset_cpu(cpu_buffer); - spin_unlock_irq(&cpu_buffer->reader_lock); rb_check_pages(cpu_buffer); @@ -1870,7 +1868,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, * Nested commits always have zero deltas, so * just reread the time stamp */ - *ts = rb_time_stamp(buffer); + *ts = rb_time_stamp(buffer, cpu_buffer->cpu); next_page->page->time_stamp = *ts; } @@ -2113,7 +2111,7 @@ rb_reserve_next_event(struct ring_buffer *buffer, if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000)) goto out_fail; - ts = rb_time_stamp(cpu_buffer->buffer); + ts = rb_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu); /* * Only the first commit can update the timestamp. @@ -2683,7 +2681,7 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer) EXPORT_SYMBOL_GPL(ring_buffer_entries); /** - * ring_buffer_overruns - get the number of overruns in buffer + * ring_buffer_overrun_cpu - get the number of overruns in buffer * @buffer: The ring buffer * * Returns the total number of overruns in the ring buffer diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index b20d3ec75de9..c820b0310a12 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -2440,7 +2440,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, return ret; } - *ppos += cnt; + filp->f_pos += cnt; return cnt; } @@ -2582,7 +2582,7 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf, } mutex_unlock(&trace_types_lock); - *ppos += cnt; + filp->f_pos += cnt; return cnt; } @@ -2764,7 +2764,7 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf, if (err) return err; - *ppos += ret; + filp->f_pos += ret; return ret; } @@ -3299,7 +3299,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, } } - *ppos += cnt; + filp->f_pos += cnt; /* If check pages failed, return ENOMEM */ if (tracing_disabled) diff --git a/trunk/kernel/trace/trace_output.c b/trunk/kernel/trace/trace_output.c index b6c12c6a1bcd..ed17565826b0 100644 --- a/trunk/kernel/trace/trace_output.c +++ b/trunk/kernel/trace/trace_output.c @@ -69,9 +69,6 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter) * @s: trace sequence descriptor * @fmt: printf format string * - * It returns 0 if the trace oversizes the buffer's free - * space, 1 otherwise. - * * The tracer may use either sequence operations or its own * copy to user routines. To simplify formating of a trace * trace_seq_printf is used to store strings into a special @@ -98,7 +95,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) s->len += ret; - return 1; + return len; } EXPORT_SYMBOL_GPL(trace_seq_printf); diff --git a/trunk/lib/dma-debug.c b/trunk/lib/dma-debug.c index ce6b7eabf674..58a9f9fc609a 100644 --- a/trunk/lib/dma-debug.c +++ b/trunk/lib/dma-debug.c @@ -819,11 +819,9 @@ static void check_unmap(struct dma_debug_entry *ref) err_printk(ref->dev, entry, "DMA-API: device driver frees " "DMA memory with different CPU address " "[device address=0x%016llx] [size=%llu bytes] " - "[cpu alloc address=0x%016llx] " - "[cpu free address=0x%016llx]", + "[cpu alloc address=%p] [cpu free address=%p]", ref->dev_addr, ref->size, - (unsigned long long)entry->paddr, - (unsigned long long)ref->paddr); + (void *)entry->paddr, (void *)ref->paddr); } if (ref->sg_call_ents && ref->type == dma_debug_sg && diff --git a/trunk/mm/backing-dev.c b/trunk/mm/backing-dev.c index 11aee09dd2a6..1065b715ef64 100644 --- a/trunk/mm/backing-dev.c +++ b/trunk/mm/backing-dev.c @@ -628,8 +628,6 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) void bdi_unregister(struct backing_dev_info *bdi) { if (bdi->dev) { - bdi_prune_sb(bdi); - if (!bdi_cap_flush_forker(bdi)) bdi_wb_shutdown(bdi); bdi_debug_unregister(bdi); @@ -699,6 +697,7 @@ void bdi_destroy(struct backing_dev_info *bdi) spin_unlock(&inode_lock); } + bdi_prune_sb(bdi); bdi_unregister(bdi); for (i = 0; i < NR_BDI_STAT_ITEMS; i++) diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index 9876fa0c3ad3..5189b5aed8c0 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -1362,11 +1362,9 @@ unsigned long do_mmap_pgoff(struct file *file, error_just_free: up_write(&nommu_region_sem); error: - if (region->vm_file) - fput(region->vm_file); + fput(region->vm_file); kmem_cache_free(vm_region_jar, region); - if (vma->vm_file) - fput(vma->vm_file); + fput(vma->vm_file); if (vma->vm_flags & VM_EXECUTABLE) removed_exe_file_vma(vma->vm_mm); kmem_cache_free(vm_area_cachep, vma); diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 9c590eef7912..a1bc6b9af9a2 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -1151,7 +1151,8 @@ static int try_to_unuse(unsigned int type) } else retval = unuse_mm(mm, entry, page); - if (set_start_mm && *swap_map < swcount) { + if (set_start_mm && + swap_count(*swap_map) < swcount) { mmput(new_start_mm); atomic_inc(&mm->mm_users); new_start_mm = mm; diff --git a/trunk/net/9p/client.c b/trunk/net/9p/client.c index 8af95b2dddd6..5bf5f227dbe0 100644 --- a/trunk/net/9p/client.c +++ b/trunk/net/9p/client.c @@ -582,9 +582,11 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt) memset(&fid->qid, 0, sizeof(struct p9_qid)); fid->mode = -1; + fid->rdir_fpos = 0; fid->uid = current_fsuid(); fid->clnt = clnt; - fid->rdir = NULL; + fid->aux = NULL; + spin_lock_irqsave(&clnt->lock, flags); list_add(&fid->flist, &clnt->fidlist); spin_unlock_irqrestore(&clnt->lock, flags); @@ -607,7 +609,6 @@ static void p9_fid_destroy(struct p9_fid *fid) spin_lock_irqsave(&clnt->lock, flags); list_del(&fid->flist); spin_unlock_irqrestore(&clnt->lock, flags); - kfree(fid->rdir); kfree(fid); } diff --git a/trunk/net/core/datagram.c b/trunk/net/core/datagram.c index 4ade3011bb3c..1c6cf3a1a4f6 100644 --- a/trunk/net/core/datagram.c +++ b/trunk/net/core/datagram.c @@ -224,15 +224,6 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) consume_skb(skb); sk_mem_reclaim_partial(sk); } -EXPORT_SYMBOL(skb_free_datagram); - -void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) -{ - lock_sock(sk); - skb_free_datagram(sk, skb); - release_sock(sk); -} -EXPORT_SYMBOL(skb_free_datagram_locked); /** * skb_kill_datagram - Free a datagram skbuff forcibly @@ -761,4 +752,5 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, EXPORT_SYMBOL(datagram_poll); EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); EXPORT_SYMBOL(skb_copy_datagram_iovec); +EXPORT_SYMBOL(skb_free_datagram); EXPORT_SYMBOL(skb_recv_datagram); diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index aa00398be80e..e2f950592566 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -229,17 +229,14 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, */ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, - u32 *itag, u32 mark) + struct net_device *dev, __be32 *spec_dst, u32 *itag) { struct in_device *in_dev; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = src, .saddr = dst, .tos = tos } }, - .mark = mark, .iif = oif }; - struct fib_result res; int no_addr, rpf; int ret; diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 143333852624..41ada9904d31 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -1464,7 +1464,7 @@ static void ipgre_tap_setup(struct net_device *dev) ether_setup(dev); - dev->netdev_ops = &ipgre_tap_netdev_ops; + dev->netdev_ops = &ipgre_netdev_ops; dev->destructor = free_netdev; dev->iflink = 0; @@ -1525,29 +1525,25 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], if (t->dev != dev) return -EEXIST; } else { - t = nt; + unsigned nflags = 0; - if (dev->type != ARPHRD_ETHER) { - unsigned nflags = 0; + t = nt; - if (ipv4_is_multicast(p.iph.daddr)) - nflags = IFF_BROADCAST; - else if (p.iph.daddr) - nflags = IFF_POINTOPOINT; + if (ipv4_is_multicast(p.iph.daddr)) + nflags = IFF_BROADCAST; + else if (p.iph.daddr) + nflags = IFF_POINTOPOINT; - if ((dev->flags ^ nflags) & - (IFF_POINTOPOINT | IFF_BROADCAST)) - return -EINVAL; - } + if ((dev->flags ^ nflags) & + (IFF_POINTOPOINT | IFF_BROADCAST)) + return -EINVAL; ipgre_tunnel_unlink(ign, t); t->parms.iph.saddr = p.iph.saddr; t->parms.iph.daddr = p.iph.daddr; t->parms.i_key = p.i_key; - if (dev->type != ARPHRD_ETHER) { - memcpy(dev->dev_addr, &p.iph.saddr, 4); - memcpy(dev->broadcast, &p.iph.daddr, 4); - } + memcpy(dev->dev_addr, &p.iph.saddr, 4); + memcpy(dev->broadcast, &p.iph.daddr, 4); ipgre_tunnel_link(ign, t); netdev_state_change(dev); } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 5b1050a5d874..bb4199252026 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1854,7 +1854,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto e_inval; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); } else if (fib_validate_source(saddr, 0, tos, 0, - dev, &spec_dst, &itag, 0) < 0) + dev, &spec_dst, &itag) < 0) goto e_inval; rth = dst_alloc(&ipv4_dst_ops); @@ -1967,7 +1967,7 @@ static int __mkroute_input(struct sk_buff *skb, err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), - in_dev->dev, &spec_dst, &itag, skb->mark); + in_dev->dev, &spec_dst, &itag); if (err < 0) { ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, saddr); @@ -2141,7 +2141,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, int result; result = fib_validate_source(saddr, daddr, tos, net->loopback_dev->ifindex, - dev, &spec_dst, &itag, skb->mark); + dev, &spec_dst, &itag); if (result < 0) goto martian_source; if (result) @@ -2170,7 +2170,7 @@ out: return err; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); else { err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, - &itag, skb->mark); + &itag); if (err < 0) goto martian_source; if (err) diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 0fa9f70e4b19..d0d436d6216c 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -999,7 +999,9 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, err = ulen; out_free: - skb_free_datagram_locked(sk, skb); + lock_sock(sk); + skb_free_datagram(sk, skb); + release_sock(sk); out: return err; diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index cf538ed5ef6a..3a60f12b34ed 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -288,7 +288,9 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, err = ulen; out_free: - skb_free_datagram_locked(sk, skb); + lock_sock(sk); + skb_free_datagram(sk, skb); + release_sock(sk); out: return err; diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c index b09948ceec4a..bd765f30dba2 100644 --- a/trunk/net/mac80211/agg-tx.c +++ b/trunk/net/mac80211/agg-tx.c @@ -666,25 +666,26 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, state = &sta->ampdu_mlme.tid_state_tx[tid]; - del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); - spin_lock_bh(&sta->lock); - if (!(*state & HT_ADDBA_REQUESTED_MSK)) - goto timer_still_needed; + if (!(*state & HT_ADDBA_REQUESTED_MSK)) { + spin_unlock_bh(&sta->lock); + return; + } if (mgmt->u.action.u.addba_resp.dialog_token != sta->ampdu_mlme.tid_tx[tid]->dialog_token) { + spin_unlock_bh(&sta->lock); #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ - goto timer_still_needed; + return; } + del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ - if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) == WLAN_STATUS_SUCCESS) { u8 curstate = *state; @@ -698,11 +699,5 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, } else { ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); } - - goto out; - - timer_still_needed: - add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); - out: spin_unlock_bh(&sta->lock); } diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 7b5131bd6fa1..5608f6c68413 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -72,9 +72,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, struct ieee80211_sub_if_data *sdata; int ret; - if (netif_running(dev)) - return -EBUSY; - if (!nl80211_type_check(type)) return -EINVAL; @@ -84,6 +81,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, if (ret) return ret; + if (netif_running(sdata->dev)) + return -EBUSY; + if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) ieee80211_sdata_set_mesh_id(sdata, params->mesh_id_len, diff --git a/trunk/net/mac80211/ht.c b/trunk/net/mac80211/ht.c index 48ef1a282b91..0891bfb06996 100644 --- a/trunk/net/mac80211/ht.c +++ b/trunk/net/mac80211/ht.c @@ -153,7 +153,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, if (net_ratelimit()) printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", mgmt->sa, initiator ? "initiator" : "recipient", tid, - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); + mgmt->u.action.u.delba.reason_code); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR) diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index f1362f32c17d..ca8ecce31d34 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -73,7 +73,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt; u8 *pos; struct ieee80211_supported_band *sband; - struct cfg80211_bss *bss; u32 bss_change; u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; @@ -178,9 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, mod_timer(&ifibss->timer, round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); - bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, - mgmt, skb->len, 0, GFP_KERNEL); - cfg80211_put_bss(bss); + cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, + mgmt, skb->len, 0, GFP_KERNEL); cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); } diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index 1c246a4f491e..ccc5e83cae5d 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -111,7 +111,7 @@ static void svc_release_skb(struct svc_rqst *rqstp) rqstp->rq_xprt_ctxt = NULL; dprintk("svc: service %p, releasing skb %p\n", rqstp, skb); - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); } } @@ -578,7 +578,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) "svc: received unknown control message %d/%d; " "dropping RPC reply datagram\n", cmh->cmsg_level, cmh->cmsg_type); - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); return 0; } @@ -588,18 +588,18 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { local_bh_enable(); /* checksum error */ - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); return 0; } local_bh_enable(); - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); } else { /* we can use it in-place */ rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); rqstp->rq_arg.head[0].iov_len = len; if (skb_checksum_complete(skb)) { - skb_free_datagram_locked(svsk->sk_sk, skb); + skb_free_datagram(svsk->sk_sk, skb); return 0; } rqstp->rq_xprt_ctxt = skb; diff --git a/trunk/net/wireless/sme.c b/trunk/net/wireless/sme.c index 9f0b2800a9d7..ece378d531ef 100644 --- a/trunk/net/wireless/sme.c +++ b/trunk/net/wireless/sme.c @@ -165,7 +165,7 @@ void cfg80211_conn_work(struct work_struct *work) struct cfg80211_registered_device *rdev = container_of(work, struct cfg80211_registered_device, conn_work); struct wireless_dev *wdev; - u8 bssid_buf[ETH_ALEN], *bssid = NULL; + u8 bssid[ETH_ALEN]; rtnl_lock(); cfg80211_lock_rdev(rdev); @@ -181,10 +181,7 @@ void cfg80211_conn_work(struct work_struct *work) wdev_unlock(wdev); continue; } - if (wdev->conn->params.bssid) { - memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); - bssid = bssid_buf; - } + memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN); if (cfg80211_conn_do_work(wdev)) __cfg80211_connect_result( wdev->netdev, bssid, diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index c69c60b2a48a..0c1440121c22 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -953,12 +953,11 @@ static int snd_pcm_dev_register(struct snd_device *device) struct snd_pcm_substream *substream; struct snd_pcm_notify *notify; char str[16]; - struct snd_pcm *pcm; + struct snd_pcm *pcm = device->device_data; struct device *dev; - if (snd_BUG_ON(!device || !device->device_data)) + if (snd_BUG_ON(!pcm || !device)) return -ENXIO; - pcm = device->device_data; mutex_lock(®ister_mutex); err = snd_pcm_add(pcm); if (err) { diff --git a/trunk/sound/drivers/dummy.c b/trunk/sound/drivers/dummy.c index 252e04ce602f..6ba066c41d2e 100644 --- a/trunk/sound/drivers/dummy.c +++ b/trunk/sound/drivers/dummy.c @@ -165,7 +165,7 @@ MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); module_param_array(pcm_devs, int, NULL, 0444); MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); module_param_array(pcm_substreams, int, NULL, 0444); -MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver."); +MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver."); //module_param_array(midi_devs, int, NULL, 0444); //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver."); module_param(fake_buffer, bool, 0444); @@ -808,6 +808,8 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy) unsigned int idx; int err; + if (snd_BUG_ON(!dummy)) + return -EINVAL; spin_lock_init(&dummy->mixer_lock); strcpy(card->mixername, "Dummy Mixer"); diff --git a/trunk/sound/drivers/pcsp/pcsp_lib.c b/trunk/sound/drivers/pcsp/pcsp_lib.c index e1145ac6e908..84cc2658c05b 100644 --- a/trunk/sound/drivers/pcsp/pcsp_lib.c +++ b/trunk/sound/drivers/pcsp/pcsp_lib.c @@ -39,20 +39,25 @@ static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0); /* write the port and returns the next expire time in ns; * called at the trigger-start and in hrtimer callback */ -static u64 pcsp_timer_update(struct snd_pcsp *chip) +static unsigned long pcsp_timer_update(struct hrtimer *handle) { unsigned char timer_cnt, val; u64 ns; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; + struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); unsigned long flags; if (chip->thalf) { outb(chip->val61, 0x61); chip->thalf = 0; + if (!atomic_read(&chip->timer_active)) + return 0; return chip->ns_rem; } + if (!atomic_read(&chip->timer_active)) + return 0; substream = chip->playback_substream; if (!substream) return 0; @@ -83,17 +88,24 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip) return ns; } -static void pcsp_pointer_update(struct snd_pcsp *chip) +enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) { + struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); struct snd_pcm_substream *substream; + int periods_elapsed, pointer_update; size_t period_bytes, buffer_bytes; - int periods_elapsed; + unsigned long ns; unsigned long flags; + pointer_update = !chip->thalf; + ns = pcsp_timer_update(handle); + if (!ns) + return HRTIMER_NORESTART; + /* update the playback position */ substream = chip->playback_substream; if (!substream) - return; + return HRTIMER_NORESTART; period_bytes = snd_pcm_lib_period_bytes(substream); buffer_bytes = snd_pcm_lib_buffer_bytes(substream); @@ -122,26 +134,6 @@ static void pcsp_pointer_update(struct snd_pcsp *chip) if (periods_elapsed) tasklet_schedule(&pcsp_pcm_tasklet); -} - -enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) -{ - struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); - int pointer_update; - u64 ns; - - if (!atomic_read(&chip->timer_active) || !chip->playback_substream) - return HRTIMER_NORESTART; - - pointer_update = !chip->thalf; - ns = pcsp_timer_update(chip); - if (!ns) { - printk(KERN_WARNING "PCSP: unexpected stop\n"); - return HRTIMER_NORESTART; - } - - if (pointer_update) - pcsp_pointer_update(chip); hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); @@ -150,6 +142,8 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) static int pcsp_start_playing(struct snd_pcsp *chip) { + unsigned long ns; + #if PCSP_DEBUG printk(KERN_INFO "PCSP: start_playing called\n"); #endif @@ -165,7 +159,11 @@ static int pcsp_start_playing(struct snd_pcsp *chip) atomic_set(&chip->timer_active, 1); chip->thalf = 0; - hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); + ns = pcsp_timer_update(&pcsp_chip.timer); + if (!ns) + return -EIO; + + hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL); return 0; } @@ -234,22 +232,21 @@ static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream) static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream) { struct snd_pcsp *chip = snd_pcm_substream_chip(substream); - pcsp_sync_stop(chip); - chip->playback_ptr = 0; - chip->period_ptr = 0; - chip->fmt_size = - snd_pcm_format_physical_width(substream->runtime->format) >> 3; - chip->is_signed = snd_pcm_format_signed(substream->runtime->format); #if PCSP_DEBUG printk(KERN_INFO "PCSP: prepare called, " - "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n", + "size=%zi psize=%zi f=%zi f1=%i\n", snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream) / snd_pcm_lib_period_bytes(substream), - substream->runtime->periods, - chip->fmt_size); + substream->runtime->periods); #endif + pcsp_sync_stop(chip); + chip->playback_ptr = 0; + chip->period_ptr = 0; + chip->fmt_size = + snd_pcm_format_physical_width(substream->runtime->format) >> 3; + chip->is_signed = snd_pcm_format_signed(substream->runtime->format); return 0; } diff --git a/trunk/sound/drivers/pcsp/pcsp_mixer.c b/trunk/sound/drivers/pcsp/pcsp_mixer.c index 903bc846763f..199b03377142 100644 --- a/trunk/sound/drivers/pcsp/pcsp_mixer.c +++ b/trunk/sound/drivers/pcsp/pcsp_mixer.c @@ -72,7 +72,7 @@ static int pcsp_treble_put(struct snd_kcontrol *kcontrol, if (treble != chip->treble) { chip->treble = treble; #if PCSP_DEBUG - printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE()); + printk(KERN_INFO "PCSP: rate set to %i\n", PCSP_RATE()); #endif changed = 1; } diff --git a/trunk/sound/parisc/harmony.c b/trunk/sound/parisc/harmony.c index f47f9e226b08..e924492df21d 100644 --- a/trunk/sound/parisc/harmony.c +++ b/trunk/sound/parisc/harmony.c @@ -624,9 +624,6 @@ snd_harmony_pcm_init(struct snd_harmony *h) struct snd_pcm *pcm; int err; - if (snd_BUG_ON(!h)) - return -EINVAL; - harmony_disable_interrupts(h); err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm); @@ -868,12 +865,11 @@ snd_harmony_mixer_reset(struct snd_harmony *h) static int __devinit snd_harmony_mixer_init(struct snd_harmony *h) { - struct snd_card *card; + struct snd_card *card = h->card; int idx, err; if (snd_BUG_ON(!h)) return -EINVAL; - card = h->card; strcpy(card->mixername, "Harmony Gain control interface"); for (idx = 0; idx < HARMONY_CONTROLS; idx++) { diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 75c602b5b132..fb5ee3cc3968 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -259,6 +259,7 @@ config SND_CS5530 config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" + depends on X86 && !X86_64 select SND_PCM select SND_AC97_CODEC help diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index aaf4da68969c..b458d208720b 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -973,7 +973,7 @@ static void snd_ali_free_voice(struct snd_ali * codec, void *private_data; snd_ali_printk("free_voice: channel=%d\n",pvoice->number); - if (!pvoice->use) + if (pvoice == NULL || !pvoice->use) return; snd_ali_clear_voices(codec, pvoice->number, pvoice->number); spin_lock_irq(&codec->voice_alloc); diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index e340792f6cb3..c9ad182e1b4b 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -2674,7 +2674,6 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA }, diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index ff20048504b6..c08ca660daba 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -965,8 +965,6 @@ static void alc_automute_pin(struct hda_codec *codec) unsigned int nid = spec->autocfg.hp_pins[0]; int i; - if (!nid) - return; pincap = snd_hda_query_pin_caps(codec, nid); if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -12604,8 +12602,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), - SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, - "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), + SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), /* almost compatible with toshiba but with optional digital outs; * auto-probing seems working fine */ @@ -17377,7 +17374,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, /* create playback/capture controls for input pins */ #define alc662_auto_create_input_ctls \ - alc882_auto_create_input_ctls + alc880_auto_create_input_ctls static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type, diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index 8a332d2f615c..91683a349035 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -386,7 +386,6 @@ struct via82xx { struct snd_pcm *pcms[2]; struct snd_rawmidi *rmidi; - struct snd_kcontrol *dxs_controls[4]; struct snd_ac97_bus *ac97_bus; struct snd_ac97 *ac97; @@ -1217,9 +1216,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev, /* - * open callback for playback on via686 + * open callback for playback on via686 and via823x DSX */ -static int snd_via686_playback_open(struct snd_pcm_substream *substream) +static int snd_via82xx_playback_open(struct snd_pcm_substream *substream) { struct via82xx *chip = snd_pcm_substream_chip(substream); struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number]; @@ -1230,32 +1229,6 @@ static int snd_via686_playback_open(struct snd_pcm_substream *substream) return 0; } -/* - * open callback for playback on via823x DXS - */ -static int snd_via8233_playback_open(struct snd_pcm_substream *substream) -{ - struct via82xx *chip = snd_pcm_substream_chip(substream); - struct viadev *viadev; - unsigned int stream; - int err; - - viadev = &chip->devs[chip->playback_devno + substream->number]; - if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0) - return err; - stream = viadev->reg_offset / 0x10; - if (chip->dxs_controls[stream]) { - chip->playback_volume[stream][0] = 0; - chip->playback_volume[stream][1] = 0; - chip->dxs_controls[stream]->vd[0].access &= - ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | - SNDRV_CTL_EVENT_MASK_INFO, - &chip->dxs_controls[stream]->id); - } - return 0; -} - /* * open callback for playback on via823x multi-channel */ @@ -1329,26 +1302,10 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream) return 0; } -static int snd_via8233_playback_close(struct snd_pcm_substream *substream) -{ - struct via82xx *chip = snd_pcm_substream_chip(substream); - struct viadev *viadev = substream->runtime->private_data; - unsigned int stream; - - stream = viadev->reg_offset / 0x10; - if (chip->dxs_controls[stream]) { - chip->dxs_controls[stream]->vd[0].access |= - SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, - &chip->dxs_controls[stream]->id); - } - return snd_via82xx_pcm_close(substream); -} - /* via686 playback callbacks */ static struct snd_pcm_ops snd_via686_playback_ops = { - .open = snd_via686_playback_open, + .open = snd_via82xx_playback_open, .close = snd_via82xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_via82xx_hw_params, @@ -1374,8 +1331,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = { /* via823x DSX playback callbacks */ static struct snd_pcm_ops snd_via8233_playback_ops = { - .open = snd_via8233_playback_open, - .close = snd_via8233_playback_close, + .open = snd_via82xx_playback_open, + .close = snd_via82xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_via82xx_hw_params, .hw_free = snd_via82xx_hw_free, @@ -1752,9 +1709,8 @@ static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = { .device = 0, /* .subdevice set later */ .name = "PCM Playback Volume", - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ | - SNDRV_CTL_ELEM_ACCESS_INACTIVE, + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .info = snd_via8233_dxs_volume_info, .get = snd_via8233_dxs_volume_get, .put = snd_via8233_dxs_volume_put, @@ -1992,7 +1948,6 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip) err = snd_ctl_add(chip->card, kctl); if (err < 0) return err; - chip->dxs_controls[i] = kctl; } } } diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c index 64b859925c0b..7dea74b71cf1 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -217,25 +217,20 @@ static void snd_pdacf_detach(struct pcmcia_device *link) * configuration callback */ +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) + static int pdacf_config(struct pcmcia_device *link) { struct snd_pdacf *pdacf = link->priv; - int ret; + int last_fn, last_ret; snd_printdd(KERN_DEBUG "pdacf_config called\n"); link->conf.ConfigIndex = 0x5; - ret = pcmcia_request_io(link, &link->io); - if (ret) - goto failed; - - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) goto failed; @@ -243,6 +238,8 @@ static int pdacf_config(struct pcmcia_device *link) link->dev_node = &pdacf->node; return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); return -ENODEV; diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index 1492744ad67f..7445cc8a47d3 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -213,11 +213,14 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq * configuration callback */ +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) + static int vxpocket_config(struct pcmcia_device *link) { struct vx_core *chip = link->priv; struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; - int ret; + int last_fn, last_ret; snd_printdd(KERN_DEBUG "vxpocket_config called\n"); @@ -232,17 +235,9 @@ static int vxpocket_config(struct pcmcia_device *link) strcpy(chip->card->driver, vxp440_hw.name); } - ret = pcmcia_request_io(link, &link->io); - if (ret) - goto failed; - - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); chip->dev = &handle_to_dev(link); snd_card_set_dev(chip->card, chip->dev); @@ -253,6 +248,8 @@ static int vxpocket_config(struct pcmcia_device *link) link->dev_node = &vxp->node; return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); return -ENODEV; diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index 653a362425df..2dee9839be86 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -21,18 +21,7 @@ config SND_OMAP_SOC_AMS_DELTA select SND_OMAP_SOC_MCBSP select SND_SOC_CX20442 help - Say Y if you want to add support for SoC audio device connected to - a handset and a speakerphone found on Amstrad E3 (Delta) videophone. - - Note that in order to get those devices fully supported, you have to - build the kernel with standard serial port driver included and - configured for at least 4 ports. Then, from userspace, you must load - a line discipline #19 on the modem (ttyS3) serial line. The simplest - way to achieve this is to install util-linux-ng and use the included - ldattach utility. This can be started automatically from udev, - a simple rule like this one should do the trick (it does for me): - ACTION=="add", KERNEL=="controlC0", \ - RUN+="/usr/sbin/ldattach 19 /dev/ttyS3" + Say Y if you want to add support for SoC audio on Amstrad Delta. config SND_OMAP_SOC_OSK5912 tristate "SoC Audio support for omap osk5912" diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c index 1f35c6fcf5fd..5cbbdc80fde3 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -75,19 +75,11 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) { struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; - unsigned int limit; int ret; pr_debug("Entered %s\n", __func__); - if (s3c_dma_has_circular()) { - limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; - } else - limit = prtd->dma_limit; - - pr_debug("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit); - - while (prtd->dma_loaded < limit) { + while (prtd->dma_loaded < prtd->dma_limit) { unsigned long len = prtd->dma_period; pr_debug("dma_loaded: %d\n", prtd->dma_loaded); @@ -131,7 +123,7 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, snd_pcm_period_elapsed(substream); spin_lock(&prtd->lock); - if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { + if (prtd->state & ST_RUNNING) { prtd->dma_loaded--; s3c24xx_pcm_enqueue(substream); } @@ -172,11 +164,6 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, printk(KERN_ERR "failed to get dma channel\n"); return ret; } - - /* use the circular buffering if we have it available. */ - if (s3c_dma_has_circular()) - s3c2410_dma_setflags(prtd->params->channel, - S3C2410_DMAF_CIRCULAR); } s3c2410_dma_set_buffdone_fn(prtd->params->channel, diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 0a1b2f64bbee..7ff04ad2a97e 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -834,9 +834,6 @@ EXPORT_SYMBOL_GPL(snd_soc_resume_device); #define soc_resume NULL #endif -static struct snd_soc_dai_ops null_dai_ops = { -}; - static void snd_soc_instantiate_card(struct snd_soc_card *card) { struct platform_device *pdev = container_of(card->dev, @@ -880,11 +877,6 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) ac97 = 1; } - for (i = 0; i < card->num_links; i++) { - if (!card->dai_link[i].codec_dai->ops) - card->dai_link[i].codec_dai->ops = &null_dai_ops; - } - /* If we have AC97 in the system then don't wait for the * codec. This will need revisiting if we have to handle * systems with mixed AC97 and non-AC97 parts. Only check for @@ -2337,6 +2329,9 @@ static int snd_soc_unregister_card(struct snd_soc_card *card) return 0; } +static struct snd_soc_dai_ops null_dai_ops = { +}; + /** * snd_soc_register_dai - Register a DAI with the ASoC core * diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index d89f6dc00908..8de6f9dec4a2 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -2072,9 +2072,9 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, } } } + mutex_unlock(&codec->mutex); dapm_power_widgets(codec, event); - mutex_unlock(&codec->mutex); dump_dapm(codec, __func__); return 0; } diff --git a/trunk/sound/usb/caiaq/audio.c b/trunk/sound/usb/caiaq/audio.c index 86b2c3b92df5..121af0644fd9 100644 --- a/trunk/sound/usb/caiaq/audio.c +++ b/trunk/sound/usb/caiaq/audio.c @@ -62,14 +62,10 @@ static void activate_substream(struct snd_usb_caiaqdev *dev, struct snd_pcm_substream *sub) { - spin_lock(&dev->spinlock); - if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) dev->sub_playback[sub->number] = sub; else dev->sub_capture[sub->number] = sub; - - spin_unlock(&dev->spinlock); } static void @@ -273,22 +269,16 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) { int index = sub->number; struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); - snd_pcm_uframes_t ptr; - - spin_lock(&dev->spinlock); if (dev->input_panic || dev->output_panic) - ptr = SNDRV_PCM_POS_XRUN; + return SNDRV_PCM_POS_XRUN; if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) - ptr = bytes_to_frames(sub->runtime, + return bytes_to_frames(sub->runtime, dev->audio_out_buf_pos[index]); else - ptr = bytes_to_frames(sub->runtime, + return bytes_to_frames(sub->runtime, dev->audio_in_buf_pos[index]); - - spin_unlock(&dev->spinlock); - return ptr; } /* operators for both playback and capture */ diff --git a/trunk/sound/usb/caiaq/device.c b/trunk/sound/usb/caiaq/device.c index a3f02dd97440..83e6c1312d47 100644 --- a/trunk/sound/usb/caiaq/device.c +++ b/trunk/sound/usb/caiaq/device.c @@ -35,7 +35,7 @@ #include "input.h" MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20"); +MODULE_DESCRIPTION("caiaq USB audio, version 1.3.19"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," "{Native Instruments, RigKontrol3}," diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 7e190d522cd5..742a32eee8fc 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -177,7 +177,8 @@ endif # Include saner warnings here, which can catch bugs: # -EXTRA_WARNINGS := -Wformat +EXTRA_WARNINGS := -Wcast-align +EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow @@ -421,11 +422,7 @@ ifeq ($(uname_S),Darwin) PTHREAD_LIBS = endif -ifeq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y) - ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y) - BASIC_CFLAGS += -DLIBELF_NO_MMAP - endif -else +ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y) msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]); endif diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index 226f44a2357d..47ea0609a760 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -413,7 +413,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v) if (fd < 0) goto out; - elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); if (elf == NULL) goto out_close; @@ -533,7 +533,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, Elf *elf; int nr = 0, kernel = !strcmp("[kernel]", self->name); - elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); if (elf == NULL) { if (v) fprintf(stderr, "%s: cannot read %s ELF file.\n", @@ -675,7 +675,7 @@ static char *dso__read_build_id(struct dso *self, int v) if (fd < 0) goto out; - elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); if (elf == NULL) { if (v) fprintf(stderr, "%s: cannot read %s ELF file.\n", diff --git a/trunk/tools/perf/util/symbol.h b/trunk/tools/perf/util/symbol.h index 829da9edba64..6e8490716408 100644 --- a/trunk/tools/perf/util/symbol.h +++ b/trunk/tools/perf/util/symbol.h @@ -27,16 +27,6 @@ static inline char *bfd_demangle(void __used *v, const char __used *c, #endif #endif -/* - * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; - * for newer versions we can use mmap to reduce memory usage: - */ -#ifdef LIBELF_NO_MMAP -# define PERF_ELF_C_READ_MMAP ELF_C_READ -#else -# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP -#endif - #ifndef DMGL_PARAMS #define DMGL_PARAMS (1 << 0) /* Include function args */ #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */