Merge branch 'linus' into core/rcu
This commit is contained in:
		
						commit
						cdbb92b31d
					
				| @ -77,7 +77,8 @@ documentation files are also added which explain how to use the feature. | ||||
| When a kernel change causes the interface that the kernel exposes to | ||||
| userspace to change, it is recommended that you send the information or | ||||
| a patch to the manual pages explaining the change to the manual pages | ||||
| maintainer at mtk.manpages@gmail.com. | ||||
| maintainer at mtk.manpages@gmail.com, and CC the list | ||||
| linux-api@vger.kernel.org. | ||||
| 
 | ||||
| Here is a list of files that are in the kernel source tree that are | ||||
| required reading: | ||||
|  | ||||
| @ -67,6 +67,8 @@ kernel patches. | ||||
| 
 | ||||
| 19: All new userspace interfaces are documented in Documentation/ABI/. | ||||
|     See Documentation/ABI/README for more information. | ||||
|     Patches that change userspace interfaces should be CCed to | ||||
|     linux-api@vger.kernel.org. | ||||
| 
 | ||||
| 20: Check that it all passes `make headers_check'. | ||||
| 
 | ||||
|  | ||||
| @ -46,7 +46,7 @@ | ||||
|  45 -> Pinnacle PCTV DVB-T                      (em2870) | ||||
|  46 -> Compro, VideoMate U3                     (em2870)        [185b:2870] | ||||
|  47 -> KWorld DVB-T 305U                        (em2880)        [eb1a:e305] | ||||
|  48 -> KWorld DVB-T 310U                        (em2880) | ||||
|  48 -> KWorld DVB-T 310U                        (em2880)        [eb1a:e310] | ||||
|  49 -> MSI DigiVox A/D                          (em2880)        [eb1a:e310] | ||||
|  50 -> MSI DigiVox A/D II                       (em2880)        [eb1a:e320] | ||||
|  51 -> Terratec Hybrid XS Secam                 (em2880)        [0ccd:004c] | ||||
|  | ||||
| @ -190,6 +190,7 @@ pac7311		093a:260f	SnakeCam | ||||
| pac7311		093a:2621	PAC731x | ||||
| pac7311		093a:2624	PAC7302 | ||||
| pac7311		093a:2626	Labtec 2200 | ||||
| pac7311		093a:262a	Webcam 300k | ||||
| zc3xx		0ac8:0302	Z-star Vimicro zc0302 | ||||
| vc032x		0ac8:0321	Vimicro generic vc0321 | ||||
| vc032x		0ac8:0323	Vimicro Vc0323 | ||||
|  | ||||
| @ -1198,9 +1198,7 @@ M:	hpa@zytor.com | ||||
| S:	Maintained | ||||
| 
 | ||||
| CPUSETS | ||||
| P:	Paul Jackson | ||||
| P:	Paul Menage | ||||
| M:	pj@sgi.com | ||||
| M:	menage@google.com | ||||
| L:	linux-kernel@vger.kernel.org | ||||
| W:	http://www.bullopensource.org/cpuset/ | ||||
| @ -2706,6 +2704,7 @@ MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7 | ||||
| P:	Michael Kerrisk | ||||
| M:	mtk.manpages@gmail.com | ||||
| W:	http://www.kernel.org/doc/man-pages | ||||
| L:	linux-man@vger.kernel.org | ||||
| S:	Supported | ||||
| 
 | ||||
| MARVELL LIBERTAS WIRELESS DRIVER | ||||
|  | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| VERSION = 2 | ||||
| PATCHLEVEL = 6 | ||||
| SUBLEVEL = 27 | ||||
| EXTRAVERSION = -rc8 | ||||
| EXTRAVERSION = -rc9 | ||||
| NAME = Rotary Wombat | ||||
| 
 | ||||
| # *DOCUMENTATION*
 | ||||
|  | ||||
| @ -11,6 +11,9 @@ | ||||
| #include <asm-generic/sections.h> | ||||
| 
 | ||||
| extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[]; | ||||
| #ifdef	CONFIG_SMP | ||||
| extern char __cpu0_per_cpu[]; | ||||
| #endif | ||||
| extern char __start___vtop_patchlist[], __end___vtop_patchlist[]; | ||||
| extern char __start___rse_patchlist[], __end___rse_patchlist[]; | ||||
| extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[]; | ||||
|  | ||||
| @ -367,16 +367,17 @@ start_ap: | ||||
| 	;;
 | ||||
| #else | ||||
| (isAP)	br.few 2f | ||||
| 	mov r20=r19 | ||||
| 	sub r19=r19,r18 | ||||
| 	movl r20=__cpu0_per_cpu | ||||
| 	;;
 | ||||
| 	shr.u r18=r18,3 | ||||
| 1: | ||||
| 	ld8 r21=[r20],8;;
 | ||||
| 	st8[r19]=r21,8 | ||||
| 	ld8 r21=[r19],8;;
 | ||||
| 	st8[r20]=r21,8 | ||||
| 	adds r18=-1,r18;;
 | ||||
| 	cmp4.lt p7,p6=0,r18 | ||||
| (p7)	br.cond.dptk.few 1b | ||||
| 	mov r19=r20 | ||||
| 	;;
 | ||||
| 2: | ||||
| #endif | ||||
| 	tpa r19=r19 | ||||
|  | ||||
| @ -215,9 +215,6 @@ SECTIONS | ||||
|   /* Per-cpu data: */ | ||||
|   percpu : { } :percpu | ||||
|   . = ALIGN(PERCPU_PAGE_SIZE);
 | ||||
| #ifdef	CONFIG_SMP | ||||
|   . = . + PERCPU_PAGE_SIZE;	/* cpu0 per-cpu space */
 | ||||
| #endif | ||||
|   __phys_per_cpu_start = .;
 | ||||
|   .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET) | ||||
| 	{ | ||||
| @ -233,6 +230,11 @@ SECTIONS | ||||
|   data : { } :data | ||||
|   .data : AT(ADDR(.data) - LOAD_OFFSET) | ||||
| 	{ | ||||
| #ifdef	CONFIG_SMP | ||||
|   . = ALIGN(PERCPU_PAGE_SIZE);
 | ||||
| 		__cpu0_per_cpu = .;
 | ||||
|   . = . + PERCPU_PAGE_SIZE;	/* cpu0 per-cpu space */
 | ||||
| #endif | ||||
| 		DATA_DATA | ||||
| 		*(.data1) | ||||
| 		*(.gnu.linkonce.d*) | ||||
|  | ||||
| @ -163,7 +163,7 @@ per_cpu_init (void) | ||||
| 	 * get_zeroed_page(). | ||||
| 	 */ | ||||
| 	if (first_time) { | ||||
| 		void *cpu0_data = __phys_per_cpu_start - PERCPU_PAGE_SIZE; | ||||
| 		void *cpu0_data = __cpu0_per_cpu; | ||||
| 
 | ||||
| 		first_time=0; | ||||
| 
 | ||||
|  | ||||
| @ -144,7 +144,7 @@ static void *per_cpu_node_setup(void *cpu_data, int node) | ||||
| 
 | ||||
| 	for_each_possible_early_cpu(cpu) { | ||||
| 		if (cpu == 0) { | ||||
| 			void *cpu0_data = __phys_per_cpu_start - PERCPU_PAGE_SIZE; | ||||
| 			void *cpu0_data = __cpu0_per_cpu; | ||||
| 			__per_cpu_offset[cpu] = (char*)cpu0_data - | ||||
| 				__per_cpu_start; | ||||
| 		} else if (node == node_cpuid[cpu].nid) { | ||||
|  | ||||
| @ -211,6 +211,7 @@ config MIPS_MALTA | ||||
| 	select SYS_SUPPORTS_64BIT_KERNEL | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
| 	select SYS_SUPPORTS_LITTLE_ENDIAN | ||||
| 	select SYS_SUPPORTS_MIPS_CMP if BROKEN	# because SYNC_R4K is broken | ||||
| 	select SYS_SUPPORTS_MULTITHREADING | ||||
| 	select SYS_SUPPORTS_SMARTMIPS | ||||
| 	help | ||||
| @ -1403,7 +1404,6 @@ config MIPS_MT_SMTC | ||||
| 	depends on CPU_MIPS32_R2 | ||||
| 	#depends on CPU_MIPS64_R2		# once there is hardware ... | ||||
| 	depends on SYS_SUPPORTS_MULTITHREADING | ||||
| 	select GENERIC_CLOCKEVENTS_BROADCAST | ||||
| 	select CPU_MIPSR2_IRQ_VI | ||||
| 	select CPU_MIPSR2_IRQ_EI | ||||
| 	select MIPS_MT | ||||
| @ -1451,32 +1451,17 @@ config MIPS_VPE_LOADER | ||||
| 	  Includes a loader for loading an elf relocatable object | ||||
| 	  onto another VPE and running it. | ||||
| 
 | ||||
| config MIPS_MT_SMTC_INSTANT_REPLAY | ||||
| 	bool "Low-latency Dispatch of Deferred SMTC IPIs" | ||||
| 	depends on MIPS_MT_SMTC && !PREEMPT | ||||
| 	default y | ||||
| 	help | ||||
| 	  SMTC pseudo-interrupts between TCs are deferred and queued | ||||
| 	  if the target TC is interrupt-inhibited (IXMT). In the first | ||||
| 	  SMTC prototypes, these queued IPIs were serviced on return | ||||
| 	  to user mode, or on entry into the kernel idle loop. The | ||||
| 	  INSTANT_REPLAY option dispatches them as part of local_irq_restore() | ||||
| 	  processing, which adds runtime overhead (hence the option to turn | ||||
| 	  it off), but ensures that IPIs are handled promptly even under | ||||
| 	  heavy I/O interrupt load. | ||||
| 
 | ||||
| config MIPS_MT_SMTC_IM_BACKSTOP | ||||
| 	bool "Use per-TC register bits as backstop for inhibited IM bits" | ||||
| 	depends on MIPS_MT_SMTC | ||||
| 	default y | ||||
| 	default n | ||||
| 	help | ||||
| 	  To support multiple TC microthreads acting as "CPUs" within | ||||
| 	  a VPE, VPE-wide interrupt mask bits must be specially manipulated | ||||
| 	  during interrupt handling. To support legacy drivers and interrupt | ||||
| 	  controller management code, SMTC has a "backstop" to track and | ||||
| 	  if necessary restore the interrupt mask. This has some performance | ||||
| 	  impact on interrupt service overhead. Disable it only if you know | ||||
| 	  what you are doing. | ||||
| 	  impact on interrupt service overhead. | ||||
| 
 | ||||
| config MIPS_MT_SMTC_IRQAFF | ||||
| 	bool "Support IRQ affinity API" | ||||
| @ -1486,10 +1471,8 @@ config MIPS_MT_SMTC_IRQAFF | ||||
| 	  Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.) | ||||
| 	  for SMTC Linux kernel. Requires platform support, of which | ||||
| 	  an example can be found in the MIPS kernel i8259 and Malta | ||||
| 	  platform code.  It is recommended that MIPS_MT_SMTC_INSTANT_REPLAY | ||||
| 	  be enabled if MIPS_MT_SMTC_IRQAFF is used. Adds overhead to | ||||
| 	  interrupt dispatch, and should be used only if you know what | ||||
| 	  you are doing. | ||||
| 	  platform code.  Adds some overhead to interrupt dispatch, and | ||||
| 	  should be used only if you know what you are doing. | ||||
| 
 | ||||
| config MIPS_VPE_LOADER_TOM | ||||
| 	bool "Load VPE program into memory hidden from linux" | ||||
| @ -1517,6 +1500,18 @@ config MIPS_APSP_KSPD | ||||
| 	  "exit" syscall notifying other kernel modules the SP program is | ||||
| 	  exiting.  You probably want to say yes here. | ||||
| 
 | ||||
| config MIPS_CMP | ||||
| 	bool "MIPS CMP framework support" | ||||
| 	depends on SYS_SUPPORTS_MIPS_CMP | ||||
| 	select SYNC_R4K if BROKEN | ||||
| 	select SYS_SUPPORTS_SMP | ||||
| 	select SYS_SUPPORTS_SCHED_SMT if SMP | ||||
| 	select WEAK_ORDERING | ||||
| 	default n | ||||
| 	help | ||||
| 	  This is a placeholder option for the GCMP work. It will need to | ||||
| 	  be handled differently... | ||||
| 
 | ||||
| config SB1_PASS_1_WORKAROUNDS | ||||
| 	bool | ||||
| 	depends on CPU_SB1_PASS_1 | ||||
| @ -1693,6 +1688,9 @@ config SMP | ||||
| config SMP_UP | ||||
| 	bool | ||||
| 
 | ||||
| config SYS_SUPPORTS_MIPS_CMP | ||||
| 	bool | ||||
| 
 | ||||
| config SYS_SUPPORTS_SMP | ||||
| 	bool | ||||
| 
 | ||||
| @ -1740,17 +1738,6 @@ config NR_CPUS | ||||
| 	  performance should round up your number of processors to the next | ||||
| 	  power of two. | ||||
| 
 | ||||
| config MIPS_CMP | ||||
| 	bool "MIPS CMP framework support" | ||||
| 	depends on SMP | ||||
| 	select SYNC_R4K | ||||
| 	select SYS_SUPPORTS_SCHED_SMT | ||||
| 	select WEAK_ORDERING | ||||
| 	default n | ||||
| 	help | ||||
| 	  This is a placeholder option for the GCMP work. It will need to | ||||
| 	  be handled differently... | ||||
| 
 | ||||
| source "kernel/time/Kconfig" | ||||
| 
 | ||||
| # | ||||
|  | ||||
| @ -10,6 +10,7 @@ obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | ||||
| 
 | ||||
| obj-$(CONFIG_CEVT_BCM1480)	+= cevt-bcm1480.o | ||||
| obj-$(CONFIG_CEVT_R4K)		+= cevt-r4k.o | ||||
| obj-$(CONFIG_MIPS_MT_SMTC)	+= cevt-smtc.o | ||||
| obj-$(CONFIG_CEVT_DS1287)	+= cevt-ds1287.o | ||||
| obj-$(CONFIG_CEVT_GT641XX)	+= cevt-gt641xx.o | ||||
| obj-$(CONFIG_CEVT_SB1250)	+= cevt-sb1250.o | ||||
|  | ||||
| @ -12,6 +12,14 @@ | ||||
| 
 | ||||
| #include <asm/smtc_ipi.h> | ||||
| #include <asm/time.h> | ||||
| #include <asm/cevt-r4k.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * The SMTC Kernel for the 34K, 1004K, et. al. replaces several | ||||
|  * of these routines with SMTC-specific variants. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef CONFIG_MIPS_MT_SMTC | ||||
| 
 | ||||
| static int mips_next_event(unsigned long delta, | ||||
|                            struct clock_event_device *evt) | ||||
| @ -19,60 +27,27 @@ static int mips_next_event(unsigned long delta, | ||||
| 	unsigned int cnt; | ||||
| 	int res; | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 	{ | ||||
| 	unsigned long flags, vpflags; | ||||
| 	local_irq_save(flags); | ||||
| 	vpflags = dvpe(); | ||||
| #endif | ||||
| 	cnt = read_c0_count(); | ||||
| 	cnt += delta; | ||||
| 	write_c0_compare(cnt); | ||||
| 	res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 	evpe(vpflags); | ||||
| 	local_irq_restore(flags); | ||||
| 	} | ||||
| #endif | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| static void mips_set_mode(enum clock_event_mode mode, | ||||
|                           struct clock_event_device *evt) | ||||
| #endif /* CONFIG_MIPS_MT_SMTC */ | ||||
| 
 | ||||
| void mips_set_clock_mode(enum clock_event_mode mode, | ||||
| 				struct clock_event_device *evt) | ||||
| { | ||||
| 	/* Nothing to do ...  */ | ||||
| } | ||||
| 
 | ||||
| static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); | ||||
| static int cp0_timer_irq_installed; | ||||
| DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); | ||||
| int cp0_timer_irq_installed; | ||||
| 
 | ||||
| /*
 | ||||
|  * Timer ack for an R4k-compatible timer of a known frequency. | ||||
|  */ | ||||
| static void c0_timer_ack(void) | ||||
| { | ||||
| 	write_c0_compare(read_c0_compare()); | ||||
| } | ||||
| #ifndef CONFIG_MIPS_MT_SMTC | ||||
| 
 | ||||
| /*
 | ||||
|  * Possibly handle a performance counter interrupt. | ||||
|  * Return true if the timer interrupt should not be checked | ||||
|  */ | ||||
| static inline int handle_perf_irq(int r2) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * The performance counter overflow interrupt may be shared with the | ||||
| 	 * timer interrupt (cp0_perfcount_irq < 0). If it is and a | ||||
| 	 * performance counter has overflowed (perf_irq() == IRQ_HANDLED) | ||||
| 	 * and we can't reliably determine if a counter interrupt has also | ||||
| 	 * happened (!r2) then don't check for a timer interrupt. | ||||
| 	 */ | ||||
| 	return (cp0_perfcount_irq < 0) && | ||||
| 		perf_irq() == IRQ_HANDLED && | ||||
| 		!r2; | ||||
| } | ||||
| 
 | ||||
| static irqreturn_t c0_compare_interrupt(int irq, void *dev_id) | ||||
| irqreturn_t c0_compare_interrupt(int irq, void *dev_id) | ||||
| { | ||||
| 	const int r2 = cpu_has_mips_r2; | ||||
| 	struct clock_event_device *cd; | ||||
| @ -93,12 +68,8 @@ static irqreturn_t c0_compare_interrupt(int irq, void *dev_id) | ||||
| 	 * interrupt.  Being the paranoiacs we are we check anyway. | ||||
| 	 */ | ||||
| 	if (!r2 || (read_c0_cause() & (1 << 30))) { | ||||
| 		c0_timer_ack(); | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 		if (cpu_data[cpu].vpe_id) | ||||
| 			goto out; | ||||
| 		cpu = 0; | ||||
| #endif | ||||
| 		/* Clear Count/Compare Interrupt */ | ||||
| 		write_c0_compare(read_c0_compare()); | ||||
| 		cd = &per_cpu(mips_clockevent_device, cpu); | ||||
| 		cd->event_handler(cd); | ||||
| 	} | ||||
| @ -107,65 +78,16 @@ out: | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| static struct irqaction c0_compare_irqaction = { | ||||
| #endif /* Not CONFIG_MIPS_MT_SMTC */ | ||||
| 
 | ||||
| struct irqaction c0_compare_irqaction = { | ||||
| 	.handler = c0_compare_interrupt, | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 	.flags = IRQF_DISABLED, | ||||
| #else | ||||
| 	.flags = IRQF_DISABLED | IRQF_PERCPU, | ||||
| #endif | ||||
| 	.name = "timer", | ||||
| }; | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); | ||||
| 
 | ||||
| static void smtc_set_mode(enum clock_event_mode mode, | ||||
|                           struct clock_event_device *evt) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static void mips_broadcast(cpumask_t mask) | ||||
| { | ||||
| 	unsigned int cpu; | ||||
| 
 | ||||
| 	for_each_cpu_mask(cpu, mask) | ||||
| 		smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); | ||||
| } | ||||
| 
 | ||||
| static void setup_smtc_dummy_clockevent_device(void) | ||||
| { | ||||
| 	//uint64_t mips_freq = mips_hpt_^frequency;
 | ||||
| 	unsigned int cpu = smp_processor_id(); | ||||
| 	struct clock_event_device *cd; | ||||
| 
 | ||||
| 	cd = &per_cpu(smtc_dummy_clockevent_device, cpu); | ||||
| 
 | ||||
| 	cd->name		= "SMTC"; | ||||
| 	cd->features		= CLOCK_EVT_FEAT_DUMMY; | ||||
| 
 | ||||
| 	/* Calculate the min / max delta */ | ||||
| 	cd->mult	= 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
 | ||||
| 	cd->shift		= 0; //32;
 | ||||
| 	cd->max_delta_ns	= 0; //clockevent_delta2ns(0x7fffffff, cd);
 | ||||
| 	cd->min_delta_ns	= 0; //clockevent_delta2ns(0x30, cd);
 | ||||
| 
 | ||||
| 	cd->rating		= 200; | ||||
| 	cd->irq			= 17; //-1;
 | ||||
| //	if (cpu)
 | ||||
| //		cd->cpumask	= CPU_MASK_ALL; // cpumask_of_cpu(cpu);
 | ||||
| //	else
 | ||||
| 		cd->cpumask	= cpumask_of_cpu(cpu); | ||||
| 
 | ||||
| 	cd->set_mode		= smtc_set_mode; | ||||
| 
 | ||||
| 	cd->broadcast		= mips_broadcast; | ||||
| 
 | ||||
| 	clockevents_register_device(cd); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void mips_event_handler(struct clock_event_device *dev) | ||||
| void mips_event_handler(struct clock_event_device *dev) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| @ -177,7 +99,23 @@ static int c0_compare_int_pending(void) | ||||
| 	return (read_c0_cause() >> cp0_compare_irq) & 0x100; | ||||
| } | ||||
| 
 | ||||
| static int c0_compare_int_usable(void) | ||||
| /*
 | ||||
|  * Compare interrupt can be routed and latched outside the core, | ||||
|  * so a single execution hazard barrier may not be enough to give | ||||
|  * it time to clear as seen in the Cause register.  4 time the | ||||
|  * pipeline depth seems reasonably conservative, and empirically | ||||
|  * works better in configurations with high CPU/bus clock ratios. | ||||
|  */ | ||||
| 
 | ||||
| #define compare_change_hazard() \ | ||||
| 	do { \ | ||||
| 		irq_disable_hazard(); \ | ||||
| 		irq_disable_hazard(); \ | ||||
| 		irq_disable_hazard(); \ | ||||
| 		irq_disable_hazard(); \ | ||||
| 	} while (0) | ||||
| 
 | ||||
| int c0_compare_int_usable(void) | ||||
| { | ||||
| 	unsigned int delta; | ||||
| 	unsigned int cnt; | ||||
| @ -187,7 +125,7 @@ static int c0_compare_int_usable(void) | ||||
| 	 */ | ||||
| 	if (c0_compare_int_pending()) { | ||||
| 		write_c0_compare(read_c0_count()); | ||||
| 		irq_disable_hazard(); | ||||
| 		compare_change_hazard(); | ||||
| 		if (c0_compare_int_pending()) | ||||
| 			return 0; | ||||
| 	} | ||||
| @ -196,7 +134,7 @@ static int c0_compare_int_usable(void) | ||||
| 		cnt = read_c0_count(); | ||||
| 		cnt += delta; | ||||
| 		write_c0_compare(cnt); | ||||
| 		irq_disable_hazard(); | ||||
| 		compare_change_hazard(); | ||||
| 		if ((int)(read_c0_count() - cnt) < 0) | ||||
| 		    break; | ||||
| 		/* increase delta if the timer was already expired */ | ||||
| @ -205,11 +143,12 @@ static int c0_compare_int_usable(void) | ||||
| 	while ((int)(read_c0_count() - cnt) <= 0) | ||||
| 		;	/* Wait for expiry  */ | ||||
| 
 | ||||
| 	compare_change_hazard(); | ||||
| 	if (!c0_compare_int_pending()) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	write_c0_compare(read_c0_count()); | ||||
| 	irq_disable_hazard(); | ||||
| 	compare_change_hazard(); | ||||
| 	if (c0_compare_int_pending()) | ||||
| 		return 0; | ||||
| 
 | ||||
| @ -219,6 +158,8 @@ static int c0_compare_int_usable(void) | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| #ifndef CONFIG_MIPS_MT_SMTC | ||||
| 
 | ||||
| int __cpuinit mips_clockevent_init(void) | ||||
| { | ||||
| 	uint64_t mips_freq = mips_hpt_frequency; | ||||
| @ -229,17 +170,6 @@ int __cpuinit mips_clockevent_init(void) | ||||
| 	if (!cpu_has_counter || !mips_hpt_frequency) | ||||
| 		return -ENXIO; | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 	setup_smtc_dummy_clockevent_device(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * On SMTC we only register VPE0's compare interrupt as clockevent | ||||
| 	 * device. | ||||
| 	 */ | ||||
| 	if (cpu) | ||||
| 		return 0; | ||||
| #endif | ||||
| 
 | ||||
| 	if (!c0_compare_int_usable()) | ||||
| 		return -ENXIO; | ||||
| 
 | ||||
| @ -265,13 +195,9 @@ int __cpuinit mips_clockevent_init(void) | ||||
| 
 | ||||
| 	cd->rating		= 300; | ||||
| 	cd->irq			= irq; | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 	cd->cpumask		= CPU_MASK_ALL; | ||||
| #else | ||||
| 	cd->cpumask		= cpumask_of_cpu(cpu); | ||||
| #endif | ||||
| 	cd->set_next_event	= mips_next_event; | ||||
| 	cd->set_mode		= mips_set_mode; | ||||
| 	cd->set_mode		= mips_set_clock_mode; | ||||
| 	cd->event_handler	= mips_event_handler; | ||||
| 
 | ||||
| 	clockevents_register_device(cd); | ||||
| @ -281,12 +207,9 @@ int __cpuinit mips_clockevent_init(void) | ||||
| 
 | ||||
| 	cp0_timer_irq_installed = 1; | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) | ||||
| 	setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); | ||||
| #else | ||||
| 	setup_irq(irq, &c0_compare_irqaction); | ||||
| #endif | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #endif /* Not CONFIG_MIPS_MT_SMTC */ | ||||
|  | ||||
							
								
								
									
										321
									
								
								arch/mips/kernel/cevt-smtc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										321
									
								
								arch/mips/kernel/cevt-smtc.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,321 @@ | ||||
| /*
 | ||||
|  * 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) 2007 MIPS Technologies, Inc. | ||||
|  * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org> | ||||
|  * Copyright (C) 2008 Kevin D. Kissell, Paralogos sarl | ||||
|  */ | ||||
| #include <linux/clockchips.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/percpu.h> | ||||
| 
 | ||||
| #include <asm/smtc_ipi.h> | ||||
| #include <asm/time.h> | ||||
| #include <asm/cevt-r4k.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * Variant clock event timer support for SMTC on MIPS 34K, 1004K | ||||
|  * or other MIPS MT cores. | ||||
|  * | ||||
|  * Notes on SMTC Support: | ||||
|  * | ||||
|  * SMTC has multiple microthread TCs pretending to be Linux CPUs. | ||||
|  * But there's only one Count/Compare pair per VPE, and Compare | ||||
|  * interrupts are taken opportunisitically by available TCs | ||||
|  * bound to the VPE with the Count register.  The new timer | ||||
|  * framework provides for global broadcasts, but we really | ||||
|  * want VPE-level multicasts for best behavior. So instead | ||||
|  * of invoking the high-level clock-event broadcast code, | ||||
|  * this version of SMTC support uses the historical SMTC | ||||
|  * multicast mechanisms "under the hood", appearing to the | ||||
|  * generic clock layer as if the interrupts are per-CPU. | ||||
|  * | ||||
|  * The approach taken here is to maintain a set of NR_CPUS | ||||
|  * virtual timers, and track which "CPU" needs to be alerted | ||||
|  * at each event. | ||||
|  * | ||||
|  * It's unlikely that we'll see a MIPS MT core with more than | ||||
|  * 2 VPEs, but we *know* that we won't need to handle more | ||||
|  * VPEs than we have "CPUs".  So NCPUs arrays of NCPUs elements | ||||
|  * is always going to be overkill, but always going to be enough. | ||||
|  */ | ||||
| 
 | ||||
| unsigned long smtc_nexttime[NR_CPUS][NR_CPUS]; | ||||
| static int smtc_nextinvpe[NR_CPUS]; | ||||
| 
 | ||||
| /*
 | ||||
|  * Timestamps stored are absolute values to be programmed | ||||
|  * into Count register.  Valid timestamps will never be zero. | ||||
|  * If a Zero Count value is actually calculated, it is converted | ||||
|  * to be a 1, which will introduce 1 or two CPU cycles of error | ||||
|  * roughly once every four billion events, which at 1000 HZ means | ||||
|  * about once every 50 days.  If that's actually a problem, one | ||||
|  * could alternate squashing 0 to 1 and to -1. | ||||
|  */ | ||||
| 
 | ||||
| #define MAKEVALID(x) (((x) == 0L) ? 1L : (x)) | ||||
| #define ISVALID(x) ((x) != 0L) | ||||
| 
 | ||||
| /*
 | ||||
|  * Time comparison is subtle, as it's really truncated | ||||
|  * modular arithmetic. | ||||
|  */ | ||||
| 
 | ||||
| #define IS_SOONER(a, b, reference) \ | ||||
|     (((a) - (unsigned long)(reference)) < ((b) - (unsigned long)(reference))) | ||||
| 
 | ||||
| /*
 | ||||
|  * CATCHUP_INCREMENT, used when the function falls behind the counter. | ||||
|  * Could be an increasing function instead of a constant; | ||||
|  */ | ||||
| 
 | ||||
| #define CATCHUP_INCREMENT 64 | ||||
| 
 | ||||
| static int mips_next_event(unsigned long delta, | ||||
| 				struct clock_event_device *evt) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	unsigned int mtflags; | ||||
| 	unsigned long timestamp, reference, previous; | ||||
| 	unsigned long nextcomp = 0L; | ||||
| 	int vpe = current_cpu_data.vpe_id; | ||||
| 	int cpu = smp_processor_id(); | ||||
| 	local_irq_save(flags); | ||||
| 	mtflags = dmt(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Maintain the per-TC virtual timer | ||||
| 	 * and program the per-VPE shared Count register | ||||
| 	 * as appropriate here... | ||||
| 	 */ | ||||
| 	reference = (unsigned long)read_c0_count(); | ||||
| 	timestamp = MAKEVALID(reference + delta); | ||||
| 	/*
 | ||||
| 	 * To really model the clock, we have to catch the case | ||||
| 	 * where the current next-in-VPE timestamp is the old | ||||
| 	 * timestamp for the calling CPE, but the new value is | ||||
| 	 * in fact later.  In that case, we have to do a full | ||||
| 	 * scan and discover the new next-in-VPE CPU id and | ||||
| 	 * timestamp. | ||||
| 	 */ | ||||
| 	previous = smtc_nexttime[vpe][cpu]; | ||||
| 	if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous) | ||||
| 	    && IS_SOONER(previous, timestamp, reference)) { | ||||
| 		int i; | ||||
| 		int soonest = cpu; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Update timestamp array here, so that new | ||||
| 		 * value gets considered along with those of | ||||
| 		 * other virtual CPUs on the VPE. | ||||
| 		 */ | ||||
| 		smtc_nexttime[vpe][cpu] = timestamp; | ||||
| 		for_each_online_cpu(i) { | ||||
| 			if (ISVALID(smtc_nexttime[vpe][i]) | ||||
| 			    && IS_SOONER(smtc_nexttime[vpe][i], | ||||
| 				smtc_nexttime[vpe][soonest], reference)) { | ||||
| 				    soonest = i; | ||||
| 			} | ||||
| 		} | ||||
| 		smtc_nextinvpe[vpe] = soonest; | ||||
| 		nextcomp = smtc_nexttime[vpe][soonest]; | ||||
| 	/*
 | ||||
| 	 * Otherwise, we don't have to process the whole array rank, | ||||
| 	 * we just have to see if the event horizon has gotten closer. | ||||
| 	 */ | ||||
| 	} else { | ||||
| 		if (!ISVALID(smtc_nexttime[vpe][smtc_nextinvpe[vpe]]) || | ||||
| 		    IS_SOONER(timestamp, | ||||
| 			smtc_nexttime[vpe][smtc_nextinvpe[vpe]], reference)) { | ||||
| 			    smtc_nextinvpe[vpe] = cpu; | ||||
| 			    nextcomp = timestamp; | ||||
| 		} | ||||
| 		/*
 | ||||
| 		 * Since next-in-VPE may me the same as the executing | ||||
| 		 * virtual CPU, we update the array *after* checking | ||||
| 		 * its value. | ||||
| 		 */ | ||||
| 		smtc_nexttime[vpe][cpu] = timestamp; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * It may be that, in fact, we don't need to update Compare, | ||||
| 	 * but if we do, we want to make sure we didn't fall into | ||||
| 	 * a crack just behind Count. | ||||
| 	 */ | ||||
| 	if (ISVALID(nextcomp)) { | ||||
| 		write_c0_compare(nextcomp); | ||||
| 		ehb(); | ||||
| 		/*
 | ||||
| 		 * We never return an error, we just make sure | ||||
| 		 * that we trigger the handlers as quickly as | ||||
| 		 * we can if we fell behind. | ||||
| 		 */ | ||||
| 		while ((nextcomp - (unsigned long)read_c0_count()) | ||||
| 			> (unsigned long)LONG_MAX) { | ||||
| 			nextcomp += CATCHUP_INCREMENT; | ||||
| 			write_c0_compare(nextcomp); | ||||
| 			ehb(); | ||||
| 		} | ||||
| 	} | ||||
| 	emt(mtflags); | ||||
| 	local_irq_restore(flags); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void smtc_distribute_timer(int vpe) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	unsigned int mtflags; | ||||
| 	int cpu; | ||||
| 	struct clock_event_device *cd; | ||||
| 	unsigned long nextstamp = 0L; | ||||
| 	unsigned long reference; | ||||
| 
 | ||||
| 
 | ||||
| repeat: | ||||
| 	for_each_online_cpu(cpu) { | ||||
| 	    /*
 | ||||
| 	     * Find virtual CPUs within the current VPE who have | ||||
| 	     * unserviced timer requests whose time is now past. | ||||
| 	     */ | ||||
| 	    local_irq_save(flags); | ||||
| 	    mtflags = dmt(); | ||||
| 	    if (cpu_data[cpu].vpe_id == vpe && | ||||
| 		ISVALID(smtc_nexttime[vpe][cpu])) { | ||||
| 		reference = (unsigned long)read_c0_count(); | ||||
| 		if ((smtc_nexttime[vpe][cpu] - reference) | ||||
| 			 > (unsigned long)LONG_MAX) { | ||||
| 			    smtc_nexttime[vpe][cpu] = 0L; | ||||
| 			    emt(mtflags); | ||||
| 			    local_irq_restore(flags); | ||||
| 			    /*
 | ||||
| 			     * We don't send IPIs to ourself. | ||||
| 			     */ | ||||
| 			    if (cpu != smp_processor_id()) { | ||||
| 				smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); | ||||
| 			    } else { | ||||
| 				cd = &per_cpu(mips_clockevent_device, cpu); | ||||
| 				cd->event_handler(cd); | ||||
| 			    } | ||||
| 		} else { | ||||
| 			/* Local to VPE but Valid Time not yet reached. */ | ||||
| 			if (!ISVALID(nextstamp) || | ||||
| 			    IS_SOONER(smtc_nexttime[vpe][cpu], nextstamp, | ||||
| 			    reference)) { | ||||
| 				smtc_nextinvpe[vpe] = cpu; | ||||
| 				nextstamp = smtc_nexttime[vpe][cpu]; | ||||
| 			} | ||||
| 			emt(mtflags); | ||||
| 			local_irq_restore(flags); | ||||
| 		} | ||||
| 	    } else { | ||||
| 		emt(mtflags); | ||||
| 		local_irq_restore(flags); | ||||
| 
 | ||||
| 	    } | ||||
| 	} | ||||
| 	/* Reprogram for interrupt at next soonest timestamp for VPE */ | ||||
| 	if (ISVALID(nextstamp)) { | ||||
| 		write_c0_compare(nextstamp); | ||||
| 		ehb(); | ||||
| 		if ((nextstamp - (unsigned long)read_c0_count()) | ||||
| 			> (unsigned long)LONG_MAX) | ||||
| 				goto repeat; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| irqreturn_t c0_compare_interrupt(int irq, void *dev_id) | ||||
| { | ||||
| 	int cpu = smp_processor_id(); | ||||
| 
 | ||||
| 	/* If we're running SMTC, we've got MIPS MT and therefore MIPS32R2 */ | ||||
| 	handle_perf_irq(1); | ||||
| 
 | ||||
| 	if (read_c0_cause() & (1 << 30)) { | ||||
| 		/* Clear Count/Compare Interrupt */ | ||||
| 		write_c0_compare(read_c0_compare()); | ||||
| 		smtc_distribute_timer(cpu_data[cpu].vpe_id); | ||||
| 	} | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int __cpuinit mips_clockevent_init(void) | ||||
| { | ||||
| 	uint64_t mips_freq = mips_hpt_frequency; | ||||
| 	unsigned int cpu = smp_processor_id(); | ||||
| 	struct clock_event_device *cd; | ||||
| 	unsigned int irq; | ||||
| 	int i; | ||||
| 	int j; | ||||
| 
 | ||||
| 	if (!cpu_has_counter || !mips_hpt_frequency) | ||||
| 		return -ENXIO; | ||||
| 	if (cpu == 0) { | ||||
| 		for (i = 0; i < num_possible_cpus(); i++) { | ||||
| 			smtc_nextinvpe[i] = 0; | ||||
| 			for (j = 0; j < num_possible_cpus(); j++) | ||||
| 				smtc_nexttime[i][j] = 0L; | ||||
| 		} | ||||
| 		/*
 | ||||
| 		 * SMTC also can't have the usablility test | ||||
| 		 * run by secondary TCs once Compare is in use. | ||||
| 		 */ | ||||
| 		if (!c0_compare_int_usable()) | ||||
| 			return -ENXIO; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * With vectored interrupts things are getting platform specific. | ||||
| 	 * get_c0_compare_int is a hook to allow a platform to return the | ||||
| 	 * interrupt number of it's liking. | ||||
| 	 */ | ||||
| 	irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | ||||
| 	if (get_c0_compare_int) | ||||
| 		irq = get_c0_compare_int(); | ||||
| 
 | ||||
| 	cd = &per_cpu(mips_clockevent_device, cpu); | ||||
| 
 | ||||
| 	cd->name		= "MIPS"; | ||||
| 	cd->features		= CLOCK_EVT_FEAT_ONESHOT; | ||||
| 
 | ||||
| 	/* Calculate the min / max delta */ | ||||
| 	cd->mult	= div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); | ||||
| 	cd->shift		= 32; | ||||
| 	cd->max_delta_ns	= clockevent_delta2ns(0x7fffffff, cd); | ||||
| 	cd->min_delta_ns	= clockevent_delta2ns(0x300, cd); | ||||
| 
 | ||||
| 	cd->rating		= 300; | ||||
| 	cd->irq			= irq; | ||||
| 	cd->cpumask		= cpumask_of_cpu(cpu); | ||||
| 	cd->set_next_event	= mips_next_event; | ||||
| 	cd->set_mode		= mips_set_clock_mode; | ||||
| 	cd->event_handler	= mips_event_handler; | ||||
| 
 | ||||
| 	clockevents_register_device(cd); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * On SMTC we only want to do the data structure | ||||
| 	 * initialization and IRQ setup once. | ||||
| 	 */ | ||||
| 	if (cpu) | ||||
| 		return 0; | ||||
| 	/*
 | ||||
| 	 * And we need the hwmask associated with the c0_compare | ||||
| 	 * vector to be initialized. | ||||
| 	 */ | ||||
| 	irq_hwmask[irq] = (0x100 << cp0_compare_irq); | ||||
| 	if (cp0_timer_irq_installed) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	cp0_timer_irq_installed = 1; | ||||
| 
 | ||||
| 	setup_irq(irq, &c0_compare_irqaction); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -54,14 +54,18 @@ extern void r4k_wait(void); | ||||
|  * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes | ||||
|  * using this version a gamble. | ||||
|  */ | ||||
| static void r4k_wait_irqoff(void) | ||||
| void r4k_wait_irqoff(void) | ||||
| { | ||||
| 	local_irq_disable(); | ||||
| 	if (!need_resched()) | ||||
| 		__asm__("	.set	mips3		\n" | ||||
| 		__asm__("	.set	push		\n" | ||||
| 			"	.set	mips3		\n" | ||||
| 			"	wait			\n" | ||||
| 			"	.set	mips0		\n"); | ||||
| 			"	.set	pop		\n"); | ||||
| 	local_irq_enable(); | ||||
| 	__asm__(" 	.globl __pastwait	\n" | ||||
| 		"__pastwait:			\n"); | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
| @ -79,11 +79,6 @@ FEXPORT(syscall_exit) | ||||
| 
 | ||||
| FEXPORT(restore_all)			# restore full frame | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| /* Detect and execute deferred IPI "interrupts" */ | ||||
| 	LONG_L	s0, TI_REGS($28) | ||||
| 	LONG_S	sp, TI_REGS($28) | ||||
| 	jal	deferred_smtc_ipi | ||||
| 	LONG_S	s0, TI_REGS($28) | ||||
| #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP | ||||
| /* Re-arm any temporarily masked interrupts not explicitly "acked" */ | ||||
| 	mfc0	v0, CP0_TCSTATUS | ||||
| @ -112,6 +107,11 @@ FEXPORT(restore_all)			# restore full frame | ||||
| 	xor	t0, t0, t3 | ||||
| 	mtc0	t0, CP0_TCCONTEXT | ||||
| #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ | ||||
| /* Detect and execute deferred IPI "interrupts" */ | ||||
| 	LONG_L	s0, TI_REGS($28) | ||||
| 	LONG_S	sp, TI_REGS($28) | ||||
| 	jal	deferred_smtc_ipi | ||||
| 	LONG_S	s0, TI_REGS($28) | ||||
| #endif /* CONFIG_MIPS_MT_SMTC */ | ||||
| 	.set	noat
 | ||||
| 	RESTORE_TEMP | ||||
|  | ||||
| @ -282,8 +282,8 @@ NESTED(except_vec_vi_handler, 0, sp) | ||||
| 	and	t0, a0, t1 | ||||
| #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP | ||||
| 	mfc0	t2, CP0_TCCONTEXT | ||||
| 	or	t0, t0, t2 | ||||
| 	mtc0	t0, CP0_TCCONTEXT | ||||
| 	or	t2, t0, t2 | ||||
| 	mtc0	t2, CP0_TCCONTEXT | ||||
| #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ | ||||
| 	xor	t1, t1, t0 | ||||
| 	mtc0	t1, CP0_STATUS | ||||
|  | ||||
| @ -22,6 +22,7 @@ | ||||
| #include <asm/irqflags.h> | ||||
| #include <asm/regdef.h> | ||||
| #include <asm/page.h> | ||||
| #include <asm/pgtable-bits.h> | ||||
| #include <asm/mipsregs.h> | ||||
| #include <asm/stackframe.h> | ||||
| 
 | ||||
|  | ||||
| @ -159,7 +159,7 @@ __setup("fpaff=", fpaff_thresh); | ||||
| /*
 | ||||
|  * FPU Use Factor empirically derived from experiments on 34K | ||||
|  */ | ||||
| #define FPUSEFACTOR 333 | ||||
| #define FPUSEFACTOR 2000 | ||||
| 
 | ||||
| static __init int mt_fp_affinity_init(void) | ||||
| { | ||||
|  | ||||
| @ -55,7 +55,7 @@ void __noreturn cpu_idle(void) | ||||
| 	while (1) { | ||||
| 		tick_nohz_stop_sched_tick(1); | ||||
| 		while (!need_resched()) { | ||||
| #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 			extern void smtc_idle_loop_hook(void); | ||||
| 
 | ||||
| 			smtc_idle_loop_hook(); | ||||
| @ -145,19 +145,18 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | ||||
| 	 */ | ||||
| 	p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); | ||||
| 	childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 	/*
 | ||||
| 	 * SMTC restores TCStatus after Status, and the CU bits | ||||
| 	 * are aliased there. | ||||
| 	 */ | ||||
| 	childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1); | ||||
| #endif | ||||
| 	clear_tsk_thread_flag(p, TIF_USEDFPU); | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_MT_FPAFF | ||||
| 	clear_tsk_thread_flag(p, TIF_FPUBOUND); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * FPU affinity support is cleaner if we track the | ||||
| 	 * user-visible CPU affinity from the very beginning. | ||||
| 	 * The generic cpus_allowed mask will already have | ||||
| 	 * been copied from the parent before copy_thread | ||||
| 	 * is invoked. | ||||
| 	 */ | ||||
| 	p->thread.user_cpus_allowed = p->cpus_allowed; | ||||
| #endif /* CONFIG_MIPS_MT_FPAFF */ | ||||
| 
 | ||||
| 	if (clone_flags & CLONE_SETTLS) | ||||
|  | ||||
| @ -238,7 +238,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | ||||
| 		case FPC_EIR: {	/* implementation / version register */ | ||||
| 			unsigned int flags; | ||||
| #ifdef CONFIG_MIPS_MT_SMTC | ||||
| 			unsigned int irqflags; | ||||
| 			unsigned long irqflags; | ||||
| 			unsigned int mtflags; | ||||
| #endif /* CONFIG_MIPS_MT_SMTC */ | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,21 @@ | ||||
| /* Copyright (C) 2004 Mips Technologies, 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, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  * Copyright (C) 2004 Mips Technologies, Inc | ||||
|  * Copyright (C) 2008 Kevin D. Kissell | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/clockchips.h> | ||||
| #include <linux/kernel.h> | ||||
| @ -21,7 +38,6 @@ | ||||
| #include <asm/time.h> | ||||
| #include <asm/addrspace.h> | ||||
| #include <asm/smtc.h> | ||||
| #include <asm/smtc_ipi.h> | ||||
| #include <asm/smtc_proc.h> | ||||
| 
 | ||||
| /*
 | ||||
| @ -58,11 +74,6 @@ unsigned long irq_hwmask[NR_IRQS]; | ||||
| 
 | ||||
| asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; | ||||
| 
 | ||||
| /*
 | ||||
|  * Clock interrupt "latch" buffers, per "CPU" | ||||
|  */ | ||||
| 
 | ||||
| static atomic_t ipi_timer_latch[NR_CPUS]; | ||||
| 
 | ||||
| /*
 | ||||
|  * Number of InterProcessor Interrupt (IPI) message buffers to allocate | ||||
| @ -70,7 +81,7 @@ static atomic_t ipi_timer_latch[NR_CPUS]; | ||||
| 
 | ||||
| #define IPIBUF_PER_CPU 4 | ||||
| 
 | ||||
| static struct smtc_ipi_q IPIQ[NR_CPUS]; | ||||
| struct smtc_ipi_q IPIQ[NR_CPUS]; | ||||
| static struct smtc_ipi_q freeIPIq; | ||||
| 
 | ||||
| 
 | ||||
| @ -282,7 +293,7 @@ static void smtc_configure_tlb(void) | ||||
|  * phys_cpu_present_map and the logical/physical mappings. | ||||
|  */ | ||||
| 
 | ||||
| int __init mipsmt_build_cpu_map(int start_cpu_slot) | ||||
| int __init smtc_build_cpu_map(int start_cpu_slot) | ||||
| { | ||||
| 	int i, ntcs; | ||||
| 
 | ||||
| @ -325,7 +336,12 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | ||||
| 	write_tc_c0_tcstatus((read_tc_c0_tcstatus() | ||||
| 			& ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT)) | ||||
| 			| TCSTATUS_A); | ||||
| 	write_tc_c0_tccontext(0); | ||||
| 	/*
 | ||||
| 	 * TCContext gets an offset from the base of the IPIQ array | ||||
| 	 * to be used in low-level code to detect the presence of | ||||
| 	 * an active IPI queue | ||||
| 	 */ | ||||
| 	write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); | ||||
| 	/* Bind tc to vpe */ | ||||
| 	write_tc_c0_tcbind(vpe); | ||||
| 	/* In general, all TCs should have the same cpu_data indications */ | ||||
| @ -336,10 +352,18 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | ||||
| 		cpu_data[cpu].options &= ~MIPS_CPU_FPU; | ||||
| 	cpu_data[cpu].vpe_id = vpe; | ||||
| 	cpu_data[cpu].tc_id = tc; | ||||
| 	/* Multi-core SMTC hasn't been tested, but be prepared */ | ||||
| 	cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Tweak to get Count registes in as close a sync as possible. | ||||
|  * Value seems good for 34K-class cores. | ||||
|  */ | ||||
| 
 | ||||
| void mipsmt_prepare_cpus(void) | ||||
| #define CP0_SKEW 8 | ||||
| 
 | ||||
| void smtc_prepare_cpus(int cpus) | ||||
| { | ||||
| 	int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu; | ||||
| 	unsigned long flags; | ||||
| @ -363,13 +387,13 @@ void mipsmt_prepare_cpus(void) | ||||
| 		IPIQ[i].head = IPIQ[i].tail = NULL; | ||||
| 		spin_lock_init(&IPIQ[i].lock); | ||||
| 		IPIQ[i].depth = 0; | ||||
| 		atomic_set(&ipi_timer_latch[i], 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/* cpu_data index starts at zero */ | ||||
| 	cpu = 0; | ||||
| 	cpu_data[cpu].vpe_id = 0; | ||||
| 	cpu_data[cpu].tc_id = 0; | ||||
| 	cpu_data[cpu].core = (read_c0_ebase() >> 1) & 0xff; | ||||
| 	cpu++; | ||||
| 
 | ||||
| 	/* Report on boot-time options */ | ||||
| @ -484,7 +508,8 @@ void mipsmt_prepare_cpus(void) | ||||
| 			write_vpe_c0_compare(0); | ||||
| 			/* Propagate Config7 */ | ||||
| 			write_vpe_c0_config7(read_c0_config7()); | ||||
| 			write_vpe_c0_count(read_c0_count()); | ||||
| 			write_vpe_c0_count(read_c0_count() + CP0_SKEW); | ||||
| 			ehb(); | ||||
| 		} | ||||
| 		/* enable multi-threading within VPE */ | ||||
| 		write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); | ||||
| @ -556,7 +581,7 @@ void mipsmt_prepare_cpus(void) | ||||
| void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) | ||||
| { | ||||
| 	extern u32 kernelsp[NR_CPUS]; | ||||
| 	long flags; | ||||
| 	unsigned long flags; | ||||
| 	int mtflags; | ||||
| 
 | ||||
| 	LOCK_MT_PRA(); | ||||
| @ -585,24 +610,22 @@ void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) | ||||
| 
 | ||||
| void smtc_init_secondary(void) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * Start timer on secondary VPEs if necessary. | ||||
| 	 * plat_timer_setup has already have been invoked by init/main | ||||
| 	 * on "boot" TC.  Like per_cpu_trap_init() hack, this assumes that | ||||
| 	 * SMTC init code assigns TCs consdecutively and in ascending order | ||||
| 	 * to across available VPEs. | ||||
| 	 */ | ||||
| 	if (((read_c0_tcbind() & TCBIND_CURTC) != 0) && | ||||
| 	    ((read_c0_tcbind() & TCBIND_CURVPE) | ||||
| 	    != cpu_data[smp_processor_id() - 1].vpe_id)){ | ||||
| 		write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); | ||||
| 	} | ||||
| 
 | ||||
| 	local_irq_enable(); | ||||
| } | ||||
| 
 | ||||
| void smtc_smp_finish(void) | ||||
| { | ||||
| 	int cpu = smp_processor_id(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Lowest-numbered CPU per VPE starts a clock tick. | ||||
| 	 * Like per_cpu_trap_init() hack, this assumes that | ||||
| 	 * SMTC init code assigns TCs consdecutively and | ||||
| 	 * in ascending order across available VPEs. | ||||
| 	 */ | ||||
| 	if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id)) | ||||
| 		write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); | ||||
| 
 | ||||
| 	printk("TC %d going on-line as CPU %d\n", | ||||
| 		cpu_data[smp_processor_id()].tc_id, smp_processor_id()); | ||||
| } | ||||
| @ -753,8 +776,10 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) | ||||
| { | ||||
| 	int tcstatus; | ||||
| 	struct smtc_ipi *pipi; | ||||
| 	long flags; | ||||
| 	unsigned long flags; | ||||
| 	int mtflags; | ||||
| 	unsigned long tcrestart; | ||||
| 	extern void r4k_wait_irqoff(void), __pastwait(void); | ||||
| 
 | ||||
| 	if (cpu == smp_processor_id()) { | ||||
| 		printk("Cannot Send IPI to self!\n"); | ||||
| @ -771,8 +796,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) | ||||
| 	pipi->arg = (void *)action; | ||||
| 	pipi->dest = cpu; | ||||
| 	if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||||
| 		if (type == SMTC_CLOCK_TICK) | ||||
| 			atomic_inc(&ipi_timer_latch[cpu]); | ||||
| 		/* If not on same VPE, enqueue and send cross-VPE interrupt */ | ||||
| 		smtc_ipi_nq(&IPIQ[cpu], pipi); | ||||
| 		LOCK_CORE_PRA(); | ||||
| @ -800,22 +823,29 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) | ||||
| 
 | ||||
| 		if ((tcstatus & TCSTATUS_IXMT) != 0) { | ||||
| 			/*
 | ||||
| 			 * Spin-waiting here can deadlock, | ||||
| 			 * so we queue the message for the target TC. | ||||
| 			 * If we're in the the irq-off version of the wait | ||||
| 			 * loop, we need to force exit from the wait and | ||||
| 			 * do a direct post of the IPI. | ||||
| 			 */ | ||||
| 			if (cpu_wait == r4k_wait_irqoff) { | ||||
| 				tcrestart = read_tc_c0_tcrestart(); | ||||
| 				if (tcrestart >= (unsigned long)r4k_wait_irqoff | ||||
| 				    && tcrestart < (unsigned long)__pastwait) { | ||||
| 					write_tc_c0_tcrestart(__pastwait); | ||||
| 					tcstatus &= ~TCSTATUS_IXMT; | ||||
| 					write_tc_c0_tcstatus(tcstatus); | ||||
| 					goto postdirect; | ||||
| 				} | ||||
| 			} | ||||
| 			/*
 | ||||
| 			 * Otherwise we queue the message for the target TC | ||||
| 			 * to pick up when he does a local_irq_restore() | ||||
| 			 */ | ||||
| 			write_tc_c0_tchalt(0); | ||||
| 			UNLOCK_CORE_PRA(); | ||||
| 			/* Try to reduce redundant timer interrupt messages */ | ||||
| 			if (type == SMTC_CLOCK_TICK) { | ||||
| 			    if (atomic_postincrement(&ipi_timer_latch[cpu])!=0){ | ||||
| 				smtc_ipi_nq(&freeIPIq, pipi); | ||||
| 				return; | ||||
| 			    } | ||||
| 			} | ||||
| 			smtc_ipi_nq(&IPIQ[cpu], pipi); | ||||
| 		} else { | ||||
| 			if (type == SMTC_CLOCK_TICK) | ||||
| 				atomic_inc(&ipi_timer_latch[cpu]); | ||||
| postdirect: | ||||
| 			post_direct_ipi(cpu, pipi); | ||||
| 			write_tc_c0_tchalt(0); | ||||
| 			UNLOCK_CORE_PRA(); | ||||
| @ -883,7 +913,7 @@ static void ipi_call_interrupt(void) | ||||
| 	smp_call_function_interrupt(); | ||||
| } | ||||
| 
 | ||||
| DECLARE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); | ||||
| DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); | ||||
| 
 | ||||
| void ipi_decode(struct smtc_ipi *pipi) | ||||
| { | ||||
| @ -891,20 +921,13 @@ void ipi_decode(struct smtc_ipi *pipi) | ||||
| 	struct clock_event_device *cd; | ||||
| 	void *arg_copy = pipi->arg; | ||||
| 	int type_copy = pipi->type; | ||||
| 	int ticks; | ||||
| 
 | ||||
| 	smtc_ipi_nq(&freeIPIq, pipi); | ||||
| 	switch (type_copy) { | ||||
| 	case SMTC_CLOCK_TICK: | ||||
| 		irq_enter(); | ||||
| 		kstat_this_cpu.irqs[MIPS_CPU_IRQ_BASE + 1]++; | ||||
| 		cd = &per_cpu(smtc_dummy_clockevent_device, cpu); | ||||
| 		ticks = atomic_read(&ipi_timer_latch[cpu]); | ||||
| 		atomic_sub(ticks, &ipi_timer_latch[cpu]); | ||||
| 		while (ticks) { | ||||
| 			cd->event_handler(cd); | ||||
| 			ticks--; | ||||
| 		} | ||||
| 		cd = &per_cpu(mips_clockevent_device, cpu); | ||||
| 		cd->event_handler(cd); | ||||
| 		irq_exit(); | ||||
| 		break; | ||||
| 
 | ||||
| @ -937,24 +960,48 @@ void ipi_decode(struct smtc_ipi *pipi) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Similar to smtc_ipi_replay(), but invoked from context restore, | ||||
|  * so it reuses the current exception frame rather than set up a | ||||
|  * new one with self_ipi. | ||||
|  */ | ||||
| 
 | ||||
| void deferred_smtc_ipi(void) | ||||
| { | ||||
| 	struct smtc_ipi *pipi; | ||||
| 	unsigned long flags; | ||||
| /* DEBUG */ | ||||
| 	int q = smp_processor_id(); | ||||
| 	int cpu = smp_processor_id(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Test is not atomic, but much faster than a dequeue, | ||||
| 	 * and the vast majority of invocations will have a null queue. | ||||
| 	 * If irq_disabled when this was called, then any IPIs queued | ||||
| 	 * after we test last will be taken on the next irq_enable/restore. | ||||
| 	 * If interrupts were enabled, then any IPIs added after the | ||||
| 	 * last test will be taken directly. | ||||
| 	 */ | ||||
| 	if (IPIQ[q].head != NULL) { | ||||
| 		while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) { | ||||
| 			/* ipi_decode() should be called with interrupts off */ | ||||
| 			local_irq_save(flags); | ||||
| 
 | ||||
| 	while (IPIQ[cpu].head != NULL) { | ||||
| 		struct smtc_ipi_q *q = &IPIQ[cpu]; | ||||
| 		struct smtc_ipi *pipi; | ||||
| 		unsigned long flags; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * It may be possible we'll come in with interrupts | ||||
| 		 * already enabled. | ||||
| 		 */ | ||||
| 		local_irq_save(flags); | ||||
| 
 | ||||
| 		spin_lock(&q->lock); | ||||
| 		pipi = __smtc_ipi_dq(q); | ||||
| 		spin_unlock(&q->lock); | ||||
| 		if (pipi != NULL) | ||||
| 			ipi_decode(pipi); | ||||
| 			local_irq_restore(flags); | ||||
| 		} | ||||
| 		/*
 | ||||
| 		 * The use of the __raw_local restore isn't | ||||
| 		 * as obviously necessary here as in smtc_ipi_replay(), | ||||
| 		 * but it's more efficient, given that we're already | ||||
| 		 * running down the IPI queue. | ||||
| 		 */ | ||||
| 		__raw_local_irq_restore(flags); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -975,7 +1022,7 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) | ||||
| 	struct smtc_ipi *pipi; | ||||
| 	unsigned long tcstatus; | ||||
| 	int sent; | ||||
| 	long flags; | ||||
| 	unsigned long flags; | ||||
| 	unsigned int mtflags; | ||||
| 	unsigned int vpflags; | ||||
| 
 | ||||
| @ -1066,55 +1113,53 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe) | ||||
| 
 | ||||
| /*
 | ||||
|  * SMTC-specific hacks invoked from elsewhere in the kernel. | ||||
|  * | ||||
|  * smtc_ipi_replay is called from raw_local_irq_restore which is only ever | ||||
|  * called with interrupts disabled.  We do rely on interrupts being disabled | ||||
|  * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would | ||||
|  * result in a recursive call to raw_local_irq_restore(). | ||||
|  */ | ||||
| 
 | ||||
| static void __smtc_ipi_replay(void) | ||||
|  /*
 | ||||
|   * smtc_ipi_replay is called from raw_local_irq_restore | ||||
|   */ | ||||
| 
 | ||||
| void smtc_ipi_replay(void) | ||||
| { | ||||
| 	unsigned int cpu = smp_processor_id(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * To the extent that we've ever turned interrupts off, | ||||
| 	 * we may have accumulated deferred IPIs.  This is subtle. | ||||
| 	 * If we use the smtc_ipi_qdepth() macro, we'll get an | ||||
| 	 * exact number - but we'll also disable interrupts | ||||
| 	 * and create a window of failure where a new IPI gets | ||||
| 	 * queued after we test the depth but before we re-enable | ||||
| 	 * interrupts. So long as IXMT never gets set, however, | ||||
| 	 * we should be OK:  If we pick up something and dispatch | ||||
| 	 * it here, that's great. If we see nothing, but concurrent | ||||
| 	 * with this operation, another TC sends us an IPI, IXMT | ||||
| 	 * is clear, and we'll handle it as a real pseudo-interrupt | ||||
| 	 * and not a pseudo-pseudo interrupt. | ||||
| 	 * and not a pseudo-pseudo interrupt.  The important thing | ||||
| 	 * is to do the last check for queued message *after* the | ||||
| 	 * re-enabling of interrupts. | ||||
| 	 */ | ||||
| 	if (IPIQ[cpu].depth > 0) { | ||||
| 		while (1) { | ||||
| 			struct smtc_ipi_q *q = &IPIQ[cpu]; | ||||
| 			struct smtc_ipi *pipi; | ||||
| 			extern void self_ipi(struct smtc_ipi *); | ||||
| 	while (IPIQ[cpu].head != NULL) { | ||||
| 		struct smtc_ipi_q *q = &IPIQ[cpu]; | ||||
| 		struct smtc_ipi *pipi; | ||||
| 		unsigned long flags; | ||||
| 
 | ||||
| 			spin_lock(&q->lock); | ||||
| 			pipi = __smtc_ipi_dq(q); | ||||
| 			spin_unlock(&q->lock); | ||||
| 			if (!pipi) | ||||
| 				break; | ||||
| 		/*
 | ||||
| 		 * It's just possible we'll come in with interrupts | ||||
| 		 * already enabled. | ||||
| 		 */ | ||||
| 		local_irq_save(flags); | ||||
| 
 | ||||
| 		spin_lock(&q->lock); | ||||
| 		pipi = __smtc_ipi_dq(q); | ||||
| 		spin_unlock(&q->lock); | ||||
| 		/*
 | ||||
| 		 ** But use a raw restore here to avoid recursion. | ||||
| 		 */ | ||||
| 		__raw_local_irq_restore(flags); | ||||
| 
 | ||||
| 		if (pipi) { | ||||
| 			self_ipi(pipi); | ||||
| 			smtc_cpu_stats[cpu].selfipis++; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void smtc_ipi_replay(void) | ||||
| { | ||||
| 	raw_local_irq_disable(); | ||||
| 	__smtc_ipi_replay(); | ||||
| } | ||||
| 
 | ||||
| EXPORT_SYMBOL(smtc_ipi_replay); | ||||
| 
 | ||||
| void smtc_idle_loop_hook(void) | ||||
| @ -1193,40 +1238,13 @@ void smtc_idle_loop_hook(void) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Now that we limit outstanding timer IPIs, check for hung TC | ||||
| 	 */ | ||||
| 	for (tc = 0; tc < NR_CPUS; tc++) { | ||||
| 		/* Don't check ourself - we'll dequeue IPIs just below */ | ||||
| 		if ((tc != smp_processor_id()) && | ||||
| 		    atomic_read(&ipi_timer_latch[tc]) > timerq_limit) { | ||||
| 		    if (clock_hang_reported[tc] == 0) { | ||||
| 			pdb_msg += sprintf(pdb_msg, | ||||
| 				"TC %d looks hung with timer latch at %d\n", | ||||
| 				tc, atomic_read(&ipi_timer_latch[tc])); | ||||
| 			clock_hang_reported[tc]++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	emt(mtflags); | ||||
| 	local_irq_restore(flags); | ||||
| 	if (pdb_msg != &id_ho_db_msg[0]) | ||||
| 		printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); | ||||
| #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Replay any accumulated deferred IPIs. If "Instant Replay" | ||||
| 	 * is in use, there should never be any. | ||||
| 	 */ | ||||
| #ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY | ||||
| 	{ | ||||
| 		unsigned long flags; | ||||
| 
 | ||||
| 		local_irq_save(flags); | ||||
| 		__smtc_ipi_replay(); | ||||
| 		local_irq_restore(flags); | ||||
| 	} | ||||
| #endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ | ||||
| 	smtc_ipi_replay(); | ||||
| } | ||||
| 
 | ||||
| void smtc_soft_dump(void) | ||||
| @ -1242,10 +1260,6 @@ void smtc_soft_dump(void) | ||||
| 		printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis); | ||||
| 	} | ||||
| 	smtc_ipi_qdump(); | ||||
| 	printk("Timer IPI Backlogs:\n"); | ||||
| 	for (i=0; i < NR_CPUS; i++) { | ||||
| 		printk("%d: %d\n", i, atomic_read(&ipi_timer_latch[i])); | ||||
| 	} | ||||
| 	printk("%d Recoveries of \"stolen\" FPU\n", | ||||
| 	       atomic_read(&smtc_fpu_recoveries)); | ||||
| } | ||||
|  | ||||
| @ -825,8 +825,10 @@ static void mt_ase_fp_affinity(void) | ||||
| 		if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) { | ||||
| 			cpumask_t tmask; | ||||
| 
 | ||||
| 			cpus_and(tmask, current->thread.user_cpus_allowed, | ||||
| 			         mt_fpu_cpumask); | ||||
| 			current->thread.user_cpus_allowed | ||||
| 				= current->cpus_allowed; | ||||
| 			cpus_and(tmask, current->cpus_allowed, | ||||
| 				mt_fpu_cpumask); | ||||
| 			set_cpus_allowed(current, tmask); | ||||
| 			set_thread_flag(TIF_FPUBOUND); | ||||
| 		} | ||||
|  | ||||
| @ -15,6 +15,6 @@ obj-$(CONFIG_EARLY_PRINTK)	+= malta-console.o | ||||
| obj-$(CONFIG_PCI)		+= malta-pci.o | ||||
| 
 | ||||
| # FIXME FIXME FIXME
 | ||||
| obj-$(CONFIG_MIPS_MT_SMTC)	+= malta_smtc.o | ||||
| obj-$(CONFIG_MIPS_MT_SMTC)	+= malta-smtc.o | ||||
| 
 | ||||
| EXTRA_CFLAGS += -Werror | ||||
|  | ||||
| @ -84,12 +84,17 @@ static void msmtc_cpus_done(void) | ||||
| 
 | ||||
| static void __init msmtc_smp_setup(void) | ||||
| { | ||||
| 	mipsmt_build_cpu_map(0); | ||||
| 	/*
 | ||||
| 	 * we won't get the definitive value until | ||||
| 	 * we've run smtc_prepare_cpus later, but | ||||
| 	 * we would appear to need an upper bound now. | ||||
| 	 */ | ||||
| 	smp_num_siblings = smtc_build_cpu_map(0); | ||||
| } | ||||
| 
 | ||||
| static void __init msmtc_prepare_cpus(unsigned int max_cpus) | ||||
| { | ||||
| 	mipsmt_prepare_cpus(); | ||||
| 	smtc_prepare_cpus(max_cpus); | ||||
| } | ||||
| 
 | ||||
| struct plat_smp_ops msmtc_smp_ops = { | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| obj-y				:= setup.o rtc_xicor1241.o rtc_m41t81.o | ||||
| obj-y				:= platform.o setup.o rtc_xicor1241.o \
 | ||||
| 				   rtc_m41t81.o | ||||
| 
 | ||||
| obj-$(CONFIG_I2C_BOARDINFO)	+= swarm-i2c.o | ||||
|  | ||||
							
								
								
									
										85
									
								
								arch/mips/sibyte/swarm/platform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								arch/mips/sibyte/swarm/platform.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | ||||
| #include <linux/err.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/ata_platform.h> | ||||
| 
 | ||||
| #include <asm/sibyte/board.h> | ||||
| #include <asm/sibyte/sb1250_genbus.h> | ||||
| #include <asm/sibyte/sb1250_regs.h> | ||||
| 
 | ||||
| #if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) | ||||
| 
 | ||||
| #define DRV_NAME	"pata-swarm" | ||||
| 
 | ||||
| #define SWARM_IDE_SHIFT	5 | ||||
| #define SWARM_IDE_BASE	0x1f0 | ||||
| #define SWARM_IDE_CTRL	0x3f6 | ||||
| 
 | ||||
| static struct resource swarm_pata_resource[] = { | ||||
| 	{ | ||||
| 		.name	= "Swarm GenBus IDE", | ||||
| 		.flags	= IORESOURCE_MEM, | ||||
| 	}, { | ||||
| 		.name	= "Swarm GenBus IDE", | ||||
| 		.flags	= IORESOURCE_MEM, | ||||
| 	}, { | ||||
| 		.name	= "Swarm GenBus IDE", | ||||
| 		.flags	= IORESOURCE_IRQ, | ||||
| 		.start	= K_INT_GB_IDE, | ||||
| 		.end	= K_INT_GB_IDE, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct pata_platform_info pata_platform_data = { | ||||
| 	.ioport_shift	= SWARM_IDE_SHIFT, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device swarm_pata_device = { | ||||
| 	.name		= "pata_platform", | ||||
| 	.id		= -1, | ||||
| 	.resource	= swarm_pata_resource, | ||||
| 	.num_resources	= ARRAY_SIZE(swarm_pata_resource), | ||||
| 	.dev  = { | ||||
| 		.platform_data		= &pata_platform_data, | ||||
| 		.coherent_dma_mask	= ~0,	/* grumble */ | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static int __init swarm_pata_init(void) | ||||
| { | ||||
| 	u8 __iomem *base; | ||||
| 	phys_t offset, size; | ||||
| 	struct resource *r; | ||||
| 
 | ||||
| 	if (!SIBYTE_HAVE_IDE) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	base = ioremap(A_IO_EXT_BASE, 0x800); | ||||
| 	offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); | ||||
| 	size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); | ||||
| 	iounmap(base); | ||||
| 
 | ||||
| 	offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE; | ||||
| 	size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE; | ||||
| 	if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) { | ||||
| 		pr_info(DRV_NAME ": PATA interface at GenBus disabled\n"); | ||||
| 
 | ||||
| 		return -EBUSY; | ||||
| 	} | ||||
| 
 | ||||
| 	pr_info(DRV_NAME ": PATA interface at GenBus slot %i\n", IDE_CS); | ||||
| 
 | ||||
| 	r = swarm_pata_resource; | ||||
| 	r[0].start = offset + (SWARM_IDE_BASE << SWARM_IDE_SHIFT); | ||||
| 	r[0].end   = offset + ((SWARM_IDE_BASE + 8) << SWARM_IDE_SHIFT) - 1; | ||||
| 	r[1].start = offset + (SWARM_IDE_CTRL << SWARM_IDE_SHIFT); | ||||
| 	r[1].end   = offset + ((SWARM_IDE_CTRL + 1) << SWARM_IDE_SHIFT) - 1; | ||||
| 
 | ||||
| 	return platform_device_register(&swarm_pata_device); | ||||
| } | ||||
| 
 | ||||
| device_initcall(swarm_pata_init); | ||||
| 
 | ||||
| #endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) */ | ||||
| @ -20,22 +20,8 @@ EXPORT_SYMBOL(__mn10300_irq_enabled_epsw); | ||||
| atomic_t irq_err_count; | ||||
| 
 | ||||
| /*
 | ||||
|  * MN10300 INTC controller operations | ||||
|  * MN10300 interrupt controller operations | ||||
|  */ | ||||
| static void mn10300_cpupic_disable(unsigned int irq) | ||||
| { | ||||
| 	u16 tmp = GxICR(irq); | ||||
| 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT; | ||||
| 	tmp = GxICR(irq); | ||||
| } | ||||
| 
 | ||||
| static void mn10300_cpupic_enable(unsigned int irq) | ||||
| { | ||||
| 	u16 tmp = GxICR(irq); | ||||
| 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE; | ||||
| 	tmp = GxICR(irq); | ||||
| } | ||||
| 
 | ||||
| static void mn10300_cpupic_ack(unsigned int irq) | ||||
| { | ||||
| 	u16 tmp; | ||||
| @ -58,28 +44,56 @@ static void mn10300_cpupic_mask_ack(unsigned int irq) | ||||
| } | ||||
| 
 | ||||
| static void mn10300_cpupic_unmask(unsigned int irq) | ||||
| { | ||||
| 	u16 tmp = GxICR(irq); | ||||
| 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; | ||||
| 	tmp = GxICR(irq); | ||||
| } | ||||
| 
 | ||||
| static void mn10300_cpupic_end(unsigned int irq) | ||||
| { | ||||
| 	u16 tmp = GxICR(irq); | ||||
| 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE; | ||||
| 	tmp = GxICR(irq); | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip mn10300_cpu_pic = { | ||||
| 	.name		= "cpu", | ||||
| 	.disable	= mn10300_cpupic_disable, | ||||
| 	.enable		= mn10300_cpupic_enable, | ||||
| static void mn10300_cpupic_unmask_clear(unsigned int irq) | ||||
| { | ||||
| 	/* the MN10300 PIC latches its interrupt request bit, even after the
 | ||||
| 	 * device has ceased to assert its interrupt line and the interrupt | ||||
| 	 * channel has been disabled in the PIC, so for level-triggered | ||||
| 	 * interrupts we need to clear the request bit when we re-enable */ | ||||
| 	u16 tmp = GxICR(irq); | ||||
| 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; | ||||
| 	tmp = GxICR(irq); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * MN10300 PIC level-triggered IRQ handling. | ||||
|  * | ||||
|  * The PIC has no 'ACK' function per se.  It is possible to clear individual | ||||
|  * channel latches, but each latch relatches whether or not the channel is | ||||
|  * masked, so we need to clear the latch when we unmask the channel. | ||||
|  * | ||||
|  * Also for this reason, we don't supply an ack() op (it's unused anyway if | ||||
|  * mask_ack() is provided), and mask_ack() just masks. | ||||
|  */ | ||||
| static struct irq_chip mn10300_cpu_pic_level = { | ||||
| 	.name		= "cpu_l", | ||||
| 	.disable	= mn10300_cpupic_mask, | ||||
| 	.enable		= mn10300_cpupic_unmask_clear, | ||||
| 	.ack		= NULL, | ||||
| 	.mask		= mn10300_cpupic_mask, | ||||
| 	.mask_ack	= mn10300_cpupic_mask, | ||||
| 	.unmask		= mn10300_cpupic_unmask_clear, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * MN10300 PIC edge-triggered IRQ handling. | ||||
|  * | ||||
|  * We use the latch clearing function of the PIC as the 'ACK' function. | ||||
|  */ | ||||
| static struct irq_chip mn10300_cpu_pic_edge = { | ||||
| 	.name		= "cpu_e", | ||||
| 	.disable	= mn10300_cpupic_mask, | ||||
| 	.enable		= mn10300_cpupic_unmask, | ||||
| 	.ack		= mn10300_cpupic_ack, | ||||
| 	.mask		= mn10300_cpupic_mask, | ||||
| 	.mask_ack	= mn10300_cpupic_mask_ack, | ||||
| 	.unmask		= mn10300_cpupic_unmask, | ||||
| 	.end		= mn10300_cpupic_end, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
| @ -114,7 +128,8 @@ void set_intr_level(int irq, u16 level) | ||||
|  */ | ||||
| void set_intr_postackable(int irq) | ||||
| { | ||||
| 	set_irq_handler(irq, handle_level_irq); | ||||
| 	set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level, | ||||
| 				 handle_level_irq); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
| @ -126,8 +141,12 @@ void __init init_IRQ(void) | ||||
| 
 | ||||
| 	for (irq = 0; irq < NR_IRQS; irq++) | ||||
| 		if (irq_desc[irq].chip == &no_irq_type) | ||||
| 			set_irq_chip_and_handler(irq, &mn10300_cpu_pic, | ||||
| 						 handle_edge_irq); | ||||
| 			/* due to the PIC latching interrupt requests, even
 | ||||
| 			 * when the IRQ is disabled, IRQ_PENDING is superfluous | ||||
| 			 * and we can use handle_level_irq() for edge-triggered | ||||
| 			 * interrupts */ | ||||
| 			set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge, | ||||
| 						 handle_level_irq); | ||||
| 	unit_init_IRQ(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -51,7 +51,7 @@ void __init unit_init_IRQ(void) | ||||
| 		switch (GET_XIRQ_TRIGGER(extnum)) { | ||||
| 		case XIRQ_TRIGGER_HILEVEL: | ||||
| 		case XIRQ_TRIGGER_LOWLEVEL: | ||||
| 			set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq); | ||||
| 			set_intr_postackable(XIRQ2IRQ(extnum)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
|  | ||||
| @ -52,7 +52,7 @@ void __init unit_init_IRQ(void) | ||||
| 		switch (GET_XIRQ_TRIGGER(extnum)) { | ||||
| 		case XIRQ_TRIGGER_HILEVEL: | ||||
| 		case XIRQ_TRIGGER_LOWLEVEL: | ||||
| 			set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq); | ||||
| 			set_intr_postackable(XIRQ2IRQ(extnum)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
|  | ||||
| @ -133,61 +133,61 @@ | ||||
| 			reg = <0x00007400 0x00000400>; | ||||
| 			big-endian; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 		pci@1000 { | ||||
| 			device_type = "pci"; | ||||
| 			compatible = "tsi109-pci", "tsi108-pci"; | ||||
| 			#interrupt-cells = <1>; | ||||
| 			#size-cells = <2>; | ||||
| 			#address-cells = <3>; | ||||
| 			reg = <0x00001000 0x00001000>; | ||||
| 			bus-range = <0x0 0x0>; | ||||
| 			/*----------------------------------------------------+ | ||||
| 			| PCI memory range. | ||||
| 			| 01 denotes I/O space | ||||
| 			| 02 denotes 32-bit memory space | ||||
| 			+----------------------------------------------------*/ | ||||
| 			ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000 | ||||
| 				  0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>; | ||||
| 			clock-frequency = <133333332>; | ||||
| 			interrupt-parent = <&MPIC>; | ||||
| 	pci@c0001000 { | ||||
| 		device_type = "pci"; | ||||
| 		compatible = "tsi109-pci", "tsi108-pci"; | ||||
| 		#interrupt-cells = <1>; | ||||
| 		#size-cells = <2>; | ||||
| 		#address-cells = <3>; | ||||
| 		reg = <0xc0001000 0x00001000>; | ||||
| 		bus-range = <0x0 0x0>; | ||||
| 		/*----------------------------------------------------+ | ||||
| 		| PCI memory range. | ||||
| 		| 01 denotes I/O space | ||||
| 		| 02 denotes 32-bit memory space | ||||
| 		+----------------------------------------------------*/ | ||||
| 		ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000 | ||||
| 			  0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>; | ||||
| 		clock-frequency = <133333332>; | ||||
| 		interrupt-parent = <&MPIC>; | ||||
| 		interrupts = <0x17 0x2>; | ||||
| 		interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||||
| 		/*----------------------------------------------------+ | ||||
| 		| The INTA, INTB, INTC, INTD are shared. | ||||
| 		+----------------------------------------------------*/ | ||||
| 		interrupt-map = < | ||||
| 			0x800 0x0 0x0 0x1 &RT0 0x24 0x0 | ||||
| 			0x800 0x0 0x0 0x2 &RT0 0x25 0x0 | ||||
| 			0x800 0x0 0x0 0x3 &RT0 0x26 0x0 | ||||
| 			0x800 0x0 0x0 0x4 &RT0 0x27 0x0 | ||||
| 
 | ||||
| 			0x1000 0x0 0x0 0x1 &RT0 0x25 0x0 | ||||
| 			0x1000 0x0 0x0 0x2 &RT0 0x26 0x0 | ||||
| 			0x1000 0x0 0x0 0x3 &RT0 0x27 0x0 | ||||
| 			0x1000 0x0 0x0 0x4 &RT0 0x24 0x0 | ||||
| 
 | ||||
| 			0x1800 0x0 0x0 0x1 &RT0 0x26 0x0 | ||||
| 			0x1800 0x0 0x0 0x2 &RT0 0x27 0x0 | ||||
| 			0x1800 0x0 0x0 0x3 &RT0 0x24 0x0 | ||||
| 			0x1800 0x0 0x0 0x4 &RT0 0x25 0x0 | ||||
| 
 | ||||
| 			0x2000 0x0 0x0 0x1 &RT0 0x27 0x0 | ||||
| 			0x2000 0x0 0x0 0x2 &RT0 0x24 0x0 | ||||
| 			0x2000 0x0 0x0 0x3 &RT0 0x25 0x0 | ||||
| 			0x2000 0x0 0x0 0x4 &RT0 0x26 0x0 | ||||
| 			>; | ||||
| 
 | ||||
| 		RT0: router@1180 { | ||||
| 			device_type = "pic-router"; | ||||
| 			interrupt-controller; | ||||
| 			big-endian; | ||||
| 			clock-frequency = <0>; | ||||
| 			#address-cells = <0>; | ||||
| 			#interrupt-cells = <2>; | ||||
| 			interrupts = <0x17 0x2>; | ||||
| 			interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||||
| 			/*----------------------------------------------------+ | ||||
| 			| The INTA, INTB, INTC, INTD are shared. | ||||
| 			+----------------------------------------------------*/ | ||||
| 			interrupt-map = < | ||||
| 				0x800 0x0 0x0 0x1 &RT0 0x24 0x0 | ||||
| 				0x800 0x0 0x0 0x2 &RT0 0x25 0x0 | ||||
| 				0x800 0x0 0x0 0x3 &RT0 0x26 0x0 | ||||
| 				0x800 0x0 0x0 0x4 &RT0 0x27 0x0 | ||||
| 
 | ||||
| 				0x1000 0x0 0x0 0x1 &RT0 0x25 0x0 | ||||
| 				0x1000 0x0 0x0 0x2 &RT0 0x26 0x0 | ||||
| 				0x1000 0x0 0x0 0x3 &RT0 0x27 0x0 | ||||
| 				0x1000 0x0 0x0 0x4 &RT0 0x24 0x0 | ||||
| 
 | ||||
| 				0x1800 0x0 0x0 0x1 &RT0 0x26 0x0 | ||||
| 				0x1800 0x0 0x0 0x2 &RT0 0x27 0x0 | ||||
| 				0x1800 0x0 0x0 0x3 &RT0 0x24 0x0 | ||||
| 				0x1800 0x0 0x0 0x4 &RT0 0x25 0x0 | ||||
| 
 | ||||
| 				0x2000 0x0 0x0 0x1 &RT0 0x27 0x0 | ||||
| 				0x2000 0x0 0x0 0x2 &RT0 0x24 0x0 | ||||
| 				0x2000 0x0 0x0 0x3 &RT0 0x25 0x0 | ||||
| 				0x2000 0x0 0x0 0x4 &RT0 0x26 0x0 | ||||
| 				>; | ||||
| 
 | ||||
| 			RT0: router@1180 { | ||||
|  				device_type = "pic-router"; | ||||
|  				interrupt-controller; | ||||
|  				big-endian; | ||||
|  				clock-frequency = <0>; | ||||
|  				#address-cells = <0>; | ||||
|  				#interrupt-cells = <2>; | ||||
|  				interrupts = <0x17 0x2>; | ||||
| 				interrupt-parent = <&MPIC>; | ||||
| 			}; | ||||
| 			interrupt-parent = <&MPIC>; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
|  | ||||
| @ -34,11 +34,7 @@ | ||||
| #include <asm/smp.h> | ||||
| 
 | ||||
| #ifdef CONFIG_HOTPLUG_CPU | ||||
| /* this is used for software suspend, and that shuts down
 | ||||
|  * CPUs even while the system is still booting... */ | ||||
| #define cpu_should_die()	(cpu_is_offline(smp_processor_id()) && \ | ||||
| 				   (system_state == SYSTEM_RUNNING     \ | ||||
| 				 || system_state == SYSTEM_BOOTING)) | ||||
| #define cpu_should_die()	cpu_is_offline(smp_processor_id()) | ||||
| #else | ||||
| #define cpu_should_die()	0 | ||||
| #endif | ||||
|  | ||||
| @ -219,11 +219,21 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev) | ||||
| 	int i; | ||||
| 	u8 *dummy; | ||||
| 	struct pci_bus *bus = dev->bus; | ||||
| 	resource_size_t end = 0; | ||||
| 
 | ||||
| 	for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) { | ||||
| 		unsigned long flags = pci_resource_flags(dev, i); | ||||
| 		if ((flags & (IORESOURCE_MEM|IORESOURCE_PREFETCH)) == IORESOURCE_MEM) | ||||
| 			end = pci_resource_end(dev, i); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | ||||
| 		if ((bus->resource[i]) && | ||||
| 			(bus->resource[i]->flags & IORESOURCE_MEM)) { | ||||
| 			dummy = ioremap(bus->resource[i]->end - 3, 0x4); | ||||
| 			if (bus->resource[i]->end == end) | ||||
| 				dummy = ioremap(bus->resource[i]->start, 0x4); | ||||
| 			else | ||||
| 				dummy = ioremap(bus->resource[i]->end - 3, 0x4); | ||||
| 			if (dummy) { | ||||
| 				in_8(dummy); | ||||
| 				iounmap(dummy); | ||||
|  | ||||
| @ -169,6 +169,8 @@ void init_cpu_timer(void) | ||||
| 
 | ||||
| static void clock_comparator_interrupt(__u16 code) | ||||
| { | ||||
| 	if (S390_lowcore.clock_comparator == -1ULL) | ||||
| 		set_clock_comparator(S390_lowcore.clock_comparator); | ||||
| } | ||||
| 
 | ||||
| static void etr_timing_alert(struct etr_irq_parm *); | ||||
|  | ||||
| @ -1,14 +1,9 @@ | ||||
| /*
 | ||||
|  *  arch/s390/lib/delay.c | ||||
|  *    Precise Delay Loops for S390 | ||||
|  * | ||||
|  *  S390 version | ||||
|  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||||
|  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||||
|  * | ||||
|  *  Derived from "arch/i386/lib/delay.c" | ||||
|  *    Copyright (C) 1993 Linus Torvalds | ||||
|  *    Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||||
|  *    Copyright IBM Corp. 1999,2008 | ||||
|  *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||||
|  *		 Heiko Carstens <heiko.carstens@de.ibm.com>, | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/sched.h> | ||||
| @ -29,30 +24,31 @@ void __delay(unsigned long loops) | ||||
| 	asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Waits for 'usecs' microseconds using the TOD clock comparator. | ||||
|  */ | ||||
| void __udelay(unsigned long usecs) | ||||
| static void __udelay_disabled(unsigned long usecs) | ||||
| { | ||||
| 	u64 end, time, old_cc = 0; | ||||
| 	unsigned long flags, cr0, mask, dummy; | ||||
| 	int irq_context; | ||||
| 	unsigned long mask, cr0, cr0_saved; | ||||
| 	u64 clock_saved; | ||||
| 
 | ||||
| 	irq_context = in_interrupt(); | ||||
| 	if (!irq_context) | ||||
| 		local_bh_disable(); | ||||
| 	local_irq_save(flags); | ||||
| 	if (raw_irqs_disabled_flags(flags)) { | ||||
| 		old_cc = local_tick_disable(); | ||||
| 		S390_lowcore.clock_comparator = -1ULL; | ||||
| 		__ctl_store(cr0, 0, 0); | ||||
| 		dummy = (cr0 & 0xffff00e0) | 0x00000800; | ||||
| 		__ctl_load(dummy , 0, 0); | ||||
| 		mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; | ||||
| 	} else | ||||
| 		mask = psw_kernel_bits | PSW_MASK_WAIT | | ||||
| 			PSW_MASK_EXT | PSW_MASK_IO; | ||||
| 	clock_saved = local_tick_disable(); | ||||
| 	set_clock_comparator(get_clock() + ((u64) usecs << 12)); | ||||
| 	__ctl_store(cr0_saved, 0, 0); | ||||
| 	cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; | ||||
| 	__ctl_load(cr0 , 0, 0); | ||||
| 	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; | ||||
| 	trace_hardirqs_on(); | ||||
| 	__load_psw_mask(mask); | ||||
| 	local_irq_disable(); | ||||
| 	__ctl_load(cr0_saved, 0, 0); | ||||
| 	local_tick_enable(clock_saved); | ||||
| 	set_clock_comparator(S390_lowcore.clock_comparator); | ||||
| } | ||||
| 
 | ||||
| static void __udelay_enabled(unsigned long usecs) | ||||
| { | ||||
| 	unsigned long mask; | ||||
| 	u64 end, time; | ||||
| 
 | ||||
| 	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; | ||||
| 	end = get_clock() + ((u64) usecs << 12); | ||||
| 	do { | ||||
| 		time = end < S390_lowcore.clock_comparator ? | ||||
| @ -62,13 +58,37 @@ void __udelay(unsigned long usecs) | ||||
| 		__load_psw_mask(mask); | ||||
| 		local_irq_disable(); | ||||
| 	} while (get_clock() < end); | ||||
| 
 | ||||
| 	if (raw_irqs_disabled_flags(flags)) { | ||||
| 		__ctl_load(cr0, 0, 0); | ||||
| 		local_tick_enable(old_cc); | ||||
| 	} | ||||
| 	if (!irq_context) | ||||
| 		_local_bh_enable(); | ||||
| 	set_clock_comparator(S390_lowcore.clock_comparator); | ||||
| 	local_irq_restore(flags); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Waits for 'usecs' microseconds using the TOD clock comparator. | ||||
|  */ | ||||
| void __udelay(unsigned long usecs) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	preempt_disable(); | ||||
| 	local_irq_save(flags); | ||||
| 	if (in_irq()) { | ||||
| 		__udelay_disabled(usecs); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if (in_softirq()) { | ||||
| 		if (raw_irqs_disabled_flags(flags)) | ||||
| 			__udelay_disabled(usecs); | ||||
| 		else | ||||
| 			__udelay_enabled(usecs); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if (raw_irqs_disabled_flags(flags)) { | ||||
| 		local_bh_disable(); | ||||
| 		__udelay_disabled(usecs); | ||||
| 		_local_bh_enable(); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	__udelay_enabled(usecs); | ||||
| out: | ||||
| 	local_irq_restore(flags); | ||||
| 	preempt_enable(); | ||||
| } | ||||
|  | ||||
| @ -492,7 +492,7 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) | ||||
| 			continue; | ||||
| 		} | ||||
| 		sh_symtab = sec_symtab->symtab; | ||||
| 		sym_strtab = sec->link->strtab; | ||||
| 		sym_strtab = sec_symtab->link->strtab; | ||||
| 		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { | ||||
| 			Elf32_Rel *rel; | ||||
| 			Elf32_Sym *sym; | ||||
|  | ||||
| @ -1603,6 +1603,14 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | ||||
| 	 * is not connected at all.  Force ignoring BIOS IRQ0 pin2 | ||||
| 	 * override in that cases. | ||||
| 	 */ | ||||
| 	{ | ||||
| 	 .callback = dmi_ignore_irq0_timer_override, | ||||
| 	 .ident = "HP nx6115 laptop", | ||||
| 	 .matches = { | ||||
| 		     DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||||
| 		     DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6115"), | ||||
| 		     }, | ||||
| 	 }, | ||||
| 	{ | ||||
| 	 .callback = dmi_ignore_irq0_timer_override, | ||||
| 	 .ident = "HP NX6125 laptop", | ||||
| @ -1619,6 +1627,14 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | ||||
| 		     DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), | ||||
| 		     }, | ||||
| 	 }, | ||||
| 	{ | ||||
| 	 .callback = dmi_ignore_irq0_timer_override, | ||||
| 	 .ident = "HP 6715b laptop", | ||||
| 	 .matches = { | ||||
| 		     DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||||
| 		     DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), | ||||
| 		     }, | ||||
| 	 }, | ||||
| 	{} | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -834,7 +834,7 @@ static int __init enable_mtrr_cleanup_setup(char *str) | ||||
| 		enable_mtrr_cleanup = 1; | ||||
| 	return 0; | ||||
| } | ||||
| early_param("enble_mtrr_cleanup", enable_mtrr_cleanup_setup); | ||||
| early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup); | ||||
| 
 | ||||
| struct var_mtrr_state { | ||||
| 	unsigned long	range_startk; | ||||
|  | ||||
| @ -455,12 +455,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | ||||
| 		return NOTIFY_DONE; | ||||
| 
 | ||||
| 	case DIE_NMI_IPI: | ||||
| 		if (atomic_read(&kgdb_active) != -1) { | ||||
| 			/* KGDB CPU roundup */ | ||||
| 			kgdb_nmicallback(raw_smp_processor_id(), regs); | ||||
| 			was_in_debug_nmi[raw_smp_processor_id()] = 1; | ||||
| 			touch_nmi_watchdog(); | ||||
| 		} | ||||
| 		/* Just ignore, we will handle the roundup on DIE_NMI. */ | ||||
| 		return NOTIFY_DONE; | ||||
| 
 | ||||
| 	case DIE_NMIUNKNOWN: | ||||
|  | ||||
| @ -626,7 +626,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | ||||
| 	struct pci_dev *dev; | ||||
| 	void *gatt; | ||||
| 	int i, error; | ||||
| 	unsigned long start_pfn, end_pfn; | ||||
| 
 | ||||
| 	printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); | ||||
| 	aper_size = aper_base = info->aper_size = 0; | ||||
| @ -672,12 +671,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | ||||
| 	printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", | ||||
| 	       aper_base, aper_size>>10); | ||||
| 
 | ||||
| 	/* need to map that range */ | ||||
| 	end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT); | ||||
| 	if (end_pfn > max_low_pfn_mapped) { | ||||
| 		start_pfn = (aper_base>>PAGE_SHIFT); | ||||
| 		init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); | ||||
| 	} | ||||
| 	return 0; | ||||
| 
 | ||||
|  nommu: | ||||
| @ -727,7 +720,8 @@ void __init gart_iommu_init(void) | ||||
| { | ||||
| 	struct agp_kern_info info; | ||||
| 	unsigned long iommu_start; | ||||
| 	unsigned long aper_size; | ||||
| 	unsigned long aper_base, aper_size; | ||||
| 	unsigned long start_pfn, end_pfn; | ||||
| 	unsigned long scratch; | ||||
| 	long i; | ||||
| 
 | ||||
| @ -765,8 +759,16 @@ void __init gart_iommu_init(void) | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* need to map that range */ | ||||
| 	aper_size = info.aper_size << 20; | ||||
| 	aper_base = info.aper_base; | ||||
| 	end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT); | ||||
| 	if (end_pfn > max_low_pfn_mapped) { | ||||
| 		start_pfn = (aper_base>>PAGE_SHIFT); | ||||
| 		init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); | ||||
| 	aper_size = info.aper_size * 1024 * 1024; | ||||
| 	iommu_size = check_iommu_size(info.aper_base, aper_size); | ||||
| 	iommu_pages = iommu_size >> PAGE_SHIFT; | ||||
| 
 | ||||
|  | ||||
| @ -235,7 +235,7 @@ static void vmi_write_ldt_entry(struct desc_struct *dt, int entry, | ||||
| 				const void *desc) | ||||
| { | ||||
| 	u32 *ldt_entry = (u32 *)desc; | ||||
| 	vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]); | ||||
| 	vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]); | ||||
| } | ||||
| 
 | ||||
| static void vmi_load_sp0(struct tss_struct *tss, | ||||
|  | ||||
| @ -376,6 +376,8 @@ int braille_register_console(struct console *console, int index, | ||||
| 	console->flags |= CON_ENABLED; | ||||
| 	console->index = index; | ||||
| 	braille_co = console; | ||||
| 	register_keyboard_notifier(&keyboard_notifier_block); | ||||
| 	register_vt_notifier(&vt_notifier_block); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -383,15 +385,8 @@ int braille_unregister_console(struct console *console) | ||||
| { | ||||
| 	if (braille_co != console) | ||||
| 		return -EINVAL; | ||||
| 	unregister_keyboard_notifier(&keyboard_notifier_block); | ||||
| 	unregister_vt_notifier(&vt_notifier_block); | ||||
| 	braille_co = NULL; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int __init braille_init(void) | ||||
| { | ||||
| 	register_keyboard_notifier(&keyboard_notifier_block); | ||||
| 	register_vt_notifier(&vt_notifier_block); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| console_initcall(braille_init); | ||||
|  | ||||
| @ -165,8 +165,11 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | ||||
| 				"firmware_node"); | ||||
| 		ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | ||||
| 				"physical_node"); | ||||
| 		if (acpi_dev->wakeup.flags.valid) | ||||
| 		if (acpi_dev->wakeup.flags.valid) { | ||||
| 			device_set_wakeup_capable(dev, true); | ||||
| 			device_set_wakeup_enable(dev, | ||||
| 						acpi_dev->wakeup.state.enabled); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
| @ -377,6 +377,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void physical_device_enable_wakeup(struct acpi_device *adev) | ||||
| { | ||||
| 	struct device *dev = acpi_get_physical_device(adev->handle); | ||||
| 
 | ||||
| 	if (dev && device_can_wakeup(dev)) | ||||
| 		device_set_wakeup_enable(dev, adev->wakeup.state.enabled); | ||||
| } | ||||
| 
 | ||||
| static ssize_t | ||||
| acpi_system_write_wakeup_device(struct file *file, | ||||
| 				const char __user * buffer, | ||||
| @ -411,6 +419,7 @@ acpi_system_write_wakeup_device(struct file *file, | ||||
| 		} | ||||
| 	} | ||||
| 	if (found_dev) { | ||||
| 		physical_device_enable_wakeup(found_dev); | ||||
| 		list_for_each_safe(node, next, &acpi_wakeup_device_list) { | ||||
| 			struct acpi_device *dev = container_of(node, | ||||
| 							       struct | ||||
| @ -428,6 +437,7 @@ acpi_system_write_wakeup_device(struct file *file, | ||||
| 				       dev->pnp.bus_id, found_dev->pnp.bus_id); | ||||
| 				dev->wakeup.state.enabled = | ||||
| 				    found_dev->wakeup.state.enabled; | ||||
| 				physical_device_enable_wakeup(dev); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -256,7 +256,6 @@ static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev) | ||||
| 		BT_ERR("%s urb %p submission failed (%d)", | ||||
| 						hdev->name, urb, -err); | ||||
| 		usb_unanchor_urb(urb); | ||||
| 		kfree(buf); | ||||
| 	} | ||||
| 
 | ||||
| 	usb_free_urb(urb); | ||||
| @ -298,7 +297,6 @@ static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev) | ||||
| 		BT_ERR("%s urb %p submission failed (%d)", | ||||
| 						hdev->name, urb, -err); | ||||
| 		usb_unanchor_urb(urb); | ||||
| 		kfree(buf); | ||||
| 	} | ||||
| 
 | ||||
| 	usb_free_urb(urb); | ||||
|  | ||||
| @ -102,6 +102,7 @@ static struct usb_device_id blacklist_table[] = { | ||||
| 	{ USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||||
| 
 | ||||
| 	/* Broadcom BCM2046 */ | ||||
| 	{ USB_DEVICE(0x0a5c, 0x2146), .driver_info = BTUSB_RESET }, | ||||
| 	{ USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, | ||||
| 
 | ||||
| 	/* Apple MacBook Pro with Broadcom chip */ | ||||
| @ -113,6 +114,7 @@ static struct usb_device_id blacklist_table[] = { | ||||
| 
 | ||||
| 	/* Targus ACB10US */ | ||||
| 	{ USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET }, | ||||
| 	{ USB_DEVICE(0x0a5c, 0x2154), .driver_info = BTUSB_RESET }, | ||||
| 
 | ||||
| 	/* ANYCOM Bluetooth USB-200 and USB-250 */ | ||||
| 	{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET }, | ||||
| @ -150,6 +152,9 @@ static struct usb_device_id blacklist_table[] = { | ||||
| 	{ USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||||
| 	{ USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||||
| 
 | ||||
| 	/* Belkin F8T016 device */ | ||||
| 	{ USB_DEVICE(0x050d, 0x016a), .driver_info = BTUSB_RESET }, | ||||
| 
 | ||||
| 	/* Digianswer devices */ | ||||
| 	{ USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, | ||||
| 	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE }, | ||||
| @ -271,7 +276,6 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev) | ||||
| 		BT_ERR("%s urb %p submission failed (%d)", | ||||
| 						hdev->name, urb, -err); | ||||
| 		usb_unanchor_urb(urb); | ||||
| 		kfree(buf); | ||||
| 	} | ||||
| 
 | ||||
| 	usb_free_urb(urb); | ||||
| @ -354,7 +358,6 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev) | ||||
| 		BT_ERR("%s urb %p submission failed (%d)", | ||||
| 						hdev->name, urb, -err); | ||||
| 		usb_unanchor_urb(urb); | ||||
| 		kfree(buf); | ||||
| 	} | ||||
| 
 | ||||
| 	usb_free_urb(urb); | ||||
| @ -475,7 +478,6 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev) | ||||
| 		BT_ERR("%s urb %p submission failed (%d)", | ||||
| 						hdev->name, urb, -err); | ||||
| 		usb_unanchor_urb(urb); | ||||
| 		kfree(buf); | ||||
| 	} | ||||
| 
 | ||||
| 	usb_free_urb(urb); | ||||
|  | ||||
| @ -364,7 +364,7 @@ static void dw_dma_tasklet(unsigned long data) | ||||
| 	int i; | ||||
| 
 | ||||
| 	status_block = dma_readl(dw, RAW.BLOCK); | ||||
| 	status_xfer = dma_readl(dw, RAW.BLOCK); | ||||
| 	status_xfer = dma_readl(dw, RAW.XFER); | ||||
| 	status_err = dma_readl(dw, RAW.ERROR); | ||||
| 
 | ||||
| 	dev_vdbg(dw->dma.dev, "tasklet: status_block=%x status_err=%x\n", | ||||
|  | ||||
| @ -780,10 +780,6 @@ config BLK_DEV_IDEDMA_PMAC | ||||
| 	  to transfer data to and from memory.  Saying Y is safe and improves | ||||
| 	  performance. | ||||
| 
 | ||||
| config BLK_DEV_IDE_SWARM | ||||
| 	tristate "IDE for Sibyte evaluation boards" | ||||
| 	depends on SIBYTE_SB1xxx_SOC | ||||
| 
 | ||||
| config BLK_DEV_IDE_AU1XXX | ||||
|        bool "IDE for AMD Alchemy Au1200" | ||||
|        depends on SOC_AU1200 | ||||
|  | ||||
| @ -1661,7 +1661,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) | ||||
| 		cdi->mask &= ~CDC_PLAY_AUDIO; | ||||
| 
 | ||||
| 	mechtype = buf[8 + 6] >> 5; | ||||
| 	if (mechtype == mechtype_caddy || mechtype == mechtype_popup) | ||||
| 	if (mechtype == mechtype_caddy || | ||||
| 	    mechtype == mechtype_popup || | ||||
| 	    (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE)) | ||||
| 		cdi->mask |= CDC_CLOSE_TRAY; | ||||
| 
 | ||||
| 	if (cdi->sanyo_slot > 0) { | ||||
| @ -1859,6 +1861,8 @@ static const struct cd_list_entry ide_cd_quirks_list[] = { | ||||
| 	{ "MATSHITADVD-ROM SR-8176", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     }, | ||||
| 	{ "MATSHITADVD-ROM SR-8174", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     }, | ||||
| 	{ "Optiarc DVD RW AD-5200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     }, | ||||
| 	{ "Optiarc DVD RW AD-7200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     }, | ||||
| 	{ "Optiarc DVD RW AD-7543A", NULL,   IDE_AFLAG_NO_AUTOCLOSE	     }, | ||||
| 	{ NULL, NULL, 0 } | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -211,7 +211,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) | ||||
| 				xcount = bcount & 0xffff; | ||||
| 				if (is_trm290) | ||||
| 					xcount = ((xcount >> 2) - 1) << 16; | ||||
| 				if (xcount == 0x0000) { | ||||
| 				else if (xcount == 0x0000) { | ||||
| 	/* 
 | ||||
| 	 * Most chipsets correctly interpret a length of 0x0000 as 64KB, | ||||
| 	 * but at least one (e.g. CS5530) misinterprets it as zero (!). | ||||
|  | ||||
| @ -1492,7 +1492,7 @@ static struct device_attribute *ide_port_attrs[] = { | ||||
| 
 | ||||
| static int ide_sysfs_register_port(ide_hwif_t *hwif) | ||||
| { | ||||
| 	int i, rc; | ||||
| 	int i, uninitialized_var(rc); | ||||
| 
 | ||||
| 	for (i = 0; ide_port_attrs[i]; i++) { | ||||
| 		rc = device_create_file(hwif->portdev, ide_port_attrs[i]); | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| obj-$(CONFIG_BLK_DEV_IDE_SWARM)		+= swarm.o | ||||
| obj-$(CONFIG_BLK_DEV_IDE_AU1XXX)	+= au1xxx-ide.o | ||||
| 
 | ||||
| EXTRA_CFLAGS    := -Idrivers/ide | ||||
|  | ||||
| @ -1,197 +0,0 @@ | ||||
| /*
 | ||||
|  * Copyright (C) 2001, 2002, 2003 Broadcom Corporation | ||||
|  * Copyright (C) 2004 MontaVista Software Inc. | ||||
|  *	Author:	Manish Lachwani, mlachwani@mvista.com | ||||
|  * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved. | ||||
|  *	Author: Maciej W. Rozycki <macro@mips.com> | ||||
|  * Copyright (c) 2006, 2008  Maciej W. Rozycki | ||||
|  * | ||||
|  * 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, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  Derived loosely from ide-pmac.c, so: | ||||
|  *  Copyright (C) 1998 Paul Mackerras. | ||||
|  *  Copyright (C) 1995-1998 Mark Lord | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Boards with SiByte processors so far have supported IDE devices via | ||||
|  * the Generic Bus, PCI bus, and built-in PCMCIA interface.  In all | ||||
|  * cases, byte-swapping must be avoided for these devices (whereas | ||||
|  * other PCI devices, for example, will require swapping).  Any | ||||
|  * SiByte-targetted kernel including IDE support will include this | ||||
|  * file.  Probing of a Generic Bus for an IDE device is controlled by | ||||
|  * the definition of "SIBYTE_HAVE_IDE", which is provided by | ||||
|  * <asm/sibyte/board.h> for Broadcom boards. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/ide.h> | ||||
| #include <linux/ioport.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/platform_device.h> | ||||
| 
 | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
| #include <asm/sibyte/board.h> | ||||
| #include <asm/sibyte/sb1250_genbus.h> | ||||
| #include <asm/sibyte/sb1250_regs.h> | ||||
| 
 | ||||
| #define DRV_NAME "ide-swarm" | ||||
| 
 | ||||
| static char swarm_ide_string[] = DRV_NAME; | ||||
| 
 | ||||
| static struct resource swarm_ide_resource = { | ||||
| 	.name	= "SWARM GenBus IDE", | ||||
| 	.flags	= IORESOURCE_MEM, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device *swarm_ide_dev; | ||||
| 
 | ||||
| static const struct ide_port_info swarm_port_info = { | ||||
| 	.name			= DRV_NAME, | ||||
| 	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * swarm_ide_probe - if the board header indicates the existence of | ||||
|  * Generic Bus IDE, allocate a HWIF for it. | ||||
|  */ | ||||
| static int __devinit swarm_ide_probe(struct device *dev) | ||||
| { | ||||
| 	u8 __iomem *base; | ||||
| 	struct ide_host *host; | ||||
| 	phys_t offset, size; | ||||
| 	int i, rc; | ||||
| 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | ||||
| 
 | ||||
| 	if (!SIBYTE_HAVE_IDE) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	base = ioremap(A_IO_EXT_BASE, 0x800); | ||||
| 	offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); | ||||
| 	size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); | ||||
| 	iounmap(base); | ||||
| 
 | ||||
| 	offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE; | ||||
| 	size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE; | ||||
| 	if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) { | ||||
| 		printk(KERN_INFO DRV_NAME | ||||
| 		       ": IDE interface at GenBus disabled\n"); | ||||
| 		return -EBUSY; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n", | ||||
| 	       IDE_CS); | ||||
| 
 | ||||
| 	swarm_ide_resource.start = offset; | ||||
| 	swarm_ide_resource.end = offset + size - 1; | ||||
| 	if (request_resource(&iomem_resource, &swarm_ide_resource)) { | ||||
| 		printk(KERN_ERR DRV_NAME | ||||
| 		       ": can't request I/O memory resource\n"); | ||||
| 		return -EBUSY; | ||||
| 	} | ||||
| 
 | ||||
| 	base = ioremap(offset, size); | ||||
| 
 | ||||
| 	memset(&hw, 0, sizeof(hw)); | ||||
| 	for (i = 0; i <= 7; i++) | ||||
| 		hw.io_ports_array[i] = | ||||
| 				(unsigned long)(base + ((0x1f0 + i) << 5)); | ||||
| 	hw.io_ports.ctl_addr = | ||||
| 				(unsigned long)(base + (0x3f6 << 5)); | ||||
| 	hw.irq = K_INT_GB_IDE; | ||||
| 	hw.chipset = ide_generic; | ||||
| 
 | ||||
| 	rc = ide_host_add(&swarm_port_info, hws, &host); | ||||
| 	if (rc) | ||||
| 		goto err; | ||||
| 
 | ||||
| 	dev_set_drvdata(dev, host); | ||||
| 
 | ||||
| 	return 0; | ||||
| err: | ||||
| 	release_resource(&swarm_ide_resource); | ||||
| 	iounmap(base); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| static struct device_driver swarm_ide_driver = { | ||||
| 	.name	= swarm_ide_string, | ||||
| 	.bus	= &platform_bus_type, | ||||
| 	.probe	= swarm_ide_probe, | ||||
| }; | ||||
| 
 | ||||
| static void swarm_ide_platform_release(struct device *device) | ||||
| { | ||||
| 	struct platform_device *pldev; | ||||
| 
 | ||||
| 	/* free device */ | ||||
| 	pldev = to_platform_device(device); | ||||
| 	kfree(pldev); | ||||
| } | ||||
| 
 | ||||
| static int __devinit swarm_ide_init_module(void) | ||||
| { | ||||
| 	struct platform_device *pldev; | ||||
| 	int err; | ||||
| 
 | ||||
| 	printk(KERN_INFO "SWARM IDE driver\n"); | ||||
| 
 | ||||
| 	if (driver_register(&swarm_ide_driver)) { | ||||
| 		printk(KERN_ERR "Driver registration failed\n"); | ||||
| 		err = -ENODEV; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
|         if (!(pldev = kzalloc(sizeof (*pldev), GFP_KERNEL))) { | ||||
| 		err = -ENOMEM; | ||||
| 		goto out_unregister_driver; | ||||
| 	} | ||||
| 
 | ||||
| 	pldev->name		= swarm_ide_string; | ||||
| 	pldev->id		= 0; | ||||
| 	pldev->dev.release	= swarm_ide_platform_release; | ||||
| 
 | ||||
| 	if (platform_device_register(pldev)) { | ||||
| 		err = -ENODEV; | ||||
| 		goto out_free_pldev; | ||||
| 	} | ||||
| 
 | ||||
|         if (!pldev->dev.driver) { | ||||
| 		/*
 | ||||
| 		 * The driver was not bound to this device, there was | ||||
|                  * no hardware at this address. Unregister it, as the | ||||
| 		 * release fuction will take care of freeing the | ||||
| 		 * allocated structure | ||||
| 		 */ | ||||
| 		platform_device_unregister (pldev); | ||||
| 	} | ||||
| 
 | ||||
| 	swarm_ide_dev = pldev; | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| out_free_pldev: | ||||
| 	kfree(pldev); | ||||
| 
 | ||||
| out_unregister_driver: | ||||
| 	driver_unregister(&swarm_ide_driver); | ||||
| out: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| module_init(swarm_ide_init_module); | ||||
| @ -161,6 +161,16 @@ static int fsg_led_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	/* Map the LED chip select address space */ | ||||
| 	latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512); | ||||
| 	if (!latch_address) { | ||||
| 		ret = -ENOMEM; | ||||
| 		goto failremap; | ||||
| 	} | ||||
| 
 | ||||
| 	latch_value = 0xffff; | ||||
| 	*latch_address = latch_value; | ||||
| 
 | ||||
| 	ret = led_classdev_register(&pdev->dev, &fsg_wlan_led); | ||||
| 	if (ret < 0) | ||||
| 		goto failwlan; | ||||
| @ -185,20 +195,8 @@ static int fsg_led_probe(struct platform_device *pdev) | ||||
| 	if (ret < 0) | ||||
| 		goto failring; | ||||
| 
 | ||||
| 	/* Map the LED chip select address space */ | ||||
| 	latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512); | ||||
| 	if (!latch_address) { | ||||
| 		ret = -ENOMEM; | ||||
| 		goto failremap; | ||||
| 	} | ||||
| 
 | ||||
| 	latch_value = 0xffff; | ||||
| 	*latch_address = latch_value; | ||||
| 
 | ||||
| 	return ret; | ||||
| 
 | ||||
|  failremap: | ||||
| 	led_classdev_unregister(&fsg_ring_led); | ||||
|  failring: | ||||
| 	led_classdev_unregister(&fsg_sync_led); | ||||
|  failsync: | ||||
| @ -210,14 +208,14 @@ static int fsg_led_probe(struct platform_device *pdev) | ||||
|  failwan: | ||||
| 	led_classdev_unregister(&fsg_wlan_led); | ||||
|  failwlan: | ||||
| 	iounmap(latch_address); | ||||
|  failremap: | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int fsg_led_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	iounmap(latch_address); | ||||
| 
 | ||||
| 	led_classdev_unregister(&fsg_wlan_led); | ||||
| 	led_classdev_unregister(&fsg_wan_led); | ||||
| 	led_classdev_unregister(&fsg_sata_led); | ||||
| @ -225,6 +223,8 @@ static int fsg_led_remove(struct platform_device *pdev) | ||||
| 	led_classdev_unregister(&fsg_sync_led); | ||||
| 	led_classdev_unregister(&fsg_ring_led); | ||||
| 
 | ||||
| 	iounmap(latch_address); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -248,11 +248,10 @@ static int __devinit pca955x_probe(struct i2c_client *client, | ||||
| 					const struct i2c_device_id *id) | ||||
| { | ||||
| 	struct pca955x_led *pca955x; | ||||
| 	int i; | ||||
| 	int err = -ENODEV; | ||||
| 	struct pca955x_chipdef *chip; | ||||
| 	struct i2c_adapter *adapter; | ||||
| 	struct led_platform_data *pdata; | ||||
| 	int i, err; | ||||
| 
 | ||||
| 	chip = &pca955x_chipdefs[id->driver_data]; | ||||
| 	adapter = to_i2c_adapter(client->dev.parent); | ||||
| @ -282,43 +281,41 @@ static int __devinit pca955x_probe(struct i2c_client *client, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < chip->bits; i++) { | ||||
| 		pca955x = kzalloc(sizeof(struct pca955x_led), GFP_KERNEL); | ||||
| 		if (!pca955x) { | ||||
| 			err = -ENOMEM; | ||||
| 			goto exit; | ||||
| 		} | ||||
| 	pca955x = kzalloc(sizeof(*pca955x) * chip->bits, GFP_KERNEL); | ||||
| 	if (!pca955x) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	i2c_set_clientdata(client, pca955x); | ||||
| 
 | ||||
| 	for (i = 0; i < chip->bits; i++) { | ||||
| 		pca955x[i].chipdef = chip; | ||||
| 		pca955x[i].client = client; | ||||
| 		pca955x[i].led_num = i; | ||||
| 
 | ||||
| 		pca955x->chipdef = chip; | ||||
| 		pca955x->client = client; | ||||
| 		pca955x->led_num = i; | ||||
| 		/* Platform data can specify LED names and default triggers */ | ||||
| 		if (pdata) { | ||||
| 			if (pdata->leds[i].name) | ||||
| 				snprintf(pca955x->name, 32, "pca955x:%s", | ||||
| 							pdata->leds[i].name); | ||||
| 				snprintf(pca955x[i].name, | ||||
| 					 sizeof(pca955x[i].name), "pca955x:%s", | ||||
| 					 pdata->leds[i].name); | ||||
| 			if (pdata->leds[i].default_trigger) | ||||
| 				pca955x->led_cdev.default_trigger = | ||||
| 				pca955x[i].led_cdev.default_trigger = | ||||
| 					pdata->leds[i].default_trigger; | ||||
| 		} else { | ||||
| 			snprintf(pca955x->name, 32, "pca955x:%d", i); | ||||
| 			snprintf(pca955x[i].name, sizeof(pca955x[i].name), | ||||
| 				 "pca955x:%d", i); | ||||
| 		} | ||||
| 		spin_lock_init(&pca955x->lock); | ||||
| 
 | ||||
| 		pca955x->led_cdev.name = pca955x->name; | ||||
| 		pca955x->led_cdev.brightness_set = | ||||
| 				pca955x_led_set; | ||||
| 		spin_lock_init(&pca955x[i].lock); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Client data is a pointer to the _first_ pca955x_led | ||||
| 		 * struct | ||||
| 		 */ | ||||
| 		if (i == 0) | ||||
| 			i2c_set_clientdata(client, pca955x); | ||||
| 		pca955x[i].led_cdev.name = pca955x[i].name; | ||||
| 		pca955x[i].led_cdev.brightness_set = pca955x_led_set; | ||||
| 
 | ||||
| 		INIT_WORK(&(pca955x->work), pca955x_led_work); | ||||
| 		INIT_WORK(&pca955x[i].work, pca955x_led_work); | ||||
| 
 | ||||
| 		led_classdev_register(&client->dev, &(pca955x->led_cdev)); | ||||
| 		err = led_classdev_register(&client->dev, &pca955x[i].led_cdev); | ||||
| 		if (err < 0) | ||||
| 			goto exit; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Turn off LEDs */ | ||||
| @ -336,23 +333,32 @@ static int __devinit pca955x_probe(struct i2c_client *client, | ||||
| 	pca955x_write_psc(client, 1, 0); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| exit: | ||||
| 	while (i--) { | ||||
| 		led_classdev_unregister(&pca955x[i].led_cdev); | ||||
| 		cancel_work_sync(&pca955x[i].work); | ||||
| 	} | ||||
| 
 | ||||
| 	kfree(pca955x); | ||||
| 	i2c_set_clientdata(client, NULL); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int __devexit pca955x_remove(struct i2c_client *client) | ||||
| { | ||||
| 	struct pca955x_led *pca955x = i2c_get_clientdata(client); | ||||
| 	int leds = pca955x->chipdef->bits; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < leds; i++) { | ||||
| 		led_classdev_unregister(&(pca955x->led_cdev)); | ||||
| 		cancel_work_sync(&(pca955x->work)); | ||||
| 		kfree(pca955x); | ||||
| 		pca955x = pca955x + 1; | ||||
| 	for (i = 0; i < pca955x->chipdef->bits; i++) { | ||||
| 		led_classdev_unregister(&pca955x[i].led_cdev); | ||||
| 		cancel_work_sync(&pca955x[i].work); | ||||
| 	} | ||||
| 
 | ||||
| 	kfree(pca955x); | ||||
| 	i2c_set_clientdata(client, NULL); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -63,6 +63,7 @@ struct multipath { | ||||
| 
 | ||||
| 	const char *hw_handler_name; | ||||
| 	struct work_struct activate_path; | ||||
| 	struct pgpath *pgpath_to_activate; | ||||
| 	unsigned nr_priority_groups; | ||||
| 	struct list_head priority_groups; | ||||
| 	unsigned pg_init_required;	/* pg_init needs calling? */ | ||||
| @ -146,6 +147,7 @@ static struct priority_group *alloc_priority_group(void) | ||||
| 
 | ||||
| static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	struct pgpath *pgpath, *tmp; | ||||
| 	struct multipath *m = ti->private; | ||||
| 
 | ||||
| @ -154,6 +156,10 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) | ||||
| 		if (m->hw_handler_name) | ||||
| 			scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); | ||||
| 		dm_put_device(ti, pgpath->path.dev); | ||||
| 		spin_lock_irqsave(&m->lock, flags); | ||||
| 		if (m->pgpath_to_activate == pgpath) | ||||
| 			m->pgpath_to_activate = NULL; | ||||
| 		spin_unlock_irqrestore(&m->lock, flags); | ||||
| 		free_pgpath(pgpath); | ||||
| 	} | ||||
| } | ||||
| @ -421,6 +427,7 @@ static void process_queued_ios(struct work_struct *work) | ||||
| 		__choose_pgpath(m); | ||||
| 
 | ||||
| 	pgpath = m->current_pgpath; | ||||
| 	m->pgpath_to_activate = m->current_pgpath; | ||||
| 
 | ||||
| 	if ((pgpath && !m->queue_io) || | ||||
| 	    (!pgpath && !m->queue_if_no_path)) | ||||
| @ -1093,8 +1100,15 @@ static void activate_path(struct work_struct *work) | ||||
| 	int ret; | ||||
| 	struct multipath *m = | ||||
| 		container_of(work, struct multipath, activate_path); | ||||
| 	struct dm_path *path = &m->current_pgpath->path; | ||||
| 	struct dm_path *path; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&m->lock, flags); | ||||
| 	path = &m->pgpath_to_activate->path; | ||||
| 	m->pgpath_to_activate = NULL; | ||||
| 	spin_unlock_irqrestore(&m->lock, flags); | ||||
| 	if (!path) | ||||
| 		return; | ||||
| 	ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev)); | ||||
| 	pg_init_done(path, ret); | ||||
| } | ||||
|  | ||||
| @ -837,12 +837,14 @@ static int dm_merge_bvec(struct request_queue *q, | ||||
| 	struct dm_table *map = dm_get_table(md); | ||||
| 	struct dm_target *ti; | ||||
| 	sector_t max_sectors; | ||||
| 	int max_size; | ||||
| 	int max_size = 0; | ||||
| 
 | ||||
| 	if (unlikely(!map)) | ||||
| 		return 0; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	ti = dm_table_find_target(map, bvm->bi_sector); | ||||
| 	if (!dm_target_is_valid(ti)) | ||||
| 		goto out_table; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Find maximum amount of I/O that won't need splitting | ||||
| @ -861,14 +863,16 @@ static int dm_merge_bvec(struct request_queue *q, | ||||
| 	if (max_size && ti->type->merge) | ||||
| 		max_size = ti->type->merge(ti, bvm, biovec, max_size); | ||||
| 
 | ||||
| out_table: | ||||
| 	dm_table_put(map); | ||||
| 
 | ||||
| out: | ||||
| 	/*
 | ||||
| 	 * Always allow an entire first page | ||||
| 	 */ | ||||
| 	if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT)) | ||||
| 		max_size = biovec->bv_len; | ||||
| 
 | ||||
| 	dm_table_put(map); | ||||
| 
 | ||||
| 	return max_size; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -10,6 +10,7 @@ | ||||
| #include "dvb_frontend.h" | ||||
| 
 | ||||
| #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw" | ||||
| #define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw" | ||||
| 
 | ||||
| /*      Dmoduler		IF (kHz) */ | ||||
| #define	XC3028_FE_DEFAULT	0		/* Don't load SCODE */ | ||||
|  | ||||
| @ -491,6 +491,7 @@ static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { | ||||
| 	.demod_address = 0x53, | ||||
| 	.invert = 1, | ||||
| 	.repeated_start_workaround = 1, | ||||
| 	.serial_mpeg = 1, | ||||
| }; | ||||
| 
 | ||||
| static struct itd1000_config skystar2_rev2_7_itd1000_config = { | ||||
|  | ||||
| @ -364,15 +364,16 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, | ||||
| 				       enum dmx_success success) | ||||
| { | ||||
| 	struct dmxdev_filter *dmxdevfilter = filter->priv; | ||||
| 	unsigned long flags; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (dmxdevfilter->buffer.error) { | ||||
| 		wake_up(&dmxdevfilter->buffer.queue); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	spin_lock(&dmxdevfilter->dev->lock); | ||||
| 	spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); | ||||
| 	if (dmxdevfilter->state != DMXDEV_STATE_GO) { | ||||
| 		spin_unlock(&dmxdevfilter->dev->lock); | ||||
| 		spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	del_timer(&dmxdevfilter->timer); | ||||
| @ -391,7 +392,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, | ||||
| 	} | ||||
| 	if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) | ||||
| 		dmxdevfilter->state = DMXDEV_STATE_DONE; | ||||
| 	spin_unlock(&dmxdevfilter->dev->lock); | ||||
| 	spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); | ||||
| 	wake_up(&dmxdevfilter->buffer.queue); | ||||
| 	return 0; | ||||
| } | ||||
| @ -403,11 +404,12 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, | ||||
| { | ||||
| 	struct dmxdev_filter *dmxdevfilter = feed->priv; | ||||
| 	struct dvb_ringbuffer *buffer; | ||||
| 	unsigned long flags; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	spin_lock(&dmxdevfilter->dev->lock); | ||||
| 	spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); | ||||
| 	if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { | ||||
| 		spin_unlock(&dmxdevfilter->dev->lock); | ||||
| 		spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| @ -417,7 +419,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, | ||||
| 	else | ||||
| 		buffer = &dmxdevfilter->dev->dvr_buffer; | ||||
| 	if (buffer->error) { | ||||
| 		spin_unlock(&dmxdevfilter->dev->lock); | ||||
| 		spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); | ||||
| 		wake_up(&buffer->queue); | ||||
| 		return 0; | ||||
| 	} | ||||
| @ -428,7 +430,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, | ||||
| 		dvb_ringbuffer_flush(buffer); | ||||
| 		buffer->error = ret; | ||||
| 	} | ||||
| 	spin_unlock(&dmxdevfilter->dev->lock); | ||||
| 	spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); | ||||
| 	wake_up(&buffer->queue); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -399,7 +399,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | ||||
| void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, | ||||
| 			      size_t count) | ||||
| { | ||||
| 	spin_lock(&demux->lock); | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&demux->lock, flags); | ||||
| 
 | ||||
| 	while (count--) { | ||||
| 		if (buf[0] == 0x47) | ||||
| @ -407,16 +409,17 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, | ||||
| 		buf += 188; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_unlock(&demux->lock); | ||||
| 	spin_unlock_irqrestore(&demux->lock, flags); | ||||
| } | ||||
| 
 | ||||
| EXPORT_SYMBOL(dvb_dmx_swfilter_packets); | ||||
| 
 | ||||
| void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	int p = 0, i, j; | ||||
| 
 | ||||
| 	spin_lock(&demux->lock); | ||||
| 	spin_lock_irqsave(&demux->lock, flags); | ||||
| 
 | ||||
| 	if (demux->tsbufp) { | ||||
| 		i = demux->tsbufp; | ||||
| @ -449,17 +452,18 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) | ||||
| 	} | ||||
| 
 | ||||
| bailout: | ||||
| 	spin_unlock(&demux->lock); | ||||
| 	spin_unlock_irqrestore(&demux->lock, flags); | ||||
| } | ||||
| 
 | ||||
| EXPORT_SYMBOL(dvb_dmx_swfilter); | ||||
| 
 | ||||
| void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	int p = 0, i, j; | ||||
| 	u8 tmppack[188]; | ||||
| 
 | ||||
| 	spin_lock(&demux->lock); | ||||
| 	spin_lock_irqsave(&demux->lock, flags); | ||||
| 
 | ||||
| 	if (demux->tsbufp) { | ||||
| 		i = demux->tsbufp; | ||||
| @ -500,7 +504,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | ||||
| 	} | ||||
| 
 | ||||
| bailout: | ||||
| 	spin_unlock(&demux->lock); | ||||
| 	spin_unlock_irqrestore(&demux->lock, flags); | ||||
| } | ||||
| 
 | ||||
| EXPORT_SYMBOL(dvb_dmx_swfilter_204); | ||||
|  | ||||
| @ -59,7 +59,7 @@ struct s5h1420_state { | ||||
| 	 * it does not support repeated-start, workaround: write addr-1 | ||||
| 	 * and then read | ||||
| 	 */ | ||||
| 	u8 shadow[255]; | ||||
| 	u8 shadow[256]; | ||||
| }; | ||||
| 
 | ||||
| static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); | ||||
| @ -94,8 +94,11 @@ static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg) | ||||
| 		if (ret != 3) | ||||
| 			return ret; | ||||
| 	} else { | ||||
| 		ret = i2c_transfer(state->i2c, &msg[1], 2); | ||||
| 		if (ret != 2) | ||||
| 		ret = i2c_transfer(state->i2c, &msg[1], 1); | ||||
| 		if (ret != 1) | ||||
| 			return ret; | ||||
| 		ret = i2c_transfer(state->i2c, &msg[2], 1); | ||||
| 		if (ret != 1) | ||||
| 			return ret; | ||||
| 	} | ||||
| 
 | ||||
| @ -823,7 +826,7 @@ static int s5h1420_init (struct dvb_frontend* fe) | ||||
| 	struct s5h1420_state* state = fe->demodulator_priv; | ||||
| 
 | ||||
| 	/* disable power down and do reset */ | ||||
| 	state->CON_1_val = 0x10; | ||||
| 	state->CON_1_val = state->config->serial_mpeg << 4; | ||||
| 	s5h1420_writereg(state, 0x02, state->CON_1_val); | ||||
| 	msleep(10); | ||||
| 	s5h1420_reset(state); | ||||
|  | ||||
| @ -32,10 +32,12 @@ struct s5h1420_config | ||||
| 	u8 demod_address; | ||||
| 
 | ||||
| 	/* does the inversion require inversion? */ | ||||
| 	u8 invert : 1; | ||||
| 	u8 invert:1; | ||||
| 
 | ||||
| 	u8 repeated_start_workaround : 1; | ||||
| 	u8 cdclk_polarity : 1; /* 1 == falling edge, 0 == raising edge */ | ||||
| 	u8 repeated_start_workaround:1; | ||||
| 	u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */ | ||||
| 
 | ||||
| 	u8 serial_mpeg:1; | ||||
| }; | ||||
| 
 | ||||
| #if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) | ||||
|  | ||||
| @ -40,6 +40,8 @@ struct usb_device_id smsusb_id_table[] = { | ||||
| 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, | ||||
| 	{ USB_DEVICE(0x2040, 0x5500), | ||||
| 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||||
| 	{ USB_DEVICE(0x2040, 0x5510), | ||||
| 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||||
| 	{ USB_DEVICE(0x2040, 0x5580), | ||||
| 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||||
| 	{ USB_DEVICE(0x2040, 0x5590), | ||||
| @ -87,7 +89,7 @@ static struct sms_board sms_boards[] = { | ||||
| 		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", | ||||
| 	}, | ||||
| 	[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { | ||||
| 		.name	= "Hauppauge WinTV-Nova-T-MiniStick", | ||||
| 		.name	= "Hauppauge WinTV MiniStick", | ||||
| 		.type	= SMS_NOVA_B0, | ||||
| 		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw", | ||||
| 	}, | ||||
|  | ||||
| @ -3431,7 +3431,7 @@ static int radio_open(struct inode *inode, struct file *file) | ||||
| 	dprintk("bttv: open minor=%d\n",minor); | ||||
| 
 | ||||
| 	for (i = 0; i < bttv_num; i++) { | ||||
| 		if (bttvs[i].radio_dev->minor == minor) { | ||||
| 		if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) { | ||||
| 			btv = &bttvs[i]; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| #include <linux/module.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/fs.h> | ||||
| #include <linux/mm.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/i2c.h> | ||||
| #include <linux/interrupt.h> | ||||
|  | ||||
| @ -632,7 +632,7 @@ int cpia2_usb_transfer_cmd(struct camera_data *cam, | ||||
| static int submit_urbs(struct camera_data *cam) | ||||
| { | ||||
| 	struct urb *urb; | ||||
| 	int fx, err, i; | ||||
| 	int fx, err, i, j; | ||||
| 
 | ||||
| 	for(i=0; i<NUM_SBUF; ++i) { | ||||
| 		if (cam->sbuf[i].data) | ||||
| @ -657,6 +657,9 @@ static int submit_urbs(struct camera_data *cam) | ||||
| 		} | ||||
| 		urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); | ||||
| 		if (!urb) { | ||||
| 			ERR("%s: usb_alloc_urb error!\n", __func__); | ||||
| 			for (j = 0; j < i; j++) | ||||
| 				usb_free_urb(cam->sbuf[j].urb); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -163,7 +163,7 @@ static const struct cx18_card cx18_card_h900 = { | ||||
| 	}, | ||||
| 	.audio_inputs = { | ||||
| 		{ CX18_CARD_INPUT_AUD_TUNER, | ||||
| 		  CX18_AV_AUDIO8, 0 }, | ||||
| 		  CX18_AV_AUDIO5, 0 }, | ||||
| 		{ CX18_CARD_INPUT_LINE_IN1, | ||||
| 		  CX18_AV_AUDIO_SERIAL1, 0 }, | ||||
| 	}, | ||||
|  | ||||
| @ -117,10 +117,10 @@ static void em28xx_audio_isocirq(struct urb *urb) | ||||
| 
 | ||||
| 			if (oldptr + length >= runtime->buffer_size) { | ||||
| 				unsigned int cnt = | ||||
| 				    runtime->buffer_size - oldptr - 1; | ||||
| 				    runtime->buffer_size - oldptr; | ||||
| 				memcpy(runtime->dma_area + oldptr * stride, cp, | ||||
| 				       cnt * stride); | ||||
| 				memcpy(runtime->dma_area, cp + cnt, | ||||
| 				memcpy(runtime->dma_area, cp + cnt * stride, | ||||
| 				       length * stride - cnt * stride); | ||||
| 			} else { | ||||
| 				memcpy(runtime->dma_area + oldptr * stride, cp, | ||||
| @ -161,8 +161,14 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | ||||
| 
 | ||||
| 		memset(dev->adev->transfer_buffer[i], 0x80, sb_size); | ||||
| 		urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); | ||||
| 		if (!urb) | ||||
| 		if (!urb) { | ||||
| 			em28xx_errdev("usb_alloc_urb failed!\n"); | ||||
| 			for (j = 0; j < i; j++) { | ||||
| 				usb_free_urb(dev->adev->urb[j]); | ||||
| 				kfree(dev->adev->transfer_buffer[j]); | ||||
| 			} | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 
 | ||||
| 		urb->dev = dev->udev; | ||||
| 		urb->context = dev; | ||||
|  | ||||
| @ -93,28 +93,6 @@ struct em28xx_board em28xx_boards[] = { | ||||
| 			.amux     = 0, | ||||
| 		} }, | ||||
| 	}, | ||||
| 	[EM2800_BOARD_KWORLD_USB2800] = { | ||||
| 		.name         = "Kworld USB2800", | ||||
| 		.valid        = EM28XX_BOARD_NOT_VALIDATED, | ||||
| 		.is_em2800    = 1, | ||||
| 		.vchannels    = 3, | ||||
| 		.tuner_type   = TUNER_PHILIPS_FCV1236D, | ||||
| 		.tda9887_conf = TDA9887_PRESENT, | ||||
| 		.decoder      = EM28XX_SAA7113, | ||||
| 		.input          = { { | ||||
| 			.type     = EM28XX_VMUX_TELEVISION, | ||||
| 			.vmux     = SAA7115_COMPOSITE2, | ||||
| 			.amux     = 0, | ||||
| 		}, { | ||||
| 			.type     = EM28XX_VMUX_COMPOSITE1, | ||||
| 			.vmux     = SAA7115_COMPOSITE0, | ||||
| 			.amux     = 1, | ||||
| 		}, { | ||||
| 			.type     = EM28XX_VMUX_SVIDEO, | ||||
| 			.vmux     = SAA7115_SVIDEO3, | ||||
| 			.amux     = 1, | ||||
| 		} }, | ||||
| 	}, | ||||
| 	[EM2820_BOARD_KWORLD_PVRTV2800RF] = { | ||||
| 		.name         = "Kworld PVR TV 2800 RF", | ||||
| 		.is_em2800    = 0, | ||||
| @ -599,7 +577,7 @@ struct em28xx_board em28xx_boards[] = { | ||||
| 		}, { | ||||
| 			.type     = EM28XX_VMUX_COMPOSITE1, | ||||
| 			.vmux     = TVP5150_COMPOSITE1, | ||||
| 			.amux     = 1, | ||||
| 			.amux     = 3, | ||||
| 		}, { | ||||
| 			.type     = EM28XX_VMUX_SVIDEO, | ||||
| 			.vmux     = TVP5150_SVIDEO, | ||||
| @ -952,22 +930,23 @@ struct em28xx_board em28xx_boards[] = { | ||||
| 	}, | ||||
| 	[EM2880_BOARD_KWORLD_DVB_310U] = { | ||||
| 		.name	      = "KWorld DVB-T 310U", | ||||
| 		.valid        = EM28XX_BOARD_NOT_VALIDATED, | ||||
| 		.vchannels    = 3, | ||||
| 		.tuner_type   = TUNER_XC2028, | ||||
| 		.has_dvb      = 1, | ||||
| 		.mts_firmware = 1, | ||||
| 		.decoder      = EM28XX_TVP5150, | ||||
| 		.input          = { { | ||||
| 			.type     = EM28XX_VMUX_TELEVISION, | ||||
| 			.vmux     = TVP5150_COMPOSITE0, | ||||
| 			.amux     = 0, | ||||
| 			.amux     = EM28XX_AMUX_VIDEO, | ||||
| 		}, { | ||||
| 			.type     = EM28XX_VMUX_COMPOSITE1, | ||||
| 			.vmux     = TVP5150_COMPOSITE1, | ||||
| 			.amux     = 1, | ||||
| 		}, { | ||||
| 			.amux     = EM28XX_AMUX_AC97_LINE_IN, | ||||
| 		}, {	/* S-video has not been tested yet */ | ||||
| 			.type     = EM28XX_VMUX_SVIDEO, | ||||
| 			.vmux     = TVP5150_SVIDEO, | ||||
| 			.amux     = 1, | ||||
| 			.amux     = EM28XX_AMUX_AC97_LINE_IN, | ||||
| 		} }, | ||||
| 	}, | ||||
| 	[EM2881_BOARD_DNT_DA2_HYBRID] = { | ||||
| @ -1282,6 +1261,7 @@ static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = { | ||||
| static struct em28xx_hash_table em28xx_eeprom_hash [] = { | ||||
| 	/* P/N: SA 60002070465 Tuner: TVF7533-MF */ | ||||
| 	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | ||||
| 	{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | ||||
| }; | ||||
| 
 | ||||
| /* I2C devicelist hash table for devices with generic USB IDs */ | ||||
| @ -1552,9 +1532,12 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | ||||
| 		/* djh - Not sure which demod we need here */ | ||||
| 		ctl->demod = XC3028_FE_DEFAULT; | ||||
| 		break; | ||||
| 	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||||
| 		ctl->demod = XC3028_FE_DEFAULT; | ||||
| 		ctl->fname = XC3028L_DEFAULT_FIRMWARE; | ||||
| 		break; | ||||
| 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||||
| 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | ||||
| 	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||||
| 		/* FIXME: Better to specify the needed IF */ | ||||
| 		ctl->demod = XC3028_FE_DEFAULT; | ||||
| 		break; | ||||
| @ -1764,6 +1747,20 @@ void em28xx_card_setup(struct em28xx *dev) | ||||
| 		break; | ||||
| 	case EM2820_BOARD_UNKNOWN: | ||||
| 	case EM2800_BOARD_UNKNOWN: | ||||
| 		/*
 | ||||
| 		 * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD. | ||||
| 		 * | ||||
| 		 * This occurs because they share identical USB vendor and | ||||
| 		 * product IDs. | ||||
| 		 * | ||||
| 		 * What we do here is look up the EEPROM hash of the K-WORLD | ||||
| 		 * and if it is found then we decide that we do not have | ||||
| 		 * a DIGIVOX and reset the device to the K-WORLD instead. | ||||
| 		 * | ||||
| 		 * This solution is only valid if they do not share eeprom | ||||
| 		 * hash identities which has not been determined as yet. | ||||
| 		 */ | ||||
| 	case EM2880_BOARD_MSI_DIGIVOX_AD: | ||||
| 		if (!em28xx_hint_board(dev)) | ||||
| 			em28xx_set_model(dev); | ||||
| 		break; | ||||
|  | ||||
| @ -452,6 +452,15 @@ static int dvb_init(struct em28xx *dev) | ||||
| 			goto out_free; | ||||
| 		} | ||||
| 		break; | ||||
| 	case EM2880_BOARD_KWORLD_DVB_310U: | ||||
| 		dvb->frontend = dvb_attach(zl10353_attach, | ||||
| 						&em28xx_zl10353_with_xc3028, | ||||
| 						&dev->i2c_adap); | ||||
| 		if (attach_xc3028(0x61, dev) < 0) { | ||||
| 			result = -EINVAL; | ||||
| 			goto out_free; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" | ||||
| 				" isn't supported yet\n", | ||||
|  | ||||
| @ -459,6 +459,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, | ||||
| 		urb = usb_alloc_urb(npkt, GFP_KERNEL); | ||||
| 		if (!urb) { | ||||
| 			err("usb_alloc_urb failed"); | ||||
| 			destroy_urbs(gspca_dev); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 		urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev, | ||||
| @ -468,8 +469,8 @@ static int create_urbs(struct gspca_dev *gspca_dev, | ||||
| 
 | ||||
| 		if (urb->transfer_buffer == NULL) { | ||||
| 			usb_free_urb(urb); | ||||
| 			destroy_urbs(gspca_dev); | ||||
| 			err("usb_buffer_urb failed"); | ||||
| 			destroy_urbs(gspca_dev); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 		gspca_dev->urb[n] = urb; | ||||
|  | ||||
| @ -1063,6 +1063,7 @@ static __devinitdata struct usb_device_id device_table[] = { | ||||
| 	{USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302}, | ||||
| 	{USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302}, | ||||
| 	{USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302}, | ||||
| 	{USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302}, | ||||
| 	{} | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(usb, device_table); | ||||
|  | ||||
| @ -232,7 +232,7 @@ static struct ctrl sd_ctrls[] = { | ||||
| static struct v4l2_pix_format vga_mode[] = { | ||||
| 	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||||
| 		.bytesperline = 160, | ||||
| 		.sizeimage = 160 * 120 * 5 / 4, | ||||
| 		.sizeimage = 160 * 120, | ||||
| 		.colorspace = V4L2_COLORSPACE_SRGB, | ||||
| 		.priv = 2 | MODE_RAW}, | ||||
| 	{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||||
| @ -264,7 +264,7 @@ static struct v4l2_pix_format sif_mode[] = { | ||||
| 		.priv = 1 | MODE_REDUCED_SIF}, | ||||
| 	{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||||
| 		.bytesperline = 176, | ||||
| 		.sizeimage = 176 * 144 * 5 / 4, | ||||
| 		.sizeimage = 176 * 144, | ||||
| 		.colorspace = V4L2_COLORSPACE_SRGB, | ||||
| 		.priv = 1 | MODE_RAW}, | ||||
| 	{176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||||
|  | ||||
| @ -707,6 +707,7 @@ static void i2c_w8(struct gspca_dev *gspca_dev, | ||||
| 			0x08, 0,		/* value, index */ | ||||
| 			gspca_dev->usb_buf, 8, | ||||
| 			500); | ||||
| 	msleep(2); | ||||
| } | ||||
| 
 | ||||
| /* read 5 bytes in gspca_dev->usb_buf */ | ||||
| @ -976,13 +977,13 @@ static int sd_init(struct gspca_dev *gspca_dev) | ||||
| 	case BRIDGE_SN9C105: | ||||
| 		if (regF1 != 0x11) | ||||
| 			return -ENODEV; | ||||
| 		reg_w(gspca_dev, 0x02, regGpio, 2); | ||||
| 		reg_w(gspca_dev, 0x01, regGpio, 2); | ||||
| 		break; | ||||
| 	case BRIDGE_SN9C120: | ||||
| 		if (regF1 != 0x12) | ||||
| 			return -ENODEV; | ||||
| 		regGpio[1] = 0x70; | ||||
| 		reg_w(gspca_dev, 0x02, regGpio, 2); | ||||
| 		reg_w(gspca_dev, 0x01, regGpio, 2); | ||||
| 		break; | ||||
| 	default: | ||||
| /*	case BRIDGE_SN9C110: */ | ||||
| @ -1183,7 +1184,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | ||||
| 	static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | ||||
| 	static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */ | ||||
| 	static const __u8 CE_ov76xx[] = | ||||
| 			{ 0x32, 0xdd, 0x32, 0xdd };	/* OV7630/48 */ | ||||
| 				{ 0x32, 0xdd, 0x32, 0xdd }; | ||||
| 
 | ||||
| 	sn9c1xx = sn_tb[(int) sd->sensor]; | ||||
| 	configure_gpio(gspca_dev, sn9c1xx); | ||||
| @ -1223,8 +1224,15 @@ static void sd_start(struct gspca_dev *gspca_dev) | ||||
| 	reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); | ||||
| 	for (i = 0; i < 8; i++) | ||||
| 		reg_w(gspca_dev, 0x84, reg84, sizeof reg84); | ||||
| 	switch (sd->sensor) { | ||||
| 	case SENSOR_OV7660: | ||||
| 		reg_w1(gspca_dev, 0x9a, 0x05); | ||||
| 		break; | ||||
| 	default: | ||||
| 		reg_w1(gspca_dev, 0x9a, 0x08); | ||||
| 		reg_w1(gspca_dev, 0x99, 0x59); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||||
| 	if (mode) | ||||
| @ -1275,8 +1283,8 @@ static void sd_start(struct gspca_dev *gspca_dev) | ||||
| /*			reg1 = 0x44; */ | ||||
| /*			reg1 = 0x46;	(done) */ | ||||
| 		} else { | ||||
| 			reg17 = 0x22;	/* 640 MCKSIZE */ | ||||
| 			reg1 = 0x06; | ||||
| 			reg17 = 0xa2;	/* 640 */ | ||||
| 			reg1 = 0x44; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| @ -1285,6 +1293,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | ||||
| 	switch (sd->sensor) { | ||||
| 	case SENSOR_OV7630: | ||||
| 	case SENSOR_OV7648: | ||||
| 	case SENSOR_OV7660: | ||||
| 		reg_w(gspca_dev, 0xce, CE_ov76xx, 4); | ||||
| 		break; | ||||
| 	default: | ||||
|  | ||||
| @ -225,7 +225,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) | ||||
| 	reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01)); | ||||
| 	do { | ||||
| 		reg_r(gspca_dev, 0x8803, 1); | ||||
| 		if (!gspca_dev->usb_buf) | ||||
| 		if (!gspca_dev->usb_buf[0]) | ||||
| 			break; | ||||
| 	} while (--retry); | ||||
| 	if (retry == 0) | ||||
|  | ||||
| @ -6576,8 +6576,8 @@ static int setlightfreq(struct gspca_dev *gspca_dev) | ||||
| 		 cs2102_60HZ, cs2102_60HZScale}, | ||||
| /* SENSOR_CS2102K 1 */ | ||||
| 		{cs2102_NoFliker, cs2102_NoFlikerScale, | ||||
| 		 cs2102_50HZ, cs2102_50HZScale, | ||||
| 		 cs2102_60HZ, cs2102_60HZScale}, | ||||
| 		 NULL, NULL, /* currently disabled */ | ||||
| 		 NULL, NULL}, | ||||
| /* SENSOR_GC0305 2 */ | ||||
| 		{gc0305_NoFliker, gc0305_NoFliker, | ||||
| 		 gc0305_50HZ, gc0305_50HZ, | ||||
|  | ||||
| @ -3591,7 +3591,7 @@ static int | ||||
| ov51x_init_isoc(struct usb_ov511 *ov) | ||||
| { | ||||
| 	struct urb *urb; | ||||
| 	int fx, err, n, size; | ||||
| 	int fx, err, n, i, size; | ||||
| 
 | ||||
| 	PDEBUG(3, "*** Initializing capture ***"); | ||||
| 
 | ||||
| @ -3662,6 +3662,8 @@ ov51x_init_isoc(struct usb_ov511 *ov) | ||||
| 		urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); | ||||
| 		if (!urb) { | ||||
| 			err("init isoc: usb_alloc_urb ret. NULL"); | ||||
| 			for (i = 0; i < n; i++) | ||||
| 				usb_free_urb(ov->sbuf[i].urb); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 		ov->sbuf[n].urb = urb; | ||||
| @ -5651,7 +5653,7 @@ static ssize_t show_exposure(struct device *cd, | ||||
| 	if (!ov->dev) | ||||
| 		return -ENODEV; | ||||
| 	sensor_get_exposure(ov, &exp); | ||||
| 	return sprintf(buf, "%d\n", exp >> 8); | ||||
| 	return sprintf(buf, "%d\n", exp); | ||||
| } | ||||
| static DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); | ||||
| 
 | ||||
|  | ||||
| @ -489,6 +489,8 @@ static const struct pvr2_device_desc pvr2_device_751xx = { | ||||
| struct usb_device_id pvr2_device_table[] = { | ||||
| 	{ USB_DEVICE(0x2040, 0x2900), | ||||
| 	  .driver_info = (kernel_ulong_t)&pvr2_device_29xxx}, | ||||
| 	{ USB_DEVICE(0x2040, 0x2950), /* Logically identical to 2900 */ | ||||
| 	  .driver_info = (kernel_ulong_t)&pvr2_device_29xxx}, | ||||
| 	{ USB_DEVICE(0x2040, 0x2400), | ||||
| 	  .driver_info = (kernel_ulong_t)&pvr2_device_24xxx}, | ||||
| 	{ USB_DEVICE(0x1164, 0x0622), | ||||
|  | ||||
| @ -669,7 +669,7 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | ||||
| 		(unsigned long)vbuf, pos); | ||||
| 	/* tell v4l buffer was filled */ | ||||
| 
 | ||||
| 	buf->vb.field_count++; | ||||
| 	buf->vb.field_count = dev->frame_count[chn] * 2; | ||||
| 	do_gettimeofday(&ts); | ||||
| 	buf->vb.ts = ts; | ||||
| 	buf->vb.state = VIDEOBUF_DONE; | ||||
| @ -1268,6 +1268,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | ||||
| 	dev->last_frame[chn] = -1; | ||||
| 	dev->bad_payload[chn] = 0; | ||||
| 	dev->cur_frame[chn] = 0; | ||||
| 	dev->frame_count[chn] = 0; | ||||
| 	for (j = 0; j < SYS_FRAMES; j++) { | ||||
| 		dev->buffer[chn].frame[j].ulState = 0; | ||||
| 		dev->buffer[chn].frame[j].cur_size = 0; | ||||
|  | ||||
| @ -592,7 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | ||||
| 	if (ctrl == NULL) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	data = kmalloc(8, GFP_KERNEL); | ||||
| 	data = kmalloc(ctrl->info->size, GFP_KERNEL); | ||||
| 	if (data == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
|  | ||||
| @ -911,7 +911,6 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam) | ||||
| 
 | ||||
| 	for (i = 0; i < W9968CF_URBS; i++) { | ||||
| 		urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL); | ||||
| 		cam->urb[i] = urb; | ||||
| 		if (!urb) { | ||||
| 			for (j = 0; j < i; j++) | ||||
| 				usb_free_urb(cam->urb[j]); | ||||
| @ -919,6 +918,7 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam) | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 
 | ||||
| 		cam->urb[i] = urb; | ||||
| 		urb->dev = udev; | ||||
| 		urb->context = (void*)cam; | ||||
| 		urb->pipe = usb_rcvisocpipe(udev, 1); | ||||
|  | ||||
| @ -274,10 +274,8 @@ static int wm8739_probe(struct i2c_client *client, | ||||
| 			client->addr << 1, client->adapter->name); | ||||
| 
 | ||||
| 	state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL); | ||||
| 	if (state == NULL) { | ||||
| 		kfree(client); | ||||
| 	if (state == NULL) | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	state->vol_l = 0x17; /* 0dB */ | ||||
| 	state->vol_r = 0x17; /* 0dB */ | ||||
| 	state->muted = 0; | ||||
|  | ||||
| @ -988,7 +988,7 @@ zoran_open_init_params (struct zoran *zr) | ||||
| 	zr->v4l_grab_seq = 0; | ||||
| 	zr->v4l_settings.width = 192; | ||||
| 	zr->v4l_settings.height = 144; | ||||
| 	zr->v4l_settings.format = &zoran_formats[4];	/* YUY2 - YUV-4:2:2 packed */ | ||||
| 	zr->v4l_settings.format = &zoran_formats[7];	/* YUY2 - YUV-4:2:2 packed */ | ||||
| 	zr->v4l_settings.bytesperline = | ||||
| 	    zr->v4l_settings.width * | ||||
| 	    ((zr->v4l_settings.format->depth + 7) / 8); | ||||
|  | ||||
| @ -134,7 +134,7 @@ const struct zoran_format zoran_formats[] = { | ||||
| 	}, { | ||||
| 		.name = "16-bit RGB BE", | ||||
| 		ZFMT(-1, | ||||
| 		     V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), | ||||
| 		     V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB), | ||||
| 		.depth = 16, | ||||
| 		.flags = ZORAN_FORMAT_CAPTURE | | ||||
| 			 ZORAN_FORMAT_OVERLAY, | ||||
| @ -2737,7 +2737,8 @@ zoran_do_ioctl (struct inode *inode, | ||||
| 				    fh->v4l_settings.format->fourcc; | ||||
| 				fmt->fmt.pix.colorspace = | ||||
| 				    fh->v4l_settings.format->colorspace; | ||||
| 				fmt->fmt.pix.bytesperline = 0; | ||||
| 				fmt->fmt.pix.bytesperline = | ||||
| 				    fh->v4l_settings.bytesperline; | ||||
| 				if (BUZ_MAX_HEIGHT < | ||||
| 				    (fh->v4l_settings.height * 2)) | ||||
| 					fmt->fmt.pix.field = | ||||
| @ -2833,13 +2834,6 @@ zoran_do_ioctl (struct inode *inode, | ||||
| 				fmt->fmt.pix.pixelformat, | ||||
| 				(char *) &printformat); | ||||
| 
 | ||||
| 			if (fmt->fmt.pix.bytesperline > 0) { | ||||
| 				dprintk(5, | ||||
| 					KERN_ERR "%s: bpl not supported\n", | ||||
| 					ZR_DEVNAME(zr)); | ||||
| 				return -EINVAL; | ||||
| 			} | ||||
| 
 | ||||
| 			/* we can be requested to do JPEG/raw playback/capture */ | ||||
| 			if (! | ||||
| 			    (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||||
| @ -2923,6 +2917,7 @@ zoran_do_ioctl (struct inode *inode, | ||||
| 				fh->jpg_buffers.buffer_size = | ||||
| 				    zoran_v4l2_calc_bufsize(&fh-> | ||||
| 							    jpg_settings); | ||||
| 				fmt->fmt.pix.bytesperline = 0; | ||||
| 				fmt->fmt.pix.sizeimage = | ||||
| 				    fh->jpg_buffers.buffer_size; | ||||
| 
 | ||||
| @ -2979,6 +2974,8 @@ zoran_do_ioctl (struct inode *inode, | ||||
| 
 | ||||
| 				/* tell the user the
 | ||||
| 				 * results/missing stuff */ | ||||
| 				fmt->fmt.pix.bytesperline = | ||||
| 					fh->v4l_settings.bytesperline; | ||||
| 				fmt->fmt.pix.sizeimage = | ||||
| 					fh->v4l_settings.height * | ||||
| 					fh->v4l_settings.bytesperline; | ||||
|  | ||||
| @ -21,7 +21,7 @@ config MFD_SM501 | ||||
| 
 | ||||
| config MFD_SM501_GPIO | ||||
| 	bool "Export GPIO via GPIO layer" | ||||
| 	depends on MFD_SM501 && HAVE_GPIO_LIB | ||||
| 	depends on MFD_SM501 && GPIOLIB | ||||
| 	 ---help--- | ||||
| 	 This option uses the gpio library layer to export the 64 GPIO | ||||
| 	 lines on the SM501. The platform data is used to supply the | ||||
| @ -29,7 +29,7 @@ config MFD_SM501_GPIO | ||||
| 
 | ||||
| config MFD_ASIC3 | ||||
| 	bool "Support for Compaq ASIC3" | ||||
| 	depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM | ||||
| 	depends on GENERIC_HARDIRQS && GPIOLIB && ARM | ||||
| 	 ---help--- | ||||
| 	  This driver supports the ASIC3 multifunction chip found on many | ||||
| 	  PDAs (mainly iPAQ and HTC based ones) | ||||
|  | ||||
| @ -312,7 +312,6 @@ static int __init asic3_irq_probe(struct platform_device *pdev) | ||||
| 	struct asic3 *asic = platform_get_drvdata(pdev); | ||||
| 	unsigned long clksel = 0; | ||||
| 	unsigned int irq, irq_base; | ||||
| 	int map_size; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = platform_get_irq(pdev, 0); | ||||
| @ -534,6 +533,7 @@ static int __init asic3_probe(struct platform_device *pdev) | ||||
| 	struct asic3 *asic; | ||||
| 	struct resource *mem; | ||||
| 	unsigned long clksel; | ||||
| 	int map_size; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	asic = kzalloc(sizeof(struct asic3), GFP_KERNEL); | ||||
|  | ||||
| @ -426,8 +426,6 @@ static u32 atmci_submit_data(struct mmc_host *mmc, struct mmc_data *data) | ||||
| 	host->sg = NULL; | ||||
| 	host->data = data; | ||||
| 
 | ||||
| 	mci_writel(host, BLKR, MCI_BCNT(data->blocks) | ||||
| 			| MCI_BLKLEN(data->blksz)); | ||||
| 	dev_vdbg(&mmc->class_dev, "BLKR=0x%08x\n", | ||||
| 			MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); | ||||
| 
 | ||||
| @ -483,6 +481,10 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||||
| 		if (data->blocks > 1 && data->blksz & 3) | ||||
| 			goto fail; | ||||
| 		atmci_set_timeout(host, data); | ||||
| 
 | ||||
| 		/* Must set block count/size before sending command */ | ||||
| 		mci_writel(host, BLKR, MCI_BCNT(data->blocks) | ||||
| 				| MCI_BLKLEN(data->blksz)); | ||||
| 	} | ||||
| 
 | ||||
| 	iflags = MCI_CMDRDY; | ||||
|  | ||||
| @ -257,7 +257,6 @@ struct e1000_adapter { | ||||
| 	struct net_device *netdev; | ||||
| 	struct pci_dev *pdev; | ||||
| 	struct net_device_stats net_stats; | ||||
| 	spinlock_t stats_lock;      /* prevent concurrent stats updates */ | ||||
| 
 | ||||
| 	/* structs defined in e1000_hw.h */ | ||||
| 	struct e1000_hw hw; | ||||
| @ -284,6 +283,8 @@ struct e1000_adapter { | ||||
| 	unsigned long led_status; | ||||
| 
 | ||||
| 	unsigned int flags; | ||||
| 	struct work_struct downshift_task; | ||||
| 	struct work_struct update_phy_task; | ||||
| }; | ||||
| 
 | ||||
| struct e1000_info { | ||||
| @ -305,6 +306,7 @@ struct e1000_info { | ||||
| #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5) | ||||
| #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6) | ||||
| #define FLAG_HAS_JUMBO_FRAMES             (1 << 7) | ||||
| #define FLAG_READ_ONLY_NVM                (1 << 8) | ||||
| #define FLAG_IS_ICH                       (1 << 9) | ||||
| #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11) | ||||
| #define FLAG_IS_QUAD_PORT_A               (1 << 12) | ||||
| @ -385,6 +387,7 @@ extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw); | ||||
| extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw); | ||||
| extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state); | ||||
| 
 | ||||
| extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw); | ||||
| extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, | ||||
| 						 bool state); | ||||
| extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); | ||||
|  | ||||
| @ -432,6 +432,10 @@ static void e1000_get_regs(struct net_device *netdev, | ||||
| 	regs_buff[11] = er32(TIDV); | ||||
| 
 | ||||
| 	regs_buff[12] = adapter->hw.phy.type;  /* PHY type (IGP=1, M88=0) */ | ||||
| 
 | ||||
| 	/* ethtool doesn't use anything past this point, so all this
 | ||||
| 	 * code is likely legacy junk for apps that may or may not | ||||
| 	 * exist */ | ||||
| 	if (hw->phy.type == e1000_phy_m88) { | ||||
| 		e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); | ||||
| 		regs_buff[13] = (u32)phy_data; /* cable length */ | ||||
| @ -447,7 +451,7 @@ static void e1000_get_regs(struct net_device *netdev, | ||||
| 		regs_buff[22] = adapter->phy_stats.receive_errors; | ||||
| 		regs_buff[23] = regs_buff[13]; /* mdix mode */ | ||||
| 	} | ||||
| 	regs_buff[21] = adapter->phy_stats.idle_errors;  /* phy idle errors */ | ||||
| 	regs_buff[21] = 0; /* was idle_errors */ | ||||
| 	e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); | ||||
| 	regs_buff[24] = (u32)phy_data;  /* phy local receiver status */ | ||||
| 	regs_buff[25] = regs_buff[24];  /* phy remote receiver status */ | ||||
| @ -529,6 +533,9 @@ static int e1000_set_eeprom(struct net_device *netdev, | ||||
| 	if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) | ||||
| 		return -EFAULT; | ||||
| 
 | ||||
| 	if (adapter->flags & FLAG_READ_ONLY_NVM) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	max_len = hw->nvm.word_size * 2; | ||||
| 
 | ||||
| 	first_word = eeprom->offset >> 1; | ||||
|  | ||||
| @ -58,6 +58,7 @@ | ||||
| #define ICH_FLASH_HSFCTL		0x0006 | ||||
| #define ICH_FLASH_FADDR			0x0008 | ||||
| #define ICH_FLASH_FDATA0		0x0010 | ||||
| #define ICH_FLASH_PR0			0x0074 | ||||
| 
 | ||||
| #define ICH_FLASH_READ_COMMAND_TIMEOUT	500 | ||||
| #define ICH_FLASH_WRITE_COMMAND_TIMEOUT	500 | ||||
| @ -150,6 +151,19 @@ union ich8_hws_flash_regacc { | ||||
| 	u16 regval; | ||||
| }; | ||||
| 
 | ||||
| /* ICH Flash Protected Region */ | ||||
| union ich8_flash_protected_range { | ||||
| 	struct ich8_pr { | ||||
| 		u32 base:13;     /* 0:12 Protected Range Base */ | ||||
| 		u32 reserved1:2; /* 13:14 Reserved */ | ||||
| 		u32 rpe:1;       /* 15 Read Protection Enable */ | ||||
| 		u32 limit:13;    /* 16:28 Protected Range Limit */ | ||||
| 		u32 reserved2:2; /* 29:30 Reserved */ | ||||
| 		u32 wpe:1;       /* 31 Write Protection Enable */ | ||||
| 	} range; | ||||
| 	u32 regval; | ||||
| }; | ||||
| 
 | ||||
| static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); | ||||
| static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); | ||||
| static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); | ||||
| @ -366,6 +380,9 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static DEFINE_MUTEX(nvm_mutex); | ||||
| static pid_t nvm_owner = -1; | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_acquire_swflag_ich8lan - Acquire software control flag | ||||
|  *  @hw: pointer to the HW structure | ||||
| @ -379,6 +396,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | ||||
| 	u32 extcnf_ctrl; | ||||
| 	u32 timeout = PHY_CFG_TIMEOUT; | ||||
| 
 | ||||
| 	might_sleep(); | ||||
| 
 | ||||
| 	if (!mutex_trylock(&nvm_mutex)) { | ||||
| 		WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n", | ||||
| 		     nvm_owner); | ||||
| 		mutex_lock(&nvm_mutex); | ||||
| 	} | ||||
| 	nvm_owner = current->pid; | ||||
| 
 | ||||
| 	while (timeout) { | ||||
| 		extcnf_ctrl = er32(EXTCNF_CTRL); | ||||
| 		extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; | ||||
| @ -393,6 +419,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | ||||
| 
 | ||||
| 	if (!timeout) { | ||||
| 		hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); | ||||
| 		nvm_owner = -1; | ||||
| 		mutex_unlock(&nvm_mutex); | ||||
| 		return -E1000_ERR_CONFIG; | ||||
| 	} | ||||
| 
 | ||||
| @ -414,6 +442,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) | ||||
| 	extcnf_ctrl = er32(EXTCNF_CTRL); | ||||
| 	extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; | ||||
| 	ew32(EXTCNF_CTRL, extcnf_ctrl); | ||||
| 
 | ||||
| 	nvm_owner = -1; | ||||
| 	mutex_unlock(&nvm_mutex); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -1284,6 +1315,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | ||||
| 	 * programming failed. | ||||
| 	 */ | ||||
| 	if (ret_val) { | ||||
| 		/* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ | ||||
| 		hw_dbg(hw, "Flash commit failed.\n"); | ||||
| 		e1000_release_swflag_ich8lan(hw); | ||||
| 		return ret_val; | ||||
| @ -1373,6 +1405,49 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) | ||||
| 	return e1000e_validate_nvm_checksum_generic(hw); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000e_write_protect_nvm_ich8lan - Make the NVM read-only | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  To prevent malicious write/erase of the NVM, set it to be read-only | ||||
|  *  so that the hardware ignores all write/erase cycles of the NVM via | ||||
|  *  the flash control registers.  The shadow-ram copy of the NVM will | ||||
|  *  still be updated, however any updates to this copy will not stick | ||||
|  *  across driver reloads. | ||||
|  **/ | ||||
| void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) | ||||
| { | ||||
| 	union ich8_flash_protected_range pr0; | ||||
| 	union ich8_hws_flash_status hsfsts; | ||||
| 	u32 gfpreg; | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	ret_val = e1000_acquire_swflag_ich8lan(hw); | ||||
| 	if (ret_val) | ||||
| 		return; | ||||
| 
 | ||||
| 	gfpreg = er32flash(ICH_FLASH_GFPREG); | ||||
| 
 | ||||
| 	/* Write-protect GbE Sector of NVM */ | ||||
| 	pr0.regval = er32flash(ICH_FLASH_PR0); | ||||
| 	pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK; | ||||
| 	pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK); | ||||
| 	pr0.range.wpe = true; | ||||
| 	ew32flash(ICH_FLASH_PR0, pr0.regval); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Lock down a subset of GbE Flash Control Registers, e.g. | ||||
| 	 * PR0 to prevent the write-protection from being lifted. | ||||
| 	 * Once FLOCKDN is set, the registers protected by it cannot | ||||
| 	 * be written until FLOCKDN is cleared by a hardware reset. | ||||
| 	 */ | ||||
| 	hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); | ||||
| 	hsfsts.hsf_status.flockdn = true; | ||||
| 	ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); | ||||
| 
 | ||||
| 	e1000_release_swflag_ich8lan(hw); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_write_flash_data_ich8lan - Writes bytes to the NVM | ||||
|  *  @hw: pointer to the HW structure | ||||
| @ -1720,6 +1795,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | ||||
| 	ew32(CTRL, (ctrl | E1000_CTRL_RST)); | ||||
| 	msleep(20); | ||||
| 
 | ||||
| 	/* release the swflag because it is not reset by hardware reset */ | ||||
| 	e1000_release_swflag_ich8lan(hw); | ||||
| 
 | ||||
| 	ret_val = e1000e_get_auto_rd_done(hw); | ||||
| 	if (ret_val) { | ||||
| 		/*
 | ||||
|  | ||||
| @ -47,7 +47,7 @@ | ||||
| 
 | ||||
| #include "e1000.h" | ||||
| 
 | ||||
| #define DRV_VERSION "0.3.3.3-k2" | ||||
| #define DRV_VERSION "0.3.3.3-k6" | ||||
| char e1000e_driver_name[] = "e1000e"; | ||||
| const char e1000e_driver_version[] = DRV_VERSION; | ||||
| 
 | ||||
| @ -1115,6 +1115,14 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) | ||||
| 	writel(0, adapter->hw.hw_addr + rx_ring->tail); | ||||
| } | ||||
| 
 | ||||
| static void e1000e_downshift_workaround(struct work_struct *work) | ||||
| { | ||||
| 	struct e1000_adapter *adapter = container_of(work, | ||||
| 					struct e1000_adapter, downshift_task); | ||||
| 
 | ||||
| 	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * e1000_intr_msi - Interrupt Handler | ||||
|  * @irq: interrupt number | ||||
| @ -1139,7 +1147,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) | ||||
| 		 */ | ||||
| 		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && | ||||
| 		    (!(er32(STATUS) & E1000_STATUS_LU))) | ||||
| 			e1000e_gig_downshift_workaround_ich8lan(hw); | ||||
| 			schedule_work(&adapter->downshift_task); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * 80003ES2LAN workaround-- For packet buffer work-around on | ||||
| @ -1205,7 +1213,7 @@ static irqreturn_t e1000_intr(int irq, void *data) | ||||
| 		 */ | ||||
| 		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && | ||||
| 		    (!(er32(STATUS) & E1000_STATUS_LU))) | ||||
| 			e1000e_gig_downshift_workaround_ich8lan(hw); | ||||
| 			schedule_work(&adapter->downshift_task); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * 80003ES2LAN workaround-- | ||||
| @ -2592,8 +2600,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) | ||||
| 	/* Explicitly disable IRQ since the NIC can be in any state. */ | ||||
| 	e1000_irq_disable(adapter); | ||||
| 
 | ||||
| 	spin_lock_init(&adapter->stats_lock); | ||||
| 
 | ||||
| 	set_bit(__E1000_DOWN, &adapter->state); | ||||
| 	return 0; | ||||
| 
 | ||||
| @ -2912,6 +2918,21 @@ static int e1000_set_mac(struct net_device *netdev, void *p) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * e1000e_update_phy_task - work thread to update phy | ||||
|  * @work: pointer to our work struct | ||||
|  * | ||||
|  * this worker thread exists because we must acquire a | ||||
|  * semaphore to read the phy, which we could msleep while | ||||
|  * waiting for it, and we can't msleep in a timer. | ||||
|  **/ | ||||
| static void e1000e_update_phy_task(struct work_struct *work) | ||||
| { | ||||
| 	struct e1000_adapter *adapter = container_of(work, | ||||
| 					struct e1000_adapter, update_phy_task); | ||||
| 	e1000_get_phy_info(&adapter->hw); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Need to wait a few seconds after link up to get diagnostic information from | ||||
|  * the phy | ||||
| @ -2919,7 +2940,7 @@ static int e1000_set_mac(struct net_device *netdev, void *p) | ||||
| static void e1000_update_phy_info(unsigned long data) | ||||
| { | ||||
| 	struct e1000_adapter *adapter = (struct e1000_adapter *) data; | ||||
| 	e1000_get_phy_info(&adapter->hw); | ||||
| 	schedule_work(&adapter->update_phy_task); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -2930,10 +2951,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | ||||
| { | ||||
| 	struct e1000_hw *hw = &adapter->hw; | ||||
| 	struct pci_dev *pdev = adapter->pdev; | ||||
| 	unsigned long irq_flags; | ||||
| 	u16 phy_tmp; | ||||
| 
 | ||||
| #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Prevent stats update while adapter is being reset, or if the pci | ||||
| @ -2944,14 +2961,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | ||||
| 	if (pci_channel_offline(pdev)) | ||||
| 		return; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&adapter->stats_lock, irq_flags); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * these counters are modified from e1000_adjust_tbi_stats, | ||||
| 	 * called from the interrupt context, so they must only | ||||
| 	 * be written while holding adapter->stats_lock | ||||
| 	 */ | ||||
| 
 | ||||
| 	adapter->stats.crcerrs += er32(CRCERRS); | ||||
| 	adapter->stats.gprc += er32(GPRC); | ||||
| 	adapter->stats.gorc += er32(GORCL); | ||||
| @ -3022,21 +3031,10 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | ||||
| 
 | ||||
| 	/* Tx Dropped needs to be maintained elsewhere */ | ||||
| 
 | ||||
| 	/* Phy Stats */ | ||||
| 	if (hw->phy.media_type == e1000_media_type_copper) { | ||||
| 		if ((adapter->link_speed == SPEED_1000) && | ||||
| 		   (!e1e_rphy(hw, PHY_1000T_STATUS, &phy_tmp))) { | ||||
| 			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; | ||||
| 			adapter->phy_stats.idle_errors += phy_tmp; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Management Stats */ | ||||
| 	adapter->stats.mgptc += er32(MGTPTC); | ||||
| 	adapter->stats.mgprc += er32(MGTPRC); | ||||
| 	adapter->stats.mgpdc += er32(MGTPDC); | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -3048,10 +3046,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) | ||||
| 	struct e1000_hw *hw = &adapter->hw; | ||||
| 	struct e1000_phy_regs *phy = &adapter->phy_regs; | ||||
| 	int ret_val; | ||||
| 	unsigned long irq_flags; | ||||
| 
 | ||||
| 
 | ||||
| 	spin_lock_irqsave(&adapter->stats_lock, irq_flags); | ||||
| 
 | ||||
| 	if ((er32(STATUS) & E1000_STATUS_LU) && | ||||
| 	    (adapter->hw.phy.media_type == e1000_media_type_copper)) { | ||||
| @ -3082,8 +3076,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) | ||||
| 		phy->stat1000 = 0; | ||||
| 		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF); | ||||
| 	} | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); | ||||
| } | ||||
| 
 | ||||
| static void e1000_print_link_info(struct e1000_adapter *adapter) | ||||
| @ -4467,6 +4459,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | ||||
| 
 | ||||
| 	adapter->bd_number = cards_found++; | ||||
| 
 | ||||
| 	e1000e_check_options(adapter); | ||||
| 
 | ||||
| 	/* setup adapter struct */ | ||||
| 	err = e1000_sw_init(adapter); | ||||
| 	if (err) | ||||
| @ -4482,6 +4476,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | ||||
| 	if (err) | ||||
| 		goto err_hw_init; | ||||
| 
 | ||||
| 	if ((adapter->flags & FLAG_IS_ICH) && | ||||
| 	    (adapter->flags & FLAG_READ_ONLY_NVM)) | ||||
| 		e1000e_write_protect_nvm_ich8lan(&adapter->hw); | ||||
| 
 | ||||
| 	hw->mac.ops.get_bus_info(&adapter->hw); | ||||
| 
 | ||||
| 	adapter->hw.phy.autoneg_wait_to_complete = 0; | ||||
| @ -4572,8 +4570,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | ||||
| 
 | ||||
| 	INIT_WORK(&adapter->reset_task, e1000_reset_task); | ||||
| 	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); | ||||
| 
 | ||||
| 	e1000e_check_options(adapter); | ||||
| 	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); | ||||
| 	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); | ||||
| 
 | ||||
| 	/* Initialize link parameters. User can change them with ethtool */ | ||||
| 	adapter->hw.mac.autoneg = 1; | ||||
|  | ||||
| @ -133,6 +133,15 @@ E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); | ||||
|  */ | ||||
| E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); | ||||
| 
 | ||||
| /*
 | ||||
|  * Write Protect NVM | ||||
|  * | ||||
|  * Valid Range: 0, 1 | ||||
|  * | ||||
|  * Default Value: 1 (enabled) | ||||
|  */ | ||||
| E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); | ||||
| 
 | ||||
| struct e1000_option { | ||||
| 	enum { enable_option, range_option, list_option } type; | ||||
| 	const char *name; | ||||
| @ -388,4 +397,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) | ||||
| 								       opt.def); | ||||
| 		} | ||||
| 	} | ||||
| 	{ /* Write-protect NVM */ | ||||
| 		const struct e1000_option opt = { | ||||
| 			.type = enable_option, | ||||
| 			.name = "Write-protect NVM", | ||||
| 			.err  = "defaulting to Enabled", | ||||
| 			.def  = OPTION_ENABLED | ||||
| 		}; | ||||
| 
 | ||||
| 		if (adapter->flags & FLAG_IS_ICH) { | ||||
| 			if (num_WriteProtectNVM > bd) { | ||||
| 				unsigned int write_protect_nvm = WriteProtectNVM[bd]; | ||||
| 				e1000_validate_option(&write_protect_nvm, &opt, | ||||
| 						      adapter); | ||||
| 				if (write_protect_nvm) | ||||
| 					adapter->flags |= FLAG_READ_ONLY_NVM; | ||||
| 			} else { | ||||
| 				if (opt.def) | ||||
| 					adapter->flags |= FLAG_READ_ONLY_NVM; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -16,6 +16,7 @@ | ||||
| 
 | ||||
| 
 | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/sched.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/stat.h> | ||||
| #include <linux/topology.h> | ||||
| @ -484,6 +485,21 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, | ||||
| #endif /* HAVE_PCI_LEGACY */ | ||||
| 
 | ||||
| #ifdef HAVE_PCI_MMAP | ||||
| 
 | ||||
| static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) | ||||
| { | ||||
| 	unsigned long nr, start, size; | ||||
| 
 | ||||
| 	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | ||||
| 	start = vma->vm_pgoff; | ||||
| 	size = pci_resource_len(pdev, resno) >> PAGE_SHIFT; | ||||
| 	if (start < size && size - start >= nr) | ||||
| 		return 1; | ||||
| 	WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", | ||||
| 		current->comm, start, start+nr, pci_name(pdev), resno, size); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * pci_mmap_resource - map a PCI resource into user memory space | ||||
|  * @kobj: kobject for mapping | ||||
| @ -510,6 +526,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | ||||
| 	if (i >= PCI_ROM_RESOURCE) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	if (!pci_mmap_fits(pdev, i, vma)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	/* pci_mmap_page_range() expects the same kind of entry as coming
 | ||||
| 	 * from /proc/bus/pci/ which is a "user visible" value. If this is | ||||
| 	 * different from the resource itself, arch will do necessary fixup. | ||||
|  | ||||
| @ -422,6 +422,12 @@ done: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int rtc_dev_fasync(int fd, struct file *file, int on) | ||||
| { | ||||
| 	struct rtc_device *rtc = file->private_data; | ||||
| 	return fasync_helper(fd, file, on, &rtc->async_queue); | ||||
| } | ||||
| 
 | ||||
| static int rtc_dev_release(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct rtc_device *rtc = file->private_data; | ||||
| @ -434,16 +440,13 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | ||||
| 	if (rtc->ops->release) | ||||
| 		rtc->ops->release(rtc->dev.parent); | ||||
| 
 | ||||
| 	if (file->f_flags & FASYNC) | ||||
| 		rtc_dev_fasync(-1, file, 0); | ||||
| 
 | ||||
| 	clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int rtc_dev_fasync(int fd, struct file *file, int on) | ||||
| { | ||||
| 	struct rtc_device *rtc = file->private_data; | ||||
| 	return fasync_helper(fd, file, on, &rtc->async_queue); | ||||
| } | ||||
| 
 | ||||
| static const struct file_operations rtc_dev_fops = { | ||||
| 	.owner		= THIS_MODULE, | ||||
| 	.llseek		= no_llseek, | ||||
|  | ||||
| @ -447,51 +447,36 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, | ||||
| { | ||||
| 	char s[80]; | ||||
| 
 | ||||
| 	sprintf(s, "%s sc:%x ", cdev->dev.bus_id, irq_ptr->schid.sch_no); | ||||
| 
 | ||||
| 	sprintf(s, "qdio: %s ", dev_name(&cdev->dev)); | ||||
| 	switch (irq_ptr->qib.qfmt) { | ||||
| 	case QDIO_QETH_QFMT: | ||||
| 		sprintf(s + strlen(s), "OSADE "); | ||||
| 		sprintf(s + strlen(s), "OSA "); | ||||
| 		break; | ||||
| 	case QDIO_ZFCP_QFMT: | ||||
| 		sprintf(s + strlen(s), "ZFCP "); | ||||
| 		break; | ||||
| 	case QDIO_IQDIO_QFMT: | ||||
| 		sprintf(s + strlen(s), "HiperSockets "); | ||||
| 		sprintf(s + strlen(s), "HS "); | ||||
| 		break; | ||||
| 	} | ||||
| 	sprintf(s + strlen(s), "using: "); | ||||
| 
 | ||||
| 	if (!is_thinint_irq(irq_ptr)) | ||||
| 		sprintf(s + strlen(s), "no"); | ||||
| 	sprintf(s + strlen(s), "AdapterInterrupts "); | ||||
| 	if (!(irq_ptr->sch_token != 0)) | ||||
| 		sprintf(s + strlen(s), "no"); | ||||
| 	sprintf(s + strlen(s), "QEBSM "); | ||||
| 	if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) | ||||
| 		sprintf(s + strlen(s), "no"); | ||||
| 	sprintf(s + strlen(s), "OutboundPCI "); | ||||
| 	if (!css_general_characteristics.aif_tdd) | ||||
| 		sprintf(s + strlen(s), "no"); | ||||
| 	sprintf(s + strlen(s), "TDD\n"); | ||||
| 	printk(KERN_INFO "qdio: %s", s); | ||||
| 
 | ||||
| 	memset(s, 0, sizeof(s)); | ||||
| 	sprintf(s, "%s SIGA required: ", cdev->dev.bus_id); | ||||
| 	if (irq_ptr->siga_flag.input) | ||||
| 		sprintf(s + strlen(s), "Read "); | ||||
| 	if (irq_ptr->siga_flag.output) | ||||
| 		sprintf(s + strlen(s), "Write "); | ||||
| 	if (irq_ptr->siga_flag.sync) | ||||
| 		sprintf(s + strlen(s), "Sync "); | ||||
| 	if (!irq_ptr->siga_flag.no_sync_ti) | ||||
| 		sprintf(s + strlen(s), "SyncAI "); | ||||
| 	if (!irq_ptr->siga_flag.no_sync_out_ti) | ||||
| 		sprintf(s + strlen(s), "SyncOutAI "); | ||||
| 	if (!irq_ptr->siga_flag.no_sync_out_pci) | ||||
| 		sprintf(s + strlen(s), "SyncOutPCI"); | ||||
| 	sprintf(s + strlen(s), "on SC %x using ", irq_ptr->schid.sch_no); | ||||
| 	sprintf(s + strlen(s), "AI:%d ", is_thinint_irq(irq_ptr)); | ||||
| 	sprintf(s + strlen(s), "QEBSM:%d ", (irq_ptr->sch_token) ? 1 : 0); | ||||
| 	sprintf(s + strlen(s), "PCI:%d ", | ||||
| 		(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) ? 1 : 0); | ||||
| 	sprintf(s + strlen(s), "TDD:%d ", css_general_characteristics.aif_tdd); | ||||
| 	sprintf(s + strlen(s), "SIGA:"); | ||||
| 	sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.input) ? "R" : " "); | ||||
| 	sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.output) ? "W" : " "); | ||||
| 	sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.sync) ? "S" : " "); | ||||
| 	sprintf(s + strlen(s), "%s", | ||||
| 		(!irq_ptr->siga_flag.no_sync_ti) ? "A" : " "); | ||||
| 	sprintf(s + strlen(s), "%s", | ||||
| 		(!irq_ptr->siga_flag.no_sync_out_ti) ? "O" : " "); | ||||
| 	sprintf(s + strlen(s), "%s", | ||||
| 		(!irq_ptr->siga_flag.no_sync_out_pci) ? "P" : " "); | ||||
| 	sprintf(s + strlen(s), "\n"); | ||||
| 	printk(KERN_INFO "qdio: %s", s); | ||||
| 	printk(KERN_INFO "%s", s); | ||||
| } | ||||
| 
 | ||||
| int __init qdio_setup_init(void) | ||||
|  | ||||
| @ -427,7 +427,7 @@ static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m) | ||||
| 			goto msg_rejected; | ||||
| 		} | ||||
| 
 | ||||
| 		if (t->speed_hz < orion_spi->min_speed) { | ||||
| 		if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { | ||||
| 			dev_err(&spi->dev, | ||||
| 				"message rejected : " | ||||
| 				"device min speed (%d Hz) exceeds " | ||||
|  | ||||
| @ -49,7 +49,7 @@ MODULE_ALIAS("platform:pxa2xx-spi"); | ||||
| 
 | ||||
| #define DMA_INT_MASK		(DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) | ||||
| #define RESET_DMA_CHANNEL	(DCSR_NODESC | DMA_INT_MASK) | ||||
| #define IS_DMA_ALIGNED(x)	(((x) & 0x07) == 0) | ||||
| #define IS_DMA_ALIGNED(x)	((((u32)(x)) & 0x07) == 0) | ||||
| #define MAX_DMA_LEN		8191 | ||||
| 
 | ||||
| /*
 | ||||
| @ -896,7 +896,7 @@ static void pump_transfers(unsigned long data) | ||||
| 				|| transfer->rx_dma || transfer->tx_dma) { | ||||
| 			dev_err(&drv_data->pdev->dev, | ||||
| 				"pump_transfers: mapped transfer length " | ||||
| 				"of %lu is greater than %d\n", | ||||
| 				"of %u is greater than %d\n", | ||||
| 				transfer->len, MAX_DMA_LEN); | ||||
| 			message->status = -EINVAL; | ||||
| 			giveback(drv_data); | ||||
|  | ||||
| @ -2400,11 +2400,15 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | ||||
| 
 | ||||
|  	if (!fbcon_is_inactive(vc, info)) { | ||||
| 		if (ops->blank_state != blank) { | ||||
| 			int ret = 1; | ||||
| 
 | ||||
| 			ops->blank_state = blank; | ||||
| 			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); | ||||
| 			ops->cursor_flash = (!blank); | ||||
| 
 | ||||
| 			if (fb_blank(info, blank)) | ||||
| 			if (info->fbops->fb_blank) | ||||
| 				ret = info->fbops->fb_blank(blank, info); | ||||
| 			if (ret) | ||||
| 				fbcon_generic_blank(vc, info, blank); | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user